diff options
author | Jon Skeet <skeet@pobox.com> | 2008-10-22 13:18:49 +0100 |
---|---|---|
committer | Jon Skeet <skeet@pobox.com> | 2008-10-22 13:18:49 +0100 |
commit | f0589506c96600dcd01319b9d1929d87505f3daa (patch) | |
tree | 945bc56e2e2da748271acc8e80deb7ca22aaaf54 /src | |
parent | e60ce8bfafca616ed4fd430ae4f82360de165e80 (diff) | |
download | protobuf-f0589506c96600dcd01319b9d1929d87505f3daa.tar.gz protobuf-f0589506c96600dcd01319b9d1929d87505f3daa.tar.bz2 protobuf-f0589506c96600dcd01319b9d1929d87505f3daa.zip |
Wiping slate clean to start again with new layout.
Diffstat (limited to 'src')
192 files changed, 0 insertions, 73972 deletions
diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 3f7640af..00000000 --- a/src/Makefile.am +++ /dev/null @@ -1,277 +0,0 @@ -## Process this file with automake to produce Makefile.in - -if GCC -# These are good warnings to turn on by default -AM_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -else -AM_CXXFLAGS = $(PTHREAD_CFLAGS) -endif - -AM_LDFLAGS = $(PTHREAD_CFLAGS) - -# If I say "dist_include_DATA", automake complains that $(includedir) is not -# a "legitimate" directory for DATA. Screw you, automake. -protodir = $(includedir) -nobase_dist_proto_DATA = google/protobuf/descriptor.proto - -# Not sure why these don't get cleaned automatically. -clean-local: - rm -f *.loT - -CLEANFILES = $(protoc_outputs) unittest_proto_middleman - -MAINTAINERCLEANFILES = \ - Makefile.in - -nobase_include_HEADERS = \ - google/protobuf/stubs/common.h \ - google/protobuf/descriptor.h \ - google/protobuf/descriptor.pb.h \ - google/protobuf/descriptor_database.h \ - google/protobuf/dynamic_message.h \ - google/protobuf/extension_set.h \ - google/protobuf/generated_message_reflection.h \ - google/protobuf/message.h \ - google/protobuf/reflection_ops.h \ - google/protobuf/repeated_field.h \ - google/protobuf/service.h \ - google/protobuf/text_format.h \ - google/protobuf/unknown_field_set.h \ - google/protobuf/wire_format.h \ - google/protobuf/wire_format_inl.h \ - google/protobuf/io/coded_stream.h \ - google/protobuf/io/printer.h \ - google/protobuf/io/tokenizer.h \ - google/protobuf/io/zero_copy_stream.h \ - google/protobuf/io/zero_copy_stream_impl.h \ - google/protobuf/compiler/code_generator.h \ - google/protobuf/compiler/command_line_interface.h \ - google/protobuf/compiler/importer.h \ - google/protobuf/compiler/parser.h \ - google/protobuf/compiler/cpp/cpp_generator.h \ - google/protobuf/compiler/java/java_generator.h \ - google/protobuf/compiler/csharp/csharp_generator.h \ - google/protobuf/compiler/python/python_generator.h - -lib_LTLIBRARIES = libprotobuf.la libprotoc.la - -libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 0:0:0 -libprotobuf_la_SOURCES = \ - google/protobuf/stubs/common.cc \ - google/protobuf/stubs/hash.cc \ - google/protobuf/stubs/hash.h \ - google/protobuf/stubs/map-util.cc \ - google/protobuf/stubs/map-util.h \ - google/protobuf/stubs/stl_util-inl.cc \ - google/protobuf/stubs/stl_util-inl.h \ - google/protobuf/stubs/substitute.cc \ - google/protobuf/stubs/substitute.h \ - google/protobuf/stubs/strutil.cc \ - google/protobuf/stubs/strutil.h \ - google/protobuf/descriptor.cc \ - google/protobuf/descriptor.pb.cc \ - google/protobuf/descriptor_database.cc \ - google/protobuf/dynamic_message.cc \ - google/protobuf/extension_set.cc \ - google/protobuf/generated_message_reflection.cc \ - google/protobuf/message.cc \ - google/protobuf/reflection_ops.cc \ - google/protobuf/repeated_field.cc \ - google/protobuf/service.cc \ - google/protobuf/text_format.cc \ - google/protobuf/unknown_field_set.cc \ - google/protobuf/wire_format.cc \ - google/protobuf/io/coded_stream.cc \ - google/protobuf/io/printer.cc \ - google/protobuf/io/tokenizer.cc \ - google/protobuf/io/zero_copy_stream.cc \ - google/protobuf/io/zero_copy_stream_impl.cc \ - google/protobuf/compiler/importer.cc \ - google/protobuf/compiler/parser.cc - -libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 0:0:0 -libprotoc_la_SOURCES = \ - google/protobuf/compiler/code_generator.cc \ - google/protobuf/compiler/command_line_interface.cc \ - google/protobuf/compiler/cpp/cpp_enum.cc \ - google/protobuf/compiler/cpp/cpp_enum.h \ - google/protobuf/compiler/cpp/cpp_enum_field.cc \ - google/protobuf/compiler/cpp/cpp_enum_field.h \ - google/protobuf/compiler/cpp/cpp_extension.cc \ - google/protobuf/compiler/cpp/cpp_extension.h \ - google/protobuf/compiler/cpp/cpp_field.cc \ - google/protobuf/compiler/cpp/cpp_field.h \ - google/protobuf/compiler/cpp/cpp_file.cc \ - google/protobuf/compiler/cpp/cpp_file.h \ - google/protobuf/compiler/cpp/cpp_generator.cc \ - google/protobuf/compiler/cpp/cpp_helpers.cc \ - google/protobuf/compiler/cpp/cpp_helpers.h \ - google/protobuf/compiler/cpp/cpp_message.cc \ - google/protobuf/compiler/cpp/cpp_message.h \ - google/protobuf/compiler/cpp/cpp_message_field.cc \ - google/protobuf/compiler/cpp/cpp_message_field.h \ - google/protobuf/compiler/cpp/cpp_primitive_field.cc \ - google/protobuf/compiler/cpp/cpp_primitive_field.h \ - google/protobuf/compiler/cpp/cpp_service.cc \ - google/protobuf/compiler/cpp/cpp_service.h \ - google/protobuf/compiler/cpp/cpp_string_field.cc \ - google/protobuf/compiler/cpp/cpp_string_field.h \ - google/protobuf/compiler/java/java_enum.cc \ - google/protobuf/compiler/java/java_enum.h \ - google/protobuf/compiler/java/java_enum_field.cc \ - google/protobuf/compiler/java/java_enum_field.h \ - google/protobuf/compiler/java/java_extension.cc \ - google/protobuf/compiler/java/java_extension.h \ - google/protobuf/compiler/java/java_field.cc \ - google/protobuf/compiler/java/java_field.h \ - google/protobuf/compiler/java/java_file.cc \ - google/protobuf/compiler/java/java_file.h \ - google/protobuf/compiler/java/java_generator.cc \ - google/protobuf/compiler/java/java_helpers.cc \ - google/protobuf/compiler/java/java_helpers.h \ - google/protobuf/compiler/java/java_message.cc \ - google/protobuf/compiler/java/java_message.h \ - google/protobuf/compiler/java/java_message_field.cc \ - google/protobuf/compiler/java/java_message_field.h \ - google/protobuf/compiler/java/java_primitive_field.cc \ - google/protobuf/compiler/java/java_primitive_field.h \ - google/protobuf/compiler/java/java_service.cc \ - google/protobuf/compiler/java/java_service.h \ - google/protobuf/compiler/csharp/csharp_enum.cc \ - google/protobuf/compiler/csharp/csharp_enum.h \ - google/protobuf/compiler/csharp/csharp_enum_field.cc \ - google/protobuf/compiler/csharp/csharp_enum_field.h \ - google/protobuf/compiler/csharp/csharp_extension.cc \ - google/protobuf/compiler/csharp/csharp_extension.h \ - google/protobuf/compiler/csharp/csharp_field.cc \ - google/protobuf/compiler/csharp/csharp_field.h \ - google/protobuf/compiler/csharp/csharp_file.cc \ - google/protobuf/compiler/csharp/csharp_file.h \ - google/protobuf/compiler/csharp/csharp_generator.cc \ - google/protobuf/compiler/csharp/csharp_helpers.cc \ - google/protobuf/compiler/csharp/csharp_helpers.h \ - google/protobuf/compiler/csharp/csharp_message.cc \ - google/protobuf/compiler/csharp/csharp_message.h \ - google/protobuf/compiler/csharp/csharp_message_field.cc \ - google/protobuf/compiler/csharp/csharp_message_field.h \ - google/protobuf/compiler/csharp/csharp_primitive_field.cc \ - google/protobuf/compiler/csharp/csharp_primitive_field.h \ - google/protobuf/compiler/csharp/csharp_service.cc \ - google/protobuf/compiler/csharp/csharp_service.h \ - google/protobuf/compiler/python/python_generator.cc - -bin_PROGRAMS = protoc -protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la -protoc_SOURCES = google/protobuf/compiler/main.cc - -# Tests ============================================================== - -protoc_inputs = \ - google/protobuf/unittest.proto \ - google/protobuf/unittest_import.proto \ - google/protobuf/unittest_mset.proto \ - google/protobuf/unittest_optimize_for.proto \ - google/protobuf/unittest_embed_optimize_for.proto \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto - -EXTRA_DIST = \ - $(protoc_inputs) \ - solaris/libstdc++.la \ - google/protobuf/testdata/golden_message \ - google/protobuf/testdata/text_format_unittest_data.txt \ - google/protobuf/testdata/text_format_unittest_extensions_data.txt \ - google/protobuf/package_info.h \ - google/protobuf/io/package_info.h \ - google/protobuf/compiler/package_info.h \ - gtest/CHANGES \ - gtest/CONTRIBUTORS \ - gtest/COPYING \ - gtest/README \ - gtest/gen_gtest_pred_impl.py - -protoc_outputs = \ - google/protobuf/unittest.pb.cc \ - google/protobuf/unittest.pb.h \ - google/protobuf/unittest_import.pb.cc \ - google/protobuf/unittest_import.pb.h \ - google/protobuf/unittest_mset.pb.cc \ - google/protobuf/unittest_mset.pb.h \ - google/protobuf/unittest_optimize_for.pb.cc \ - google/protobuf/unittest_optimize_for.pb.h \ - google/protobuf/unittest_embed_optimize_for.pb.cc \ - google/protobuf/unittest_embed_optimize_for.pb.h \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ - google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h - -BUILT_SOURCES = $(protoc_outputs) - -# This rule is a little weird. The first prereq is the protoc executable -# and the rest are its inputs. Therefore, $^ -- which expands to the -# list of prereqs -- is actually a valid command. We have to place "./" in -# front of it in case protoc is in the current directory. protoc allows -# flags to appear after input file names, so we happily stick the flags on -# the end. -# -# For reference, if we didn't have to worry about VPATH (i.e., building from -# a directory other than the package root), we could have just written this: -# ./protoc$(EXEEXT) -I$(srcdir) --cpp_out=. $(protoc_inputs) -unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) - ./$^ -I$(srcdir) --cpp_out=. - touch unittest_proto_middleman - -$(protoc_outputs): unittest_proto_middleman - -noinst_PROGRAMS = protobuf-test -protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la -protobuf_test_SOURCES = \ - google/protobuf/stubs/common_unittest.cc \ - google/protobuf/stubs/strutil_unittest.cc \ - google/protobuf/descriptor_database_unittest.cc \ - google/protobuf/descriptor_unittest.cc \ - google/protobuf/dynamic_message_unittest.cc \ - google/protobuf/extension_set_unittest.cc \ - google/protobuf/generated_message_reflection_unittest.cc \ - google/protobuf/message_unittest.cc \ - google/protobuf/reflection_ops_unittest.cc \ - google/protobuf/repeated_field_unittest.cc \ - google/protobuf/text_format_unittest.cc \ - google/protobuf/unknown_field_set_unittest.cc \ - google/protobuf/wire_format_unittest.cc \ - google/protobuf/io/coded_stream_unittest.cc \ - google/protobuf/io/printer_unittest.cc \ - google/protobuf/io/tokenizer_unittest.cc \ - google/protobuf/io/zero_copy_stream_unittest.cc \ - google/protobuf/compiler/command_line_interface_unittest.cc \ - google/protobuf/compiler/importer_unittest.cc \ - google/protobuf/compiler/parser_unittest.cc \ - google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \ - google/protobuf/compiler/cpp/cpp_unittest.cc \ - google/protobuf/test_util.cc \ - google/protobuf/test_util.h \ - google/protobuf/testing/googletest.cc \ - google/protobuf/testing/googletest.h \ - google/protobuf/testing/file.cc \ - google/protobuf/testing/file.h \ - gtest/gtest.cc \ - gtest/gtest.h \ - gtest/gtest-death-test.cc \ - gtest/gtest-death-test.h \ - gtest/gtest-filepath.cc \ - gtest/gtest-internal-inl.h \ - gtest/gtest-message.h \ - gtest/gtest-port.cc \ - gtest/gtest-spi.h \ - gtest/gtest_main.cc \ - gtest/gtest_pred_impl.h \ - gtest/gtest_prod.h \ - gtest/internal/gtest-death-test-internal.h \ - gtest/internal/gtest-filepath.h \ - gtest/internal/gtest-internal.h \ - gtest/internal/gtest-port.h \ - gtest/internal/gtest-string.h - -nodist_protobuf_test_SOURCES = $(protoc_outputs) - -TESTS = protobuf-test diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc deleted file mode 100644 index d3a051d0..00000000 --- a/src/google/protobuf/compiler/code_generator.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/code_generator.h> - -namespace google { -namespace protobuf { -namespace compiler { - -CodeGenerator::~CodeGenerator() {} -OutputDirectory::~OutputDirectory() {} - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h deleted file mode 100644 index 8f9938e3..00000000 --- a/src/google/protobuf/compiler/code_generator.h +++ /dev/null @@ -1,98 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Defines the abstract interface implemented by each of the language-specific -// code generators. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ - -#include <google/protobuf/stubs/common.h> -#include <string> - -namespace google { -namespace protobuf { - -namespace io { class ZeroCopyOutputStream; } -class FileDescriptor; - -namespace compiler { - -// Defined in this file. -class CodeGenerator; -class OutputDirectory; - -// The abstract interface to a class which generates code implementing a -// particular proto file in a particular language. A number of these may -// be registered with CommandLineInterface to support various languages. -class LIBPROTOC_EXPORT CodeGenerator { - public: - inline CodeGenerator() {} - virtual ~CodeGenerator(); - - // Generates code for the given proto file, generating one or more files in - // the given output directory. - // - // A parameter to be passed to the generator can be specified on the - // command line. This is intended to be used by Java and similar languages - // to specify which specific class from the proto file is to be generated, - // though it could have other uses as well. It is empty if no parameter was - // given. - // - // Returns true if successful. Otherwise, sets *error to a description of - // the problem (e.g. "invalid parameter") and returns false. - virtual bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(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 { - public: - inline OutputDirectory() {} - virtual ~OutputDirectory(); - - // Opens the given file, truncating it if it exists, and returns a - // ZeroCopyOutputStream that writes to the file. The caller takes ownership - // of the returned object. This method never fails (a dummy stream will be - // returned instead). - // - // The filename given should be relative to the root of the source tree. - // E.g. the C++ generator, when generating code for "foo/bar.proto", will - // generate the files "foo/bar.pb2.h" and "foo/bar.pb2.cc"; note that - // "foo/" is included in these filenames. The filename is not allowed to - // contain "." or ".." components. - virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory); -}; - -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc deleted file mode 100644 index d58fc3b8..00000000 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ /dev/null @@ -1,863 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef _MSC_VER -#include <io.h> -#include <direct.h> -#else -#include <unistd.h> -#endif -#include <errno.h> -#include <iostream> -#include <ctype.h> - -#include <google/protobuf/compiler/command_line_interface.h> -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> - - -namespace google { -namespace protobuf { -namespace compiler { - -#if defined(_WIN32) -#define mkdir(name, mode) mkdir(name) -#ifndef W_OK -#define W_OK 02 // not defined by MSVC for whatever reason -#endif -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#endif - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -namespace { -#if defined(_WIN32) && !defined(__CYGWIN__) -static const char* kPathSeparator = ";"; -#else -static const char* kPathSeparator = ":"; -#endif - -// Returns true if the text looks like a Windows-style absolute path, starting -// with a drive letter. Example: "C:\foo". -static bool IsWindowsAbsolutePath(const string& text) { -#if defined(_WIN32) || defined(__CYGWIN__) - return text.size() >= 3 && text[1] == ':' && - isalpha(text[0]) && - (text[2] == '/' || text[2] == '\\') && - text.find_last_of(':') == 1; -#else - return false; -#endif -} - -void SetFdToTextMode(int fd) { -#ifdef _WIN32 - if (_setmode(fd, _O_TEXT) == -1) { - // This should never happen, I think. - GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno); - } -#endif - // (Text and binary are the same on non-Windows platforms.) -} - -void SetFdToBinaryMode(int fd) { -#ifdef _WIN32 - if (_setmode(fd, _O_BINARY) == -1) { - // This should never happen, I think. - GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno); - } -#endif - // (Text and binary are the same on non-Windows platforms.) -} - -} // namespace - -// A MultiFileErrorCollector that prints errors to stderr. -class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, - public io::ErrorCollector { - public: - ErrorPrinter() {} - ~ErrorPrinter() {} - - // implements MultiFileErrorCollector ------------------------------ - void AddError(const string& filename, int line, int column, - const string& message) { - // Users typically expect 1-based line/column numbers, so we add 1 - // to each here. - cerr << filename; - if (line != -1) { - cerr << ":" << (line + 1) << ":" << (column + 1); - } - cerr << ": " << message << endl; - } - - // implements io::ErrorCollector ----------------------------------- - void AddError(int line, int column, const string& message) { - AddError("input", line, column, message); - } -}; - -// ------------------------------------------------------------------- - -// An OutputDirectory implementation that writes to disk. -class CommandLineInterface::DiskOutputDirectory : public OutputDirectory { - public: - DiskOutputDirectory(const string& root); - ~DiskOutputDirectory(); - - bool VerifyExistence(); - - inline bool had_error() { return had_error_; } - inline void set_had_error(bool value) { had_error_ = value; } - - // implements OutputDirectory -------------------------------------- - io::ZeroCopyOutputStream* Open(const string& filename); - - private: - string root_; - bool had_error_; -}; - -// A FileOutputStream that checks for errors in the destructor and reports -// them. We extend FileOutputStream via wrapping rather than inheritance -// for two reasons: -// 1) Implementation inheritance is evil. -// 2) We need to close the file descriptor *after* the FileOutputStream's -// destructor is run to make sure it flushes the file contents. -class CommandLineInterface::ErrorReportingFileOutput - : public io::ZeroCopyOutputStream { - public: - ErrorReportingFileOutput(int file_descriptor, - const string& filename, - DiskOutputDirectory* directory); - ~ErrorReportingFileOutput(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size) { return file_stream_->Next(data, size); } - void BackUp(int count) { file_stream_->BackUp(count); } - int64 ByteCount() const { return file_stream_->ByteCount(); } - - private: - scoped_ptr<io::FileOutputStream> file_stream_; - int file_descriptor_; - string filename_; - DiskOutputDirectory* directory_; -}; - -// ------------------------------------------------------------------- - -CommandLineInterface::DiskOutputDirectory::DiskOutputDirectory( - const string& root) - : root_(root), had_error_(false) { - // Add a '/' to the end if it doesn't already have one. But don't add a - // '/' to an empty string since this probably means the current directory. - if (!root_.empty() && root[root_.size() - 1] != '/') { - root_ += '/'; - } -} - -CommandLineInterface::DiskOutputDirectory::~DiskOutputDirectory() { -} - -bool CommandLineInterface::DiskOutputDirectory::VerifyExistence() { - if (!root_.empty()) { - // Make sure the directory exists. If it isn't a directory, this will fail - // because we added a '/' to the end of the name in the constructor. - if (access(root_.c_str(), W_OK) == -1) { - cerr << root_ << ": " << strerror(errno) << endl; - return false; - } - } - - return true; -} - -io::ZeroCopyOutputStream* CommandLineInterface::DiskOutputDirectory::Open( - const string& filename) { - // Recursively create parent directories to the output file. - vector<string> parts; - SplitStringUsing(filename, "/", &parts); - string path_so_far = root_; - for (int i = 0; i < parts.size() - 1; i++) { - path_so_far += parts[i]; - if (mkdir(path_so_far.c_str(), 0777) != 0) { - if (errno != EEXIST) { - cerr << filename << ": while trying to create directory " - << path_so_far << ": " << strerror(errno) << endl; - had_error_ = true; - // Return a dummy stream. - return new io::ArrayOutputStream(NULL, 0); - } - } - path_so_far += '/'; - } - - // Create the output file. - int file_descriptor; - do { - file_descriptor = - open((root_ + filename).c_str(), - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - } while (file_descriptor < 0 && errno == EINTR); - - if (file_descriptor < 0) { - // Failed to open. - cerr << filename << ": " << strerror(errno) << endl; - had_error_ = true; - // Return a dummy stream. - return new io::ArrayOutputStream(NULL, 0); - } - - return new ErrorReportingFileOutput(file_descriptor, filename, this); -} - -CommandLineInterface::ErrorReportingFileOutput::ErrorReportingFileOutput( - int file_descriptor, - const string& filename, - DiskOutputDirectory* directory) - : file_stream_(new io::FileOutputStream(file_descriptor)), - file_descriptor_(file_descriptor), - filename_(filename), - directory_(directory) {} - -CommandLineInterface::ErrorReportingFileOutput::~ErrorReportingFileOutput() { - // Check if we had any errors while writing. - if (file_stream_->GetErrno() != 0) { - cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl; - directory_->set_had_error(true); - } - - // Close the file stream. - if (!file_stream_->Close()) { - cerr << filename_ << ": " << strerror(file_stream_->GetErrno()) << endl; - directory_->set_had_error(true); - } -} - -// =================================================================== - -CommandLineInterface::CommandLineInterface() - : mode_(MODE_COMPILE), - imports_in_descriptor_set_(false), - disallow_services_(false), - inputs_are_proto_path_relative_(false) {} -CommandLineInterface::~CommandLineInterface() {} - -void CommandLineInterface::RegisterGenerator(const string& flag_name, - CodeGenerator* generator, - const string& help_text) { - GeneratorInfo info; - info.generator = generator; - info.help_text = help_text; - generators_[flag_name] = info; -} - -int CommandLineInterface::Run(int argc, const char* const argv[]) { - Clear(); - if (!ParseArguments(argc, argv)) return 1; - - // Set up the source tree. - DiskSourceTree source_tree; - for (int i = 0; i < proto_path_.size(); i++) { - source_tree.MapPath(proto_path_[i].first, proto_path_[i].second); - } - - // Map input files to virtual paths if necessary. - if (!inputs_are_proto_path_relative_) { - if (!MakeInputsBeProtoPathRelative(&source_tree)) { - return 1; - } - } - - // Allocate the Importer. - ErrorPrinter error_collector; - Importer importer(&source_tree, &error_collector); - - vector<const FileDescriptor*> parsed_files; - - // Parse each file and generate output. - for (int i = 0; i < input_files_.size(); i++) { - // Import the file. - const FileDescriptor* parsed_file = importer.Import(input_files_[i]); - if (parsed_file == NULL) return 1; - parsed_files.push_back(parsed_file); - - // Enforce --disallow_services. - if (disallow_services_ && parsed_file->service_count() > 0) { - cerr << parsed_file->name() << ": This file contains services, but " - "--disallow_services was used." << endl; - return 1; - } - - if (mode_ == MODE_COMPILE) { - // Generate output files. - for (int i = 0; i < output_directives_.size(); i++) { - if (!GenerateOutput(parsed_file, output_directives_[i])) { - return 1; - } - } - } - } - - if (!descriptor_set_name_.empty()) { - if (!WriteDescriptorSet(parsed_files)) { - return 1; - } - } - - if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) { - if (codec_type_.empty()) { - // HACK: Define an EmptyMessage type to use for decoding. - DescriptorPool pool; - FileDescriptorProto file; - file.set_name("empty_message.proto"); - file.add_message_type()->set_name("EmptyMessage"); - GOOGLE_CHECK(pool.BuildFile(file) != NULL); - codec_type_ = "EmptyMessage"; - if (!EncodeOrDecode(&pool)) { - return 1; - } - } else { - if (!EncodeOrDecode(importer.pool())) { - return 1; - } - } - } - - return 0; -} - -void CommandLineInterface::Clear() { - // Clear all members that are set by Run(). Note that we must not clear - // members which are set by other methods before Run() is called. - executable_name_.clear(); - proto_path_.clear(); - input_files_.clear(); - output_directives_.clear(); - codec_type_.clear(); - descriptor_set_name_.clear(); - - mode_ = MODE_COMPILE; - imports_in_descriptor_set_ = false; - disallow_services_ = false; -} - -bool CommandLineInterface::MakeInputsBeProtoPathRelative( - DiskSourceTree* source_tree) { - for (int i = 0; i < input_files_.size(); i++) { - string virtual_file, shadowing_disk_file; - switch (source_tree->DiskFileToVirtualFile( - input_files_[i], &virtual_file, &shadowing_disk_file)) { - case DiskSourceTree::SUCCESS: - input_files_[i] = virtual_file; - break; - case DiskSourceTree::SHADOWED: - cerr << input_files_[i] << ": Input is shadowed in the --proto_path " - "by \"" << shadowing_disk_file << "\". Either use the latter " - "file as your input or reorder the --proto_path so that the " - "former file's location comes first." << endl; - return false; - case DiskSourceTree::CANNOT_OPEN: - cerr << input_files_[i] << ": " << strerror(errno) << endl; - return false; - case DiskSourceTree::NO_MAPPING: - // First check if the file exists at all. - if (access(input_files_[i].c_str(), F_OK) < 0) { - // File does not even exist. - cerr << input_files_[i] << ": " << strerror(ENOENT) << endl; - } else { - cerr << input_files_[i] << ": File does not reside within any path " - "specified using --proto_path (or -I). You must specify a " - "--proto_path which encompasses this file." << endl; - } - return false; - } - } - - return true; -} - -bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { - executable_name_ = argv[0]; - - // Iterate through all arguments and parse them. - for (int i = 1; i < argc; i++) { - string name, value; - - if (ParseArgument(argv[i], &name, &value)) { - // Returned true => Use the next argument as the flag value. - if (i + 1 == argc || argv[i+1][0] == '-') { - cerr << "Missing value for flag: " << name << endl; - if (name == "--decode") { - cerr << "To decode an unknown message, use --decode_raw." << endl; - } - return false; - } else { - ++i; - value = argv[i]; - } - } - - if (!InterpretArgument(name, value)) return false; - } - - // If no --proto_path was given, use the current working directory. - if (proto_path_.empty()) { - proto_path_.push_back(make_pair("", ".")); - } - - // Check some errror cases. - bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); - if (decoding_raw && !input_files_.empty()) { - cerr << "When using --decode_raw, no input files should be given." << endl; - return false; - } else if (!decoding_raw && input_files_.empty()) { - cerr << "Missing input file." << endl; - return false; - } - if (mode_ == MODE_COMPILE && output_directives_.empty() && - descriptor_set_name_.empty()) { - cerr << "Missing output directives." << endl; - return false; - } - if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) { - cerr << "--include_imports only makes sense when combined with " - "--descriptor_set_name." << endl; - } - - return true; -} - -bool CommandLineInterface::ParseArgument(const char* arg, - string* name, string* value) { - bool parsed_value = false; - - if (arg[0] != '-') { - // Not a flag. - name->clear(); - parsed_value = true; - *value = arg; - } else if (arg[1] == '-') { - // Two dashes: Multi-character name, with '=' separating name and - // value. - const char* equals_pos = strchr(arg, '='); - if (equals_pos != NULL) { - *name = string(arg, equals_pos - arg); - *value = equals_pos + 1; - parsed_value = true; - } else { - *name = arg; - } - } else { - // One dash: One-character name, all subsequent characters are the - // value. - if (arg[1] == '\0') { - // arg is just "-". We treat this as an input file, except that at - // present this will just lead to a "file not found" error. - name->clear(); - *value = arg; - parsed_value = true; - } else { - *name = string(arg, 2); - *value = arg + 2; - parsed_value = !value->empty(); - } - } - - // Need to return true iff the next arg should be used as the value for this - // one, false otherwise. - - if (parsed_value) { - // We already parsed a value for this flag. - return false; - } - - if (*name == "-h" || *name == "--help" || - *name == "--disallow_services" || - *name == "--include_imports" || - *name == "--version" || - *name == "--decode_raw") { - // HACK: These are the only flags that don't take a value. - // They probably should not be hard-coded like this but for now it's - // not worth doing better. - return false; - } - - // Next argument is the flag value. - return true; -} - -bool CommandLineInterface::InterpretArgument(const string& name, - const string& value) { - if (name.empty()) { - // Not a flag. Just a filename. - if (value.empty()) { - cerr << "You seem to have passed an empty string as one of the " - "arguments to " << executable_name_ << ". This is actually " - "sort of hard to do. Congrats. Unfortunately it is not valid " - "input so the program is going to die now." << endl; - return false; - } - - input_files_.push_back(value); - - } else if (name == "-I" || name == "--proto_path") { - // Java's -classpath (and some other languages) delimits path components - // with colons. Let's accept that syntax too just to make things more - // intuitive. - vector<string> parts; - SplitStringUsing(value, kPathSeparator, &parts); - - for (int i = 0; i < parts.size(); i++) { - string virtual_path; - string disk_path; - - int equals_pos = parts[i].find_first_of('='); - if (equals_pos == string::npos) { - virtual_path = ""; - disk_path = parts[i]; - } else { - virtual_path = parts[i].substr(0, equals_pos); - disk_path = parts[i].substr(equals_pos + 1); - } - - if (disk_path.empty()) { - cerr << "--proto_path passed empty directory name. (Use \".\" for " - "current directory.)" << endl; - return false; - } - - // Make sure disk path exists, warn otherwise. - if (access(disk_path.c_str(), F_OK) < 0) { - cerr << disk_path << ": warning: directory does not exist." << endl; - } - - proto_path_.push_back(make_pair(virtual_path, disk_path)); - } - - } else if (name == "-o" || name == "--descriptor_set_out") { - if (!descriptor_set_name_.empty()) { - cerr << name << " may only be passed once." << endl; - return false; - } - if (value.empty()) { - cerr << name << " requires a non-empty value." << endl; - return false; - } - if (mode_ != MODE_COMPILE) { - cerr << "Cannot use --encode or --decode and generate descriptors at the " - "same time." << endl; - return false; - } - descriptor_set_name_ = value; - - } else if (name == "--include_imports") { - if (imports_in_descriptor_set_) { - cerr << name << " may only be passed once." << endl; - return false; - } - imports_in_descriptor_set_ = true; - - } else if (name == "-h" || name == "--help") { - PrintHelpText(); - return false; // Exit without running compiler. - - } else if (name == "--version") { - if (!version_info_.empty()) { - cout << version_info_ << endl; - } - cout << "libprotoc " - << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION) - << endl; - return false; // Exit without running compiler. - - } else if (name == "--disallow_services") { - disallow_services_ = true; - - } else if (name == "--encode" || name == "--decode" || - name == "--decode_raw") { - if (mode_ != MODE_COMPILE) { - cerr << "Only one of --encode and --decode can be specified." << endl; - return false; - } - if (!output_directives_.empty() || !descriptor_set_name_.empty()) { - cerr << "Cannot use " << name - << " and generate code or descriptors at the same time." << endl; - return false; - } - - mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE; - - if (value.empty() && name != "--decode_raw") { - cerr << "Type name for " << name << " cannot be blank." << endl; - if (name == "--decode") { - cerr << "To decode an unknown message, use --decode_raw." << endl; - } - return false; - } else if (!value.empty() && name == "--decode_raw") { - cerr << "--decode_raw does not take a parameter." << endl; - return false; - } - - codec_type_ = value; - - } else { - // Some other flag. Look it up in the generators list. - GeneratorMap::const_iterator iter = generators_.find(name); - if (iter == generators_.end()) { - cerr << "Unknown flag: " << name << endl; - return false; - } - - // It's an output flag. Add it to the output directives. - if (mode_ != MODE_COMPILE) { - cerr << "Cannot use --encode or --decode and generate code at the " - "same time." << endl; - return false; - } - - OutputDirective directive; - directive.name = name; - directive.generator = iter->second.generator; - - // Split value at ':' to separate the generator parameter from the - // filename. However, avoid doing this if the colon is part of a valid - // Windows-style absolute path. - string::size_type colon_pos = value.find_first_of(':'); - if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) { - directive.output_location = value; - } else { - directive.parameter = value.substr(0, colon_pos); - directive.output_location = value.substr(colon_pos + 1); - } - - output_directives_.push_back(directive); - } - - return true; -} - -void CommandLineInterface::PrintHelpText() { - // Sorry for indentation here; line wrapping would be uglier. - cerr << -"Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n" -"Parse PROTO_FILES and generate output based on the options given:\n" -" -IPATH, --proto_path=PATH Specify the directory in which to search for\n" -" imports. May be specified multiple times;\n" -" directories will be searched in order. If not\n" -" given, the current working directory is used.\n" -" --version Show version info and exit.\n" -" -h, --help Show this text and exit.\n" -" --encode=MESSAGE_TYPE Read a text-format message of the given type\n" -" from standard input and write it in binary\n" -" to standard output. The message type must\n" -" be defined in PROTO_FILES or their imports.\n" -" --decode=MESSAGE_TYPE Read a binary message of the given type from\n" -" standard input and write it in text format\n" -" to standard output. The message type must\n" -" be defined in PROTO_FILES or their imports.\n" -" --decode_raw Read an arbitrary protocol message from\n" -" standard input and write the raw tag/value\n" -" pairs in text format to standard output. No\n" -" PROTO_FILES should be given when using this\n" -" flag.\n" -" -oFILE, Writes a FileDescriptorSet (a protocol buffer,\n" -" --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n" -" the input files to FILE.\n" -" --include_imports When using --descriptor_set_out, also include\n" -" all dependencies of the input files in the\n" -" set, so that the set is self-contained." << endl; - - for (GeneratorMap::iterator iter = generators_.begin(); - iter != generators_.end(); ++iter) { - // FIXME(kenton): If the text is long enough it will wrap, which is ugly, - // but fixing this nicely (e.g. splitting on spaces) is probably more - // trouble than it's worth. - cerr << " " << iter->first << "=OUT_DIR " - << string(19 - iter->first.size(), ' ') // Spaces for alignment. - << iter->second.help_text << endl; - } -} - -bool CommandLineInterface::GenerateOutput( - const FileDescriptor* parsed_file, - const OutputDirective& output_directive) { - // Create the output directory. - DiskOutputDirectory output_directory(output_directive.output_location); - if (!output_directory.VerifyExistence()) { - return false; - } - - // Opened successfully. Write it. - - // Call the generator. - string error; - if (!output_directive.generator->Generate( - parsed_file, output_directive.parameter, &output_directory, &error)) { - // Generator returned an error. - cerr << output_directive.name << ": " << error << endl; - return false; - } - - // Check for write errors. - if (output_directory.had_error()) { - return false; - } - - return true; -} - -bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { - // Look up the type. - const Descriptor* type = pool->FindMessageTypeByName(codec_type_); - if (type == NULL) { - cerr << "Type not defined: " << codec_type_ << endl; - return false; - } - - DynamicMessageFactory dynamic_factory(pool); - scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New()); - - if (mode_ == MODE_ENCODE) { - SetFdToTextMode(STDIN_FILENO); - SetFdToBinaryMode(STDOUT_FILENO); - } else { - SetFdToBinaryMode(STDIN_FILENO); - SetFdToTextMode(STDOUT_FILENO); - } - - io::FileInputStream in(STDIN_FILENO); - io::FileOutputStream out(STDOUT_FILENO); - - if (mode_ == MODE_ENCODE) { - // Input is text. - ErrorPrinter error_collector; - TextFormat::Parser parser; - parser.RecordErrorsTo(&error_collector); - parser.AllowPartialMessage(true); - - if (!parser.Parse(&in, message.get())) { - cerr << "Failed to parse input." << endl; - return false; - } - } else { - // Input is binary. - if (!message->ParsePartialFromZeroCopyStream(&in)) { - cerr << "Failed to parse input." << endl; - return false; - } - } - - if (!message->IsInitialized()) { - cerr << "warning: Input message is missing required fields: " - << message->InitializationErrorString() << endl; - } - - if (mode_ == MODE_ENCODE) { - // Output is binary. - if (!message->SerializePartialToZeroCopyStream(&out)) { - cerr << "output: I/O error." << endl; - return false; - } - } else { - // Output is text. - if (!TextFormat::Print(*message, &out)) { - cerr << "output: I/O error." << endl; - return false; - } - } - - return true; -} - -bool CommandLineInterface::WriteDescriptorSet( - const vector<const FileDescriptor*> parsed_files) { - FileDescriptorSet file_set; - set<const FileDescriptor*> already_added; - vector<const FileDescriptor*> to_add(parsed_files); - - while (!to_add.empty()) { - const FileDescriptor* file = to_add.back(); - to_add.pop_back(); - if (already_added.insert(file).second) { - // This file was not already in the set. - file->CopyTo(file_set.add_file()); - - if (imports_in_descriptor_set_) { - // Add all of this file's dependencies. - for (int i = 0; i < file->dependency_count(); i++) { - to_add.push_back(file->dependency(i)); - } - } - } - } - - int fd; - do { - fd = open(descriptor_set_name_.c_str(), - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); - } while (fd < 0 && errno == EINTR); - - if (fd < 0) { - perror(descriptor_set_name_.c_str()); - return false; - } - - io::FileOutputStream out(fd); - if (!file_set.SerializeToZeroCopyStream(&out)) { - cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; - out.Close(); - return false; - } - if (!out.Close()) { - cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; - return false; - } - - return true; -} - - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h deleted file mode 100644 index 9185e47a..00000000 --- a/src/google/protobuf/compiler/command_line_interface.h +++ /dev/null @@ -1,238 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Implements the Protocol Compiler front-end such that it may be reused by -// custom compilers written to support other languages. - -#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ -#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ - -#include <google/protobuf/stubs/common.h> -#include <string> -#include <vector> -#include <map> -#include <set> -#include <utility> - -namespace google { -namespace protobuf { - -class FileDescriptor; // descriptor.h -class DescriptorPool; // descriptor.h - -namespace compiler { - -class CodeGenerator; // code_generator.h -class DiskSourceTree; // importer.h - -// This class implements the command-line interface to the protocol compiler. -// It is designed to make it very easy to create a custom protocol compiler -// supporting the languages of your choice. For example, if you wanted to -// create a custom protocol compiler binary which includes both the regular -// C++ support plus support for your own custom output "Foo", you would -// write a class "FooGenerator" which implements the CodeGenerator interface, -// then write a main() procedure like this: -// -// int main(int argc, char* argv[]) { -// google::protobuf::compiler::CommandLineInterface cli; -// -// // Support generation of C++ source and headers. -// google::protobuf::compiler::cpp::CppGenerator cpp_generator; -// cli.RegisterGenerator("--cpp_out", &cpp_generator, -// "Generate C++ source and header."); -// -// // Support generation of Foo code. -// FooGenerator foo_generator; -// cli.RegisterGenerator("--foo_out", &foo_generator, -// "Generate Foo file."); -// -// return cli.Run(argc, argv); -// } -// -// The compiler is invoked with syntax like: -// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src foo.proto -// -// For a full description of the command-line syntax, invoke it with --help. -class LIBPROTOC_EXPORT CommandLineInterface { - public: - CommandLineInterface(); - ~CommandLineInterface(); - - // Register a code generator for a language. - // - // Parameters: - // * flag_name: The command-line flag used to specify an output file of - // this type. The name must start with a '-'. If the name is longer - // than one letter, it must start with two '-'s. - // * generator: The CodeGenerator which will be called to generate files - // of this type. - // * help_text: Text describing this flag in the --help output. - // - // Some generators accept extra parameters. You can specify this parameter - // on the command-line by placing it before the output directory, separated - // by a colon: - // protoc --foo_out=enable_bar:outdir - // The text before the colon is passed to CodeGenerator::Generate() as the - // "parameter". - void RegisterGenerator(const string& flag_name, - CodeGenerator* generator, - const string& help_text); - - // Run the Protocol Compiler with the given command-line parameters. - // Returns the error code which should be returned by main(). - // - // It may not be safe to call Run() in a multi-threaded environment because - // it calls strerror(). I'm not sure why you'd want to do this anyway. - int Run(int argc, const char* const argv[]); - - // Call SetInputsAreCwdRelative(true) if the input files given on the command - // line should be interpreted relative to the proto import path specified - // using --proto_path or -I flags. Otherwise, input file names will be - // interpreted relative to the current working directory (or as absolute - // paths if they start with '/'), though they must still reside inside - // a directory given by --proto_path or the compiler will fail. The latter - // mode is generally more intuitive and easier to use, especially e.g. when - // defining implicit rules in Makefiles. - void SetInputsAreProtoPathRelative(bool enable) { - inputs_are_proto_path_relative_ = enable; - } - - // Provides some text which will be printed when the --version flag is - // used. The version of libprotoc will also be printed on the next line - // after this text. - void SetVersionInfo(const string& text) { - version_info_ = text; - } - - - private: - // ----------------------------------------------------------------- - - class ErrorPrinter; - class DiskOutputDirectory; - class ErrorReportingFileOutput; - - // Clear state from previous Run(). - void Clear(); - - // Remaps each file in input_files_ so that it is relative to one of the - // directories in proto_path_. Returns false if an error occurred. This - // is only used if inputs_are_proto_path_relative_ is false. - bool MakeInputsBeProtoPathRelative( - DiskSourceTree* source_tree); - - // Parse all command-line arguments. - bool ParseArguments(int argc, const char* const argv[]); - - // Parses a command-line argument into a name/value pair. Returns - // true if the next argument in the argv should be used as the value, - // false otherwise. - // - // Exmaples: - // "-Isrc/protos" -> - // name = "-I", value = "src/protos" - // "--cpp_out=src/foo.pb2.cc" -> - // name = "--cpp_out", value = "src/foo.pb2.cc" - // "foo.proto" -> - // name = "", value = "foo.proto" - bool ParseArgument(const char* arg, string* name, string* value); - - // Interprets arguments parsed with ParseArgument. - bool InterpretArgument(const string& name, const string& value); - - // Print the --help text to stderr. - void PrintHelpText(); - - // Generate the given output file from the given input. - struct OutputDirective; // see below - bool GenerateOutput(const FileDescriptor* proto_file, - const OutputDirective& output_directive); - - // Implements --encode and --decode. - bool EncodeOrDecode(const DescriptorPool* pool); - - // Implements the --descriptor_set_out option. - bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files); - - // ----------------------------------------------------------------- - - // The name of the executable as invoked (i.e. argv[0]). - string executable_name_; - - // Version info set with SetVersionInfo(). - string version_info_; - - // Map from flag names to registered generators. - struct GeneratorInfo { - CodeGenerator* generator; - string help_text; - }; - typedef map<string, GeneratorInfo> GeneratorMap; - GeneratorMap generators_; - - // Stuff parsed from command line. - enum Mode { - MODE_COMPILE, // Normal mode: parse .proto files and compile them. - MODE_ENCODE, // --encode: read text from stdin, write binary to stdout. - MODE_DECODE // --decode: read binary from stdin, write text to stdout. - }; - - Mode mode_; - - vector<pair<string, string> > proto_path_; // Search path for proto files. - vector<string> input_files_; // Names of the input proto files. - - // output_directives_ lists all the files we are supposed to output and what - // generator to use for each. - struct OutputDirective { - string name; - CodeGenerator* generator; - string parameter; - string output_location; - }; - vector<OutputDirective> output_directives_; - - // When using --encode or --decode, this names the type we are encoding or - // decoding. (Empty string indicates --decode_raw.) - string codec_type_; - - // If --descriptor_set_out was given, this is the filename to which the - // FileDescriptorSet should be written. Otherwise, empty. - string descriptor_set_name_; - - // True if --include_imports was given, meaning that we should - // write all transitive dependencies to the DescriptorSet. Otherwise, only - // the .proto files listed on the command-line are added. - bool imports_in_descriptor_set_; - - // Was the --disallow_services flag used? - bool disallow_services_; - - // See SetInputsAreProtoPathRelative(). - bool inputs_are_proto_path_relative_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); -}; - -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc deleted file mode 100644 index d67cbe0d..00000000 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ /dev/null @@ -1,1278 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef _MSC_VER -#include <io.h> -#else -#include <unistd.h> -#endif -#include <vector> - -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/compiler/command_line_interface.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/testing/file.h> -#include <google/protobuf/stubs/strutil.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace compiler { - -#if defined(_WIN32) -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#endif - -namespace { - -class CommandLineInterfaceTest : public testing::Test { - protected: - virtual void SetUp(); - virtual void TearDown(); - - // Runs the CommandLineInterface with the given command line. The - // command is automatically split on spaces, and the string "$tmpdir" - // is replaced with TestTempDir(). - void Run(const string& command); - - // ----------------------------------------------------------------- - // Methods to set up the test (called before Run()). - - class MockCodeGenerator; - class NullCodeGenerator; - - // Registers a MockCodeGenerator with the given name. - MockCodeGenerator* RegisterGenerator(const string& generator_name, - const string& flag_name, - const string& filename, - const string& help_text); - MockCodeGenerator* RegisterErrorGenerator(const string& generator_name, - const string& error_text, - const string& flag_name, - const string& filename, - const string& help_text); - - // Registers a CodeGenerator which will not actually generate anything, - // but records the parameter passed to the generator. - NullCodeGenerator* RegisterNullGenerator(const string& flag_name); - - // Create a temp file within temp_directory_ with the given name. - // The containing directory is also created if necessary. - void CreateTempFile(const string& name, const string& contents); - - void SetInputsAreProtoPathRelative(bool enable) { - cli_.SetInputsAreProtoPathRelative(enable); - } - - // ----------------------------------------------------------------- - // Methods to check the test results (called after Run()). - - // Checks that no text was written to stderr during Run(), and Run() - // returned 0. - void ExpectNoErrors(); - - // Checks that Run() returned non-zero and the stderr output is exactly - // the text given. expected_test may contain references to "$tmpdir", - // which will be replaced by the temporary directory path. - void ExpectErrorText(const string& expected_text); - - // Checks that Run() returned non-zero and the stderr contains the given - // substring. - void ExpectErrorSubstring(const string& expected_substring); - - // Returns true if ExpectErrorSubstring(expected_substring) would pass, but - // does not fail otherwise. - bool HasAlternateErrorSubstring(const string& expected_substring); - - // Checks that MockCodeGenerator::Generate() was called in the given - // context. That is, this tests if the generator with the given name - // was called with the given parameter and proto file and produced the - // given output file. This is checked by reading the output file and - // checking that it contains the content that MockCodeGenerator would - // generate given these inputs. message_name is the name of the first - // message that appeared in the proto file; this is just to make extra - // sure that the correct file was parsed. - void ExpectGenerated(const string& generator_name, - const string& parameter, - const string& proto_name, - const string& message_name, - const string& output_file); - - void ReadDescriptorSet(const string& filename, - FileDescriptorSet* descriptor_set); - - private: - // The object we are testing. - CommandLineInterface cli_; - - // We create a directory within TestTempDir() in order to add extra - // protection against accidentally deleting user files (since we recursively - // delete this directory during the test). This is the full path of that - // directory. - string temp_directory_; - - // The result of Run(). - int return_code_; - - // The captured stderr output. - string error_text_; - - // Pointers which need to be deleted later. - vector<CodeGenerator*> mock_generators_to_delete_; -}; - -// A mock CodeGenerator which outputs information about the context in which -// it was called, which can then be checked. Output is written to a filename -// constructed by concatenating the filename_prefix (given to the constructor) -// with the proto file name, separated by a '.'. -class CommandLineInterfaceTest::MockCodeGenerator : public CodeGenerator { - public: - // Create a MockCodeGenerator whose Generate() method returns true. - MockCodeGenerator(const string& name, const string& filename_prefix); - - // Create a MockCodeGenerator whose Generate() method returns false - // and sets the error string to the given string. - MockCodeGenerator(const string& name, const string& filename_prefix, - const string& error); - - ~MockCodeGenerator(); - - void set_expect_write_error(bool value) { - expect_write_error_ = value; - } - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - string name_; - string filename_prefix_; - bool return_error_; - string error_; - bool expect_write_error_; -}; - -class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { - public: - NullCodeGenerator() : called_(false) {} - ~NullCodeGenerator() {} - - mutable bool called_; - mutable string parameter_; - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - called_ = true; - parameter_ = parameter; - return true; - } -}; - -// =================================================================== - -void CommandLineInterfaceTest::SetUp() { - // Most of these tests were written before this option was added, so we - // run with the option on (which used to be the only way) except in certain - // tests where we turn it off. - cli_.SetInputsAreProtoPathRelative(true); - - temp_directory_ = TestTempDir() + "/proto2_cli_test_temp"; - - // If the temp directory already exists, it must be left over from a - // previous run. Delete it. - if (File::Exists(temp_directory_)) { - File::DeleteRecursively(temp_directory_, NULL, NULL); - } - - // Create the temp directory. - GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE)); -} - -void CommandLineInterfaceTest::TearDown() { - // Delete the temp directory. - File::DeleteRecursively(temp_directory_, NULL, NULL); - - // Delete all the MockCodeGenerators. - for (int i = 0; i < mock_generators_to_delete_.size(); i++) { - delete mock_generators_to_delete_[i]; - } - mock_generators_to_delete_.clear(); -} - -void CommandLineInterfaceTest::Run(const string& command) { - vector<string> args; - SplitStringUsing(command, " ", &args); - - scoped_array<const char*> argv(new const char*[args.size()]); - - for (int i = 0; i < args.size(); i++) { - args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true); - argv[i] = args[i].c_str(); - } - - CaptureTestStderr(); - - return_code_ = cli_.Run(args.size(), argv.get()); - - error_text_ = GetCapturedTestStderr(); -} - -// ------------------------------------------------------------------- - -CommandLineInterfaceTest::MockCodeGenerator* -CommandLineInterfaceTest::RegisterGenerator( - const string& generator_name, - const string& flag_name, - const string& filename, - const string& help_text) { - MockCodeGenerator* generator = - new MockCodeGenerator(generator_name, filename); - mock_generators_to_delete_.push_back(generator); - - cli_.RegisterGenerator(flag_name, generator, help_text); - return generator; -} - -CommandLineInterfaceTest::MockCodeGenerator* -CommandLineInterfaceTest::RegisterErrorGenerator( - const string& generator_name, - const string& error_text, - const string& flag_name, - const string& filename_prefix, - const string& help_text) { - MockCodeGenerator* generator = - new MockCodeGenerator(generator_name, filename_prefix, error_text); - mock_generators_to_delete_.push_back(generator); - - cli_.RegisterGenerator(flag_name, generator, help_text); - return generator; -} - -CommandLineInterfaceTest::NullCodeGenerator* -CommandLineInterfaceTest::RegisterNullGenerator( - const string& flag_name) { - NullCodeGenerator* generator = new NullCodeGenerator; - mock_generators_to_delete_.push_back(generator); - cli_.RegisterGenerator(flag_name, generator, ""); - return generator; -} - -void CommandLineInterfaceTest::CreateTempFile( - const string& name, - const string& contents) { - // Create parent directory, if necessary. - string::size_type slash_pos = name.find_last_of('/'); - if (slash_pos != string::npos) { - string dir = name.substr(0, slash_pos); - File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777); - } - - // Write file. - string full_name = temp_directory_ + "/" + name; - File::WriteStringToFileOrDie(contents, full_name); -} - -// ------------------------------------------------------------------- - -void CommandLineInterfaceTest::ExpectNoErrors() { - EXPECT_EQ(0, return_code_); - EXPECT_EQ("", error_text_); -} - -void CommandLineInterfaceTest::ExpectErrorText(const string& expected_text) { - EXPECT_NE(0, return_code_); - EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true), - error_text_); -} - -void CommandLineInterfaceTest::ExpectErrorSubstring( - const string& expected_substring) { - EXPECT_NE(0, return_code_); - EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_); -} - -bool CommandLineInterfaceTest::HasAlternateErrorSubstring( - const string& expected_substring) { - EXPECT_NE(0, return_code_); - return error_text_.find(expected_substring) != string::npos; -} - -void CommandLineInterfaceTest::ExpectGenerated( - const string& generator_name, - const string& parameter, - const string& proto_name, - const string& message_name, - const string& output_file_prefix) { - // Open and read the file. - string output_file = output_file_prefix + "." + proto_name; - string file_contents; - ASSERT_TRUE(File::ReadFileToString(temp_directory_ + "/" + output_file, - &file_contents)) - << "Failed to open file: " + output_file; - - // Check that the contents are as we expect. - string expected_contents = - generator_name + ": " + parameter + ", " + proto_name + ", " + - message_name + "\n"; - EXPECT_EQ(expected_contents, file_contents) - << "Output file did not have expected contents: " + output_file; -} - -void CommandLineInterfaceTest::ReadDescriptorSet( - const string& filename, FileDescriptorSet* descriptor_set) { - string path = temp_directory_ + "/" + filename; - string file_contents; - if (!File::ReadFileToString(path, &file_contents)) { - FAIL() << "File not found: " << path; - } - if (!descriptor_set->ParseFromString(file_contents)) { - FAIL() << "Could not parse file contents: " << path; - } -} - -// =================================================================== - -CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator( - const string& name, const string& filename_prefix) - : name_(name), - filename_prefix_(filename_prefix), - return_error_(false), - expect_write_error_(false) { -} - -CommandLineInterfaceTest::MockCodeGenerator::MockCodeGenerator( - const string& name, const string& filename_prefix, const string& error) - : name_(name), - filename_prefix_(filename_prefix), - return_error_(true), - error_(error), - expect_write_error_(false) { -} - -CommandLineInterfaceTest::MockCodeGenerator::~MockCodeGenerator() {} - -bool CommandLineInterfaceTest::MockCodeGenerator::Generate( - const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename_prefix_ + "." + file->name())); - io::Printer printer(output.get(), '$'); - map<string, string> vars; - vars["name"] = name_; - vars["parameter"] = parameter; - vars["proto_name"] = file->name(); - vars["message_name"] = file->message_type_count() > 0 ? - file->message_type(0)->full_name().c_str() : "(none)"; - - printer.Print(vars, "$name$: $parameter$, $proto_name$, $message_name$\n"); - - if (expect_write_error_) { - EXPECT_TRUE(printer.failed()); - } else { - EXPECT_FALSE(printer.failed()); - } - - *error = error_; - return !return_error_; -} - -// =================================================================== - -TEST_F(CommandLineInterfaceTest, BasicOutput) { - // Test that the common case works. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, MultipleInputs) { - // Test parsing multiple input files. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - CreateTempFile("bar.proto", - "syntax = \"proto2\";\n" - "message Bar {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto bar.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); - ExpectGenerated("test_generator", "", "bar.proto", "Bar", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, CreateDirectory) { - // Test that when we output to a sub-directory, it is created. - - RegisterGenerator("test_generator", "--test_out", - "bar/baz/output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", - "foo.proto", "Foo", "bar/baz/output.test"); -} - -TEST_F(CommandLineInterfaceTest, GeneratorParameters) { - // Test that generator parameters are correctly parsed from the command line. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=TestParameter:$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "TestParameter", - "foo.proto", "Foo", "output.test"); -} - -#if defined(_WIN32) || defined(__CYGWIN__) - -TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { - // Test that the output path can be a Windows-style path. - - NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n"); - - Run("protocol_compiler --test_out=C:\\ " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - EXPECT_TRUE(generator->called_); - EXPECT_EQ("", generator->parameter_); -} - -TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) { - // Test that we can have a windows-style output path and a parameter. - - NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n"); - - Run("protocol_compiler --test_out=bar:C:\\ " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - EXPECT_TRUE(generator->called_); - EXPECT_EQ("bar", generator->parameter_); -} - -#endif // defined(_WIN32) || defined(__CYGWIN__) - -TEST_F(CommandLineInterfaceTest, PathLookup) { - // Test that specifying multiple directories in the proto search path works. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("b/bar.proto", - "syntax = \"proto2\";\n" - "message Bar {}\n"); - CreateTempFile("a/foo.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n" - "message Foo {\n" - " optional Bar a = 1;\n" - "}\n"); - CreateTempFile("b/foo.proto", "this should not be parsed\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { - // Same as PathLookup, but we provide the proto_path in a single flag. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("b/bar.proto", - "syntax = \"proto2\";\n" - "message Bar {}\n"); - CreateTempFile("a/foo.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n" - "message Foo {\n" - " optional Bar a = 1;\n" - "}\n"); - CreateTempFile("b/foo.proto", "this should not be parsed\n"); - -#undef PATH_SEPARATOR -#if defined(_WIN32) -#define PATH_SEPARATOR ";" -#else -#define PATH_SEPARATOR ":" -#endif - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/a"PATH_SEPARATOR"$tmpdir/b foo.proto"); - -#undef PATH_SEPARATOR - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, NonRootMapping) { - // Test setting up a search path mapping a directory to a non-root location. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=bar=$tmpdir bar/foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, MultipleGenerators) { - // Test that we can have multiple generators and use both in one invocation, - // each with a different output directory. - - RegisterGenerator("test_generator_1", "--test1_out", - "output1.test", "Test output 1."); - RegisterGenerator("test_generator_2", "--test2_out", - "output2.test", "Test output 2."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - // Create the "a" and "b" sub-directories. - CreateTempFile("a/dummy", ""); - CreateTempFile("b/dummy", ""); - - Run("protocol_compiler " - "--test1_out=$tmpdir/a " - "--test2_out=$tmpdir/b " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator_1", "", "foo.proto", "Foo", "a/output1.test"); - ExpectGenerated("test_generator_2", "", "foo.proto", "Foo", "b/output2.test"); -} - -TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) { - // Test that --disallow_services doesn't cause a problem when there are no - // services. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --disallow_services --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) { - // Test that --disallow_services produces an error when there are services. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n" - "service Bar {}\n"); - - Run("protocol_compiler --disallow_services --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorSubstring("foo.proto: This file contains services"); -} - -TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { - // Test that services work fine as long as --disallow_services is not used. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n" - "service Bar {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { - // Test that we can accept working-directory-relative input files. - - SetInputsAreProtoPathRelative(false); - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir $tmpdir/foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) { - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - CreateTempFile("bar.proto", - "syntax = \"proto2\";\n" - "import \"foo.proto\";\n" - "message Bar {\n" - " optional Foo foo = 1;\n" - "}\n"); - - Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " - "--proto_path=$tmpdir bar.proto"); - - ExpectNoErrors(); - - FileDescriptorSet descriptor_set; - ReadDescriptorSet("descriptor_set", &descriptor_set); - if (HasFatalFailure()) return; - ASSERT_EQ(1, descriptor_set.file_size()); - EXPECT_EQ("bar.proto", descriptor_set.file(0).name()); -} - -TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) { - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - CreateTempFile("bar.proto", - "syntax = \"proto2\";\n" - "import \"foo.proto\";\n" - "message Bar {\n" - " optional Foo foo = 1;\n" - "}\n"); - - Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set " - "--include_imports --proto_path=$tmpdir bar.proto"); - - ExpectNoErrors(); - - FileDescriptorSet descriptor_set; - ReadDescriptorSet("descriptor_set", &descriptor_set); - if (HasFatalFailure()) return; - ASSERT_EQ(2, descriptor_set.file_size()); - if (descriptor_set.file(0).name() == "bar.proto") { - swap(descriptor_set.mutable_file()->mutable_data()[0], - descriptor_set.mutable_file()->mutable_data()[1]); - } - EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); - EXPECT_EQ("bar.proto", descriptor_set.file(1).name()); -} - -// ------------------------------------------------------------------- - -TEST_F(CommandLineInterfaceTest, ParseErrors) { - // Test that parse errors are reported. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "badsyntax\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorText( - "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); -} - -TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { - // Test that parse errors are reported from multiple files. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - // We set up files such that foo.proto actually depends on bar.proto in - // two ways: Directly and through baz.proto. bar.proto's errors should - // only be reported once. - CreateTempFile("bar.proto", - "syntax = \"proto2\";\n" - "badsyntax\n"); - CreateTempFile("baz.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n"); - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n" - "import \"baz.proto\";\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorText( - "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n" - "baz.proto: Import \"bar.proto\" was not found or had errors.\n" - "foo.proto: Import \"bar.proto\" was not found or had errors.\n" - "foo.proto: Import \"baz.proto\" was not found or had errors.\n"); -} - -TEST_F(CommandLineInterfaceTest, InputNotFoundError) { - // Test what happens if the input file is not found. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorText( - "foo.proto: File not found.\n"); -} - -TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { - // Test what happens when a working-directory-relative input file is not - // found. - - SetInputsAreProtoPathRelative(false); - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir $tmpdir/foo.proto"); - - ExpectErrorText( - "$tmpdir/foo.proto: No such file or directory\n"); -} - -TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { - // Test what happens when a working-directory-relative input file is not - // mapped to a virtual path. - - SetInputsAreProtoPathRelative(false); - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - // Create a directory called "bar" so that we can point --proto_path at it. - CreateTempFile("bar/dummy", ""); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); - - ExpectErrorText( - "$tmpdir/foo.proto: File does not reside within any path " - "specified using --proto_path (or -I). You must specify a " - "--proto_path which encompasses this file.\n"); -} - -TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { - // Check what happens if the input file is not found *and* is not mapped - // in the proto_path. - - SetInputsAreProtoPathRelative(false); - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - // Create a directory called "bar" so that we can point --proto_path at it. - CreateTempFile("bar/dummy", ""); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/bar $tmpdir/foo.proto"); - - ExpectErrorText( - "$tmpdir/foo.proto: No such file or directory\n"); -} - -TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { - // Test what happens when a working-directory-relative input file is shadowed - // by another file in the virtual path. - - SetInputsAreProtoPathRelative(false); - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo/foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - CreateTempFile("bar/foo.proto", - "syntax = \"proto2\";\n" - "message Bar {}\n"); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar " - "$tmpdir/bar/foo.proto"); - - ExpectErrorText( - "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path " - "by \"$tmpdir/foo/foo.proto\". Either use the latter " - "file as your input or reorder the --proto_path so that the " - "former file's location comes first.\n"); -} - -TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { - // Test what happens if the input file is not found. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/foo foo.proto"); - - ExpectErrorText( - "$tmpdir/foo: warning: directory does not exist.\n" - "foo.proto: File not found.\n"); -} - -TEST_F(CommandLineInterfaceTest, MissingInputError) { - // Test that we get an error if no inputs are given. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir"); - - ExpectErrorText("Missing input file.\n"); -} - -TEST_F(CommandLineInterfaceTest, MissingOutputError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --proto_path=$tmpdir foo.proto"); - - ExpectErrorText("Missing output directives.\n"); -} - -TEST_F(CommandLineInterfaceTest, OutputWriteError) { - MockCodeGenerator* generator = - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - generator->set_expect_write_error(true); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - // Create a directory blocking our output location. - CreateTempFile("output.test.foo.proto/foo", ""); - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - -#if defined(_WIN32) && !defined(__CYGWIN__) - // Windows with MSVCRT.dll produces EPERM instead of EISDIR. - if (HasAlternateErrorSubstring("output.test.foo.proto: Permission denied")) { - return; - } -#endif - - ExpectErrorSubstring("output.test.foo.proto: Is a directory"); -} - -TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir/nosuchdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorSubstring("nosuchdir/: " - "No such file or directory"); -} - -TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out=$tmpdir/foo.proto " - "--proto_path=$tmpdir foo.proto"); - -#if defined(_WIN32) && !defined(__CYGWIN__) - // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR. - if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) { - return; - } -#endif - - ExpectErrorSubstring("foo.proto/: Not a directory"); -} - -TEST_F(CommandLineInterfaceTest, GeneratorError) { - RegisterErrorGenerator("error_generator", "Test error message.", - "--error_out", "output.test", "Test error output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --error_out=$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectErrorSubstring("--error_out: Test error message."); -} - -TEST_F(CommandLineInterfaceTest, HelpText) { - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - RegisterErrorGenerator("error_generator", "Test error message.", - "--error_out", "output.test", "Test error output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("test_exec_name --help"); - - ExpectErrorSubstring("Usage: test_exec_name "); - ExpectErrorSubstring("--test_out=OUT_DIR"); - ExpectErrorSubstring("Test output."); - ExpectErrorSubstring("--error_out=OUT_DIR"); - ExpectErrorSubstring("Test error output."); -} - -// ------------------------------------------------------------------- -// Flag parsing tests - -TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) { - // Test that a single-character flag works. - - RegisterGenerator("test_generator", "-t", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler -t$tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) { - // Test that separating the flag value with a space works. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler --test_out $tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) { - // Test that separating the flag value with a space works for - // single-character flags. - - RegisterGenerator("test_generator", "-t", - "output.test", "Test output."); - - CreateTempFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - Run("protocol_compiler -t $tmpdir " - "--proto_path=$tmpdir foo.proto"); - - ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo", "output.test"); -} - -TEST_F(CommandLineInterfaceTest, MissingValueError) { - // Test that we get an error if a flag is missing its value. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto"); - - ExpectErrorText("Missing value for flag: --test_out\n"); -} - -TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) { - // Test that we get an error if the last argument is a flag requiring a - // value. - - RegisterGenerator("test_generator", "--test_out", - "output.test", "Test output."); - - Run("protocol_compiler --test_out"); - - ExpectErrorText("Missing value for flag: --test_out\n"); -} - -// =================================================================== - -// Test for --encode and --decode. Note that it would be easier to do this -// test as a shell script, but we'd like to be able to run the test on -// platforms that don't have a Bourne-compatible shell available (especially -// Windows/MSVC). -class EncodeDecodeTest : public testing::Test { - protected: - virtual void SetUp() { - duped_stdin_ = dup(STDIN_FILENO); - } - - virtual void TearDown() { - dup2(duped_stdin_, STDIN_FILENO); - close(duped_stdin_); - } - - void RedirectStdinFromText(const string& input) { - string filename = TestTempDir() + "/test_stdin"; - File::WriteStringToFileOrDie(input, filename); - GOOGLE_CHECK(RedirectStdinFromFile(filename)); - } - - bool RedirectStdinFromFile(const string& filename) { - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) return false; - dup2(fd, STDIN_FILENO); - close(fd); - return true; - } - - // Remove '\r' characters from text. - string StripCR(const string& text) { - string result; - - for (int i = 0; i < text.size(); i++) { - if (text[i] != '\r') { - result.push_back(text[i]); - } - } - - return result; - } - - enum Type { TEXT, BINARY }; - enum ReturnCode { SUCCESS, ERROR }; - - bool Run(const string& command) { - vector<string> args; - args.push_back("protoc"); - SplitStringUsing(command, " ", &args); - args.push_back("--proto_path=" + TestSourceDir()); - - scoped_array<const char*> argv(new const char*[args.size()]); - for (int i = 0; i < args.size(); i++) { - argv[i] = args[i].c_str(); - } - - CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); - - CaptureTestStdout(); - CaptureTestStderr(); - - int result = cli.Run(args.size(), argv.get()); - - captured_stdout_ = GetCapturedTestStdout(); - captured_stderr_ = GetCapturedTestStderr(); - - return result == 0; - } - - void ExpectStdoutMatchesBinaryFile(const string& filename) { - string expected_output; - ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); - - // Don't use EXPECT_EQ because we don't want to print raw binary data to - // stdout on failure. - EXPECT_TRUE(captured_stdout_ == expected_output); - } - - void ExpectStdoutMatchesTextFile(const string& filename) { - string expected_output; - ASSERT_TRUE(File::ReadFileToString(filename, &expected_output)); - - ExpectStdoutMatchesText(expected_output); - } - - void ExpectStdoutMatchesText(const string& expected_text) { - EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_)); - } - - void ExpectStderrMatchesText(const string& expected_text) { - EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_)); - } - - private: - int duped_stdin_; - string captured_stdout_; - string captured_stderr_; -}; - -TEST_F(EncodeDecodeTest, Encode) { - RedirectStdinFromFile(TestSourceDir() + - "/google/protobuf/testdata/text_format_unittest_data.txt"); - EXPECT_TRUE(Run("google/protobuf/unittest.proto " - "--encode=protobuf_unittest.TestAllTypes")); - ExpectStdoutMatchesBinaryFile(TestSourceDir() + - "/google/protobuf/testdata/golden_message"); - ExpectStderrMatchesText(""); -} - -TEST_F(EncodeDecodeTest, Decode) { - RedirectStdinFromFile(TestSourceDir() + - "/google/protobuf/testdata/golden_message"); - EXPECT_TRUE(Run("google/protobuf/unittest.proto " - "--decode=protobuf_unittest.TestAllTypes")); - ExpectStdoutMatchesTextFile(TestSourceDir() + - "/google/protobuf/testdata/text_format_unittest_data.txt"); - ExpectStderrMatchesText(""); -} - -TEST_F(EncodeDecodeTest, Partial) { - RedirectStdinFromText(""); - EXPECT_TRUE(Run("google/protobuf/unittest.proto " - "--encode=protobuf_unittest.TestRequired")); - ExpectStdoutMatchesText(""); - ExpectStderrMatchesText( - "warning: Input message is missing required fields: a, b, c\n"); -} - -TEST_F(EncodeDecodeTest, DecodeRaw) { - protobuf_unittest::TestAllTypes message; - message.set_optional_int32(123); - message.set_optional_string("foo"); - string data; - message.SerializeToString(&data); - - RedirectStdinFromText(data); - EXPECT_TRUE(Run("--decode_raw")); - ExpectStdoutMatchesText("1: 123\n" - "14: \"foo\"\n"); - ExpectStderrMatchesText(""); -} - -TEST_F(EncodeDecodeTest, UnknownType) { - EXPECT_FALSE(Run("google/protobuf/unittest.proto " - "--encode=NoSuchType")); - ExpectStdoutMatchesText(""); - ExpectStderrMatchesText("Type not defined: NoSuchType\n"); -} - -TEST_F(EncodeDecodeTest, ProtoParseError) { - EXPECT_FALSE(Run("google/protobuf/no_such_file.proto " - "--encode=NoSuchType")); - ExpectStdoutMatchesText(""); - ExpectStderrMatchesText( - "google/protobuf/no_such_file.proto: File not found.\n"); -} - -} // anonymous namespace - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc deleted file mode 100644 index daa66c8c..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly -// what would be generated by the protocol compiler. These files are not -// generated automatically at build time because they are compiled into the -// protocol compiler itself. So, if they were auto-generated, you'd have a -// chicken-and-egg problem. -// -// If this test fails, run the script -// "generate_descriptor_proto.sh" and add -// descriptor.pb.{h,cc} to your changelist. - -#include <map> - -#include <google/protobuf/compiler/cpp/cpp_generator.h> -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/stl_util-inl.h> -#include <google/protobuf/stubs/map-util.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -#include <google/protobuf/testing/file.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -namespace { - -class MockErrorCollector : public MultiFileErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", - filename, line, column, message); - } -}; - -class MockOutputDirectory : public OutputDirectory { - public: - MockOutputDirectory() {} - ~MockOutputDirectory() { - STLDeleteValues(&files_); - } - - void ExpectFileMatches(const string& virtual_filename, - const string& physical_filename) { - string* expected_contents = FindPtrOrNull(files_, virtual_filename); - ASSERT_TRUE(expected_contents != NULL) - << "Generator failed to generate file: " << virtual_filename; - - string actual_contents; - File::ReadFileToStringOrDie( - TestSourceDir() + "/" + physical_filename, - &actual_contents); - EXPECT_TRUE(actual_contents == *expected_contents) - << physical_filename << " needs to be regenerated. Please run " - "generate_descriptor_proto.sh and add this file " - "to your CL."; - } - - // implements OutputDirectory -------------------------------------- - - virtual io::ZeroCopyOutputStream* Open(const string& filename) { - string** map_slot = &files_[filename]; - if (*map_slot != NULL) delete *map_slot; - *map_slot = new string; - - return new io::StringOutputStream(*map_slot); - } - - private: - map<string, string*> files_; -}; - -TEST(BootstrapTest, GeneratedDescriptorMatches) { - MockErrorCollector error_collector; - DiskSourceTree source_tree; - source_tree.MapPath("", TestSourceDir()); - Importer importer(&source_tree, &error_collector); - const FileDescriptor* proto_file = - importer.Import("google/protobuf/descriptor.proto"); - EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(proto_file != NULL); - - CppGenerator generator; - MockOutputDirectory output_directory; - string error; - string parameter; - parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; - ASSERT_TRUE(generator.Generate(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"); -} - -} // namespace - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc deleted file mode 100644 index f78d60d8..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ /dev/null @@ -1,196 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <set> -#include <map> - -#include <google/protobuf/compiler/cpp/cpp_enum.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, - const string& dllexport_decl) - : descriptor_(descriptor), - classname_(ClassName(descriptor, false)), - dllexport_decl_(dllexport_decl) { -} - -EnumGenerator::~EnumGenerator() {} - -void EnumGenerator::GenerateDefinition(io::Printer* printer) { - map<string, string> vars; - vars["classname"] = classname_; - vars["short_name"] = descriptor_->name(); - - printer->Print(vars, "enum $classname$ {\n"); - printer->Indent(); - - const EnumValueDescriptor* min_value = descriptor_->value(0); - const EnumValueDescriptor* max_value = descriptor_->value(0); - - for (int i = 0; i < descriptor_->value_count(); i++) { - vars["name"] = descriptor_->value(i)->name(); - vars["number"] = SimpleItoa(descriptor_->value(i)->number()); - vars["prefix"] = (descriptor_->containing_type() == NULL) ? - "" : classname_ + "_"; - - printer->Print(vars, "$prefix$$name$ = $number$,\n"); - - if (descriptor_->value(i)->number() < min_value->number()) { - min_value = descriptor_->value(i); - } - if (descriptor_->value(i)->number() > max_value->number()) { - max_value = descriptor_->value(i); - } - } - - printer->Outdent(); - printer->Print("};\n"); - - vars["min_name"] = min_value->name(); - vars["max_name"] = max_value->name(); - - if (dllexport_decl_.empty()) { - vars["dllexport"] = ""; - } else { - vars["dllexport"] = dllexport_decl_ + " "; - } - - printer->Print(vars, - "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n" - "$dllexport$bool $classname$_IsValid(int value);\n" - "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" - "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n" - "\n"); -} - -void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { - map<string, string> vars; - vars["nested_name"] = descriptor_->name(); - vars["classname"] = classname_; - printer->Print(vars, "typedef $classname$ $nested_name$;\n"); - - for (int j = 0; j < descriptor_->value_count(); j++) { - vars["tag"] = descriptor_->value(j)->name(); - printer->Print(vars, - "static const $nested_name$ $tag$ = $classname$_$tag$;\n"); - } - - printer->Print(vars, - "static inline const ::google::protobuf::EnumDescriptor*\n" - "$nested_name$_descriptor() {\n" - " return $classname$_descriptor();\n" - "}\n" - "static inline bool $nested_name$_IsValid(int value) {\n" - " return $classname$_IsValid(value);\n" - "}\n" - "static const $nested_name$ $nested_name$_MIN =\n" - " $classname$_$nested_name$_MIN;\n" - "static const $nested_name$ $nested_name$_MAX =\n" - " $classname$_$nested_name$_MAX;\n"); -} - -void EnumGenerator::GenerateDescriptorInitializer( - io::Printer* printer, int index) { - map<string, string> vars; - vars["classname"] = classname_; - vars["index"] = SimpleItoa(index); - - if (descriptor_->containing_type() == NULL) { - printer->Print(vars, - "$classname$_descriptor_ = file->enum_type($index$);\n"); - } else { - vars["parent"] = ClassName(descriptor_->containing_type(), false); - printer->Print(vars, - "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n"); - } -} - -void EnumGenerator::GenerateMethods(io::Printer* printer) { - map<string, string> vars; - vars["classname"] = classname_; - vars["builddescriptorsname"] = - GlobalBuildDescriptorsName(descriptor_->file()->name()); - - printer->Print(vars, - "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n" - " if ($classname$_descriptor_ == NULL) $builddescriptorsname$();\n" - " return $classname$_descriptor_;\n" - "}\n" - "bool $classname$_IsValid(int value) {\n" - " switch(value) {\n"); - - // Multiple values may have the same number. Make sure we only cover - // each number once by first constructing a set containing all valid - // numbers, then printing a case statement for each element. - - set<int> numbers; - for (int j = 0; j < descriptor_->value_count(); j++) { - const EnumValueDescriptor* value = descriptor_->value(j); - numbers.insert(value->number()); - } - - for (set<int>::iterator iter = numbers.begin(); - iter != numbers.end(); ++iter) { - printer->Print( - " case $number$:\n", - "number", SimpleItoa(*iter)); - } - - printer->Print(vars, - " return true;\n" - " default:\n" - " return false;\n" - " }\n" - "}\n" - "\n"); - - if (descriptor_->containing_type() != NULL) { - // We need to "define" the static constants which were declared in the - // header, to give the linker a place to put them. Or at least the C++ - // standard says we have to. MSVC actually insists tha we do _not_ define - // them again in the .cc file. - printer->Print("#ifndef _MSC_VER\n"); - - vars["parent"] = ClassName(descriptor_->containing_type(), false); - vars["nested_name"] = descriptor_->name(); - for (int i = 0; i < descriptor_->value_count(); i++) { - vars["value"] = descriptor_->value(i)->name(); - printer->Print(vars, - "const $classname$ $parent$::$value$;\n"); - } - printer->Print(vars, - "const $classname$ $parent$::$nested_name$_MIN;\n" - "const $classname$ $parent$::$nested_name$_MAX;\n"); - - printer->Print("#endif // _MSC_VER\n"); - } -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h deleted file mode 100644 index b30997c9..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_enum.h +++ /dev/null @@ -1,81 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ - -#include <string> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -class EnumGenerator { - public: - // See generator.cc for the meaning of dllexport_decl. - explicit EnumGenerator(const EnumDescriptor* descriptor, - const string& dllexport_decl); - ~EnumGenerator(); - - // Header stuff. - - // Generate header code defining the enum. This code should be placed - // within the enum's package namespace, but NOT within any class, even for - // nested enums. - void GenerateDefinition(io::Printer* printer); - - // For enums nested within a message, generate code to import all the enum's - // symbols (e.g. the enum type name, all its values, etc.) into the class's - // namespace. This should be placed inside the class definition in the - // header. - void GenerateSymbolImports(io::Printer* printer); - - // Source file stuff. - - // Generate code that initializes the global variable storing the enum's - // descriptor. - void GenerateDescriptorInitializer(io::Printer* printer, int index); - - // Generate non-inline methods related to the enum, such as IsValidValue(). - // Goes in the .cc file. - void GenerateMethods(io::Printer* printer); - - private: - const EnumDescriptor* descriptor_; - string classname_; - string dllexport_decl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc deleted file mode 100644 index e02d7d8a..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ /dev/null @@ -1,226 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_enum_field.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format_inl.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -using internal::WireFormat; - -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, - map<string, string>* variables) { - const EnumValueDescriptor* default_value = descriptor->default_value_enum(); - - (*variables)["name"] = FieldName(descriptor); - (*variables)["type"] = ClassName(descriptor->enum_type(), true); - (*variables)["default"] = SimpleItoa(default_value->number()); - (*variables)["index"] = SimpleItoa(descriptor->index()); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["classname"] = ClassName(FieldScope(descriptor), false); - (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); -} - -} // namespace - -// =================================================================== - -EnumFieldGenerator:: -EnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -EnumFieldGenerator::~EnumFieldGenerator() {} - -void EnumFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "int $name$_;\n"); -} - -void EnumFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $name$() const;\n" - "inline void set_$name$($type$ value);\n"); -} - -void EnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" - " return static_cast< $type$ >($name$_);\n" - "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" - " GOOGLE_DCHECK($type$_IsValid(value));\n" - " _set_bit($index$);\n" - " $name$_ = value;\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $default$;\n"); -} - -void EnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "set_$name$(from.$name$());\n"); -} - -void EnumFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - printer->Print(variables_, ",\n$name$_($default$)"); -} - -void EnumFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "int value;\n" - "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n" - "if ($type$_IsValid(value)) {\n" - " set_$name$(static_cast< $type$ >(value));\n" - "} else {\n" - " mutable_unknown_fields()->AddField($number$)->add_varint(value);\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::WriteEnum(" - "$number$, this->$name$(), output));\n"); -} - -void EnumFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormat::EnumSize(this->$name$());\n"); -} - -// =================================================================== - -RepeatedEnumFieldGenerator:: -RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} - -void RepeatedEnumFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "::google::protobuf::RepeatedField<int> $name$_;\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>& $name$() const;\n" - "inline ::google::protobuf::RepeatedField<int>* mutable_$name$();\n" - "inline $type$ $name$(int index) const;\n" - "inline void set_$name$(int index, $type$ value);\n" - "inline void add_$name$($type$ value);\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedField<int>*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" - "inline $type$ $classname$::$name$(int index) const {\n" - " return static_cast< $type$ >($name$_.Get(index));\n" - "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n" - " GOOGLE_DCHECK($type$_IsValid(value));\n" - " $name$_.Set(index, value);\n" - "}\n" - "inline void $classname$::add_$name$($type$ value) {\n" - " GOOGLE_DCHECK($type$_IsValid(value));\n" - " $name$_.Add(value);\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Clear();\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedEnumFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "int value;\n" - "DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value));\n" - "if ($type$_IsValid(value)) {\n" - " add_$name$(static_cast< $type$ >(value));\n" - "} else {\n" - " mutable_unknown_fields()->AddField($number$)->add_varint(value);\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::WriteEnum(" - "$number$, this->$name$(i), output));\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ * $name$_size();\n" - "for (int i = 0; i < $name$_size(); i++) {\n" - " total_size += ::google::protobuf::internal::WireFormat::EnumSize(\n" - " this->$name$(i));\n" - "}\n"); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h deleted file mode 100644 index a297e961..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -class EnumFieldGenerator : public FieldGenerator { - public: - explicit EnumFieldGenerator(const FieldDescriptor* descriptor); - ~EnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); -}; - -class RepeatedEnumFieldGenerator : public FieldGenerator { - public: - explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedEnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc deleted file mode 100644 index 87da63d7..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ /dev/null @@ -1,104 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_extension.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, - const string& dllexport_decl) - : descriptor_(descriptor), - dllexport_decl_(dllexport_decl) { - // Construct type_traits_. - if (descriptor_->is_repeated()) { - type_traits_ = "Repeated"; - } - - switch (descriptor_->cpp_type()) { - case FieldDescriptor::CPPTYPE_ENUM: - type_traits_.append("EnumTypeTraits< "); - type_traits_.append(ClassName(descriptor_->enum_type(), true)); - type_traits_.append(" >"); - break; - case FieldDescriptor::CPPTYPE_STRING: - type_traits_.append("StringTypeTraits"); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - type_traits_.append("MessageTypeTraits< "); - type_traits_.append(ClassName(descriptor_->message_type(), true)); - type_traits_.append(" >"); - break; - default: - type_traits_.append("PrimitiveTypeTraits< "); - type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type())); - type_traits_.append(" >"); - break; - } -} - -ExtensionGenerator::~ExtensionGenerator() {} - -void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) { - map<string, string> vars; - vars["extendee" ] = ClassName(descriptor_->containing_type(), true); - vars["type_traits"] = type_traits_; - vars["name" ] = descriptor_->name(); - - // If this is a class member, it needs to be declared "static". Otherwise, - // it needs to be "extern". - vars["qualifier"] = - (descriptor_->extension_scope() == NULL) ? "extern" : "static"; - - if (!dllexport_decl_.empty()) { - vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"]; - } - - printer->Print(vars, - "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n" - " ::google::protobuf::internal::$type_traits$ > $name$;\n"); -} - -void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { - map<string, string> vars; - vars["extendee" ] = ClassName(descriptor_->containing_type(), true); - vars["number" ] = SimpleItoa(descriptor_->number()); - vars["type_traits"] = type_traits_; - vars["name" ] = descriptor_->name(); - - // If this is a class member, it needs to be declared in its class scope. - vars["scope"] = (descriptor_->extension_scope() == NULL) ? "" : - ClassName(descriptor_->extension_scope(), false) + "::"; - - printer->Print(vars, - "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n" - " ::google::protobuf::internal::$type_traits$ > $scope$$name$($number$);\n"); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h deleted file mode 100644 index 149dbca9..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_extension.h +++ /dev/null @@ -1,68 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - class FieldDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -// Generates code for an extension, which may be within the scope of some -// message or may be at file scope. This is much simpler than FieldGenerator -// since extensions are just simple identifiers with interesting types. -class ExtensionGenerator { - public: - // See generator.cc for the meaning of dllexport_decl. - explicit ExtensionGenerator(const FieldDescriptor* descriptor, - const string& dllexport_decl); - ~ExtensionGenerator(); - - // Header stuff. - void GenerateDeclaration(io::Printer* printer); - - // Source file stuff. - void GenerateDefinition(io::Printer* printer); - - private: - const FieldDescriptor* descriptor_; - string type_traits_; - string dllexport_decl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc deleted file mode 100644 index 2b1041be..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_field.h> -#include <google/protobuf/compiler/cpp/cpp_primitive_field.h> -#include <google/protobuf/compiler/cpp/cpp_string_field.h> -#include <google/protobuf/compiler/cpp/cpp_enum_field.h> -#include <google/protobuf/compiler/cpp/cpp_message_field.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -FieldGenerator::~FieldGenerator() {} - -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) - : descriptor_(descriptor), - field_generators_( - new scoped_ptr<FieldGenerator>[descriptor->field_count()]) { - // Construct all the FieldGenerators. - for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i))); - } -} - -FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { - if (field->is_repeated()) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_MESSAGE: - return new RepeatedMessageFieldGenerator(field); - case FieldDescriptor::CPPTYPE_STRING: - return new RepeatedStringFieldGenerator(field); - case FieldDescriptor::CPPTYPE_ENUM: - return new RepeatedEnumFieldGenerator(field); - default: - return new RepeatedPrimitiveFieldGenerator(field); - } - } else { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_MESSAGE: - return new MessageFieldGenerator(field); - case FieldDescriptor::CPPTYPE_STRING: - return new StringFieldGenerator(field); - case FieldDescriptor::CPPTYPE_ENUM: - return new EnumFieldGenerator(field); - default: - return new PrimitiveFieldGenerator(field); - } - } -} - -FieldGeneratorMap::~FieldGeneratorMap() {} - -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); - return *field_generators_[field->index()]; -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h deleted file mode 100644 index d37eb962..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ /dev/null @@ -1,127 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -class FieldGenerator { - public: - FieldGenerator() {} - virtual ~FieldGenerator(); - - // Generate lines of code declaring members fields of the message class - // needed to represent this field. These are placed inside the message - // class. - virtual void GeneratePrivateMembers(io::Printer* printer) const = 0; - - // Generate prototypes for all of the accessor functions related to this - // field. These are placed inside the class definition. - virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0; - - // Generate inline definitions of accessor functions for this field. - // These are placed inside the header after all class definitions. - virtual void GenerateInlineAccessorDefinitions( - io::Printer* printer) const = 0; - - // Generate definitions of accessors that aren't inlined. These are - // placed somewhere in the .cc file. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateNonInlineAccessorDefinitions( - io::Printer* printer) const {} - - // Generate lines of code (statements, not declarations) which clear the - // field. This is used to define the clear_$name$() method as well as - // the Clear() method for the whole message. - virtual void GenerateClearingCode(io::Printer* printer) const = 0; - - // Generate lines of code (statements, not declarations) which merges the - // contents of the field from the current message to the target message, - // which is stored in the generated code variable "from". - // This is used to fill in the MergeFrom method for the whole message. - // Details of this usage can be found in message.cc under the - // GenerateMergeFrom method. - virtual void GenerateMergingCode(io::Printer* printer) const = 0; - - // Generate any initializers needed for the private members declared by - // GeneratePrivateMembers(). These go into the message class's - // constructor's initializer list. For each initializer, this method - // must print the comma and newline separating it from the *previous* - // initializer, not the *next* initailizer. That is, print a ",\n" first, - // e.g.: - // printer->Print(",\n$name$_($default$)"); - virtual void GenerateInitializer(io::Printer* printer) const = 0; - - // Generate any code that needs to go in the class's destructor. - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateDestructorCode(io::Printer* printer) const {} - - // Generate lines to decode this field, which will be placed inside the - // message's MergeFromCodedStream() method. - virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0; - - // Generate lines to serialize this field, which are placed within the - // message's SerializeWithCachedSizes() method. - virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0; - - // Generate lines to compute the serialized size of this field, which - // are placed in the message's ByteSize() method. - virtual void GenerateByteSize(io::Printer* printer) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); -}; - -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { - public: - explicit FieldGeneratorMap(const Descriptor* descriptor); - ~FieldGeneratorMap(); - - const FieldGenerator& get(const FieldDescriptor* field) const; - - private: - const Descriptor* descriptor_; - scoped_array<scoped_ptr<FieldGenerator> > field_generators_; - - static FieldGenerator* MakeGenerator(const FieldDescriptor* field); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc deleted file mode 100644 index f88d63fc..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ /dev/null @@ -1,414 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_file.h> -#include <google/protobuf/compiler/cpp/cpp_enum.h> -#include <google/protobuf/compiler/cpp/cpp_service.h> -#include <google/protobuf/compiler/cpp/cpp_extension.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/compiler/cpp/cpp_message.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -// =================================================================== - -FileGenerator::FileGenerator(const FileDescriptor* file, - const string& dllexport_decl) - : file_(file), - message_generators_( - new scoped_ptr<MessageGenerator>[file->message_type_count()]), - enum_generators_( - new scoped_ptr<EnumGenerator>[file->enum_type_count()]), - service_generators_( - new scoped_ptr<ServiceGenerator>[file->service_count()]), - extension_generators_( - new scoped_ptr<ExtensionGenerator>[file->extension_count()]) { - - for (int i = 0; i < file->message_type_count(); i++) { - message_generators_[i].reset( - new MessageGenerator(file->message_type(i), dllexport_decl)); - } - - for (int i = 0; i < file->enum_type_count(); i++) { - enum_generators_[i].reset( - new EnumGenerator(file->enum_type(i), dllexport_decl)); - } - - for (int i = 0; i < file->service_count(); i++) { - service_generators_[i].reset( - new ServiceGenerator(file->service(i), dllexport_decl)); - } - - for (int i = 0; i < file->extension_count(); i++) { - extension_generators_[i].reset( - new ExtensionGenerator(file->extension(i), dllexport_decl)); - } - - SplitStringUsing(file_->package(), ".", &package_parts_); -} - -FileGenerator::~FileGenerator() {} - -void FileGenerator::GenerateHeader(io::Printer* printer) { - string filename_identifier = FilenameIdentifier(file_->name()); - - // Generate top of header. - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n" - "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" - "#define PROTOBUF_$filename_identifier$__INCLUDED\n" - "\n" - "#include <string>\n" - "\n", - "filename_identifier", filename_identifier); - - printer->Print( - "#include <google/protobuf/stubs/common.h>\n" - "\n"); - - // Verify the protobuf library header version is compatible with the protoc - // version before going any further. - printer->Print( - "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n" - "#error This file was generated by a newer version of protoc which is\n" - "#error incompatible with your Protocol Buffer headers. Please update\n" - "#error your headers.\n" - "#endif\n" - "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n" - "#error This file was generated by an older version of protoc which is\n" - "#error incompatible with your Protocol Buffer headers. Please\n" - "#error regenerate this file with a newer version of protoc.\n" - "#endif\n" - "\n", - "min_header_version", - SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), - "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); - - // OK, it's now safe to #include other files. - printer->Print( - "#include <google/protobuf/generated_message_reflection.h>\n" - "#include <google/protobuf/repeated_field.h>\n" - "#include <google/protobuf/extension_set.h>\n"); - - if (file_->service_count() > 0) { - printer->Print( - "#include <google/protobuf/service.h>\n"); - } - - for (int i = 0; i < file_->dependency_count(); i++) { - printer->Print( - "#include \"$dependency$.pb.h\"\n", - "dependency", StripProto(file_->dependency(i)->name())); - } - - // Open namespace. - GenerateNamespaceOpeners(printer); - - // Forward-declare the BuildDescriptors function, so that we can declare it - // to be a friend of each class. - printer->Print( - "\n" - "// Internal implementation detail -- do not call this.\n" - "void $builddescriptorsname$();\n" - "\n", - "builddescriptorsname", GlobalBuildDescriptorsName(file_->name())); - - // Generate forward declarations of classes. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateForwardDeclaration(printer); - } - - printer->Print("\n"); - - // Generate enum definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateEnumDefinitions(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDefinition(printer); - } - - printer->Print(kThickSeparator); - printer->Print("\n"); - - // Generate class definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - if (i > 0) { - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - message_generators_[i]->GenerateClassDefinition(printer); - } - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - - // Generate service definitions. - for (int i = 0; i < file_->service_count(); i++) { - if (i > 0) { - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - service_generators_[i]->GenerateDeclarations(printer); - } - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - - // Declare extension identifiers. - for (int i = 0; i < file_->extension_count(); i++) { - extension_generators_[i]->GenerateDeclaration(printer); - } - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - - // Generate class inline methods. - for (int i = 0; i < file_->message_type_count(); i++) { - if (i > 0) { - printer->Print(kThinSeparator); - printer->Print("\n"); - } - message_generators_[i]->GenerateInlineMethods(printer); - } - - // Close up namespace. - GenerateNamespaceClosers(printer); - - printer->Print( - "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", - "filename_identifier", filename_identifier); -} - -void FileGenerator::GenerateSource(io::Printer* printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n" - "#include \"$basename$.pb.h\"\n" - "#include <google/protobuf/descriptor.h>\n" - "#include <google/protobuf/io/coded_stream.h>\n" - "#include <google/protobuf/reflection_ops.h>\n" - "#include <google/protobuf/wire_format_inl.h>\n", - "basename", StripProto(file_->name())); - - // For each dependency, write a prototype for that dependency's - // BuildDescriptors() function. We don't expose these in the header because - // they are internal implementation details, and since this is generated code - // we don't have the usual risks involved with declaring external functions - // within a .cc file. - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor* dependency = file_->dependency(i); - // Open the dependency's namespace. - vector<string> dependency_package_parts; - SplitStringUsing(dependency->package(), ".", &dependency_package_parts); - for (int i = 0; i < dependency_package_parts.size(); i++) { - printer->Print("namespace $name$ { ", - "name", dependency_package_parts[i]); - } - // Declare its BuildDescriptors() function. - printer->Print( - "void $function$();", - "function", GlobalBuildDescriptorsName(dependency->name())); - // Close the namespace. - for (int i = 0; i < dependency_package_parts.size(); i++) { - printer->Print(" }"); - } - printer->Print("\n"); - } - - GenerateNamespaceOpeners(printer); - - printer->Print( - "\n" - "namespace {\n" - "\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateDescriptorDeclarations(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - printer->Print( - "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", - "name", ClassName(file_->enum_type(i), false)); - } - for (int i = 0; i < file_->service_count(); i++) { - printer->Print( - "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", - "name", file_->service(i)->name()); - } - - printer->Print( - "\n" - "} // namespace\n" - "\n"); - - // Define our externally-visible BuildDescriptors() function. - GenerateBuildDescriptors(printer); - - // Generate enums. - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateMethods(printer); - } - - // Generate classes. - for (int i = 0; i < file_->message_type_count(); i++) { - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - message_generators_[i]->GenerateClassMethods(printer); - } - - // Generate services. - for (int i = 0; i < file_->service_count(); i++) { - if (i == 0) printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - service_generators_[i]->GenerateImplementation(printer); - } - - // Define extensions. - for (int i = 0; i < file_->extension_count(); i++) { - extension_generators_[i]->GenerateDefinition(printer); - } - - GenerateNamespaceClosers(printer); -} - -void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { - // BuildDescriptors() is a file-level procedure which initializes all of - // the Descriptor objects for this file. It runs the first time one of the - // descriptors is accessed. This will always be at static initialization - // time, because every message has a statically-initialized default instance, - // and the constructor for a message class accesses its descriptor. See the - // constructor and the descriptor() method of message classes. - // - // We also construct the reflection object for each class inside - // BuildDescriptors(). - printer->Print( - "\n" - "void $builddescriptorsname$() {\n" - " static bool already_here = false;\n" - " if (already_here) return;\n" - " already_here = true;\n" - " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" - " ::google::protobuf::DescriptorPool* pool =\n" - " ::google::protobuf::DescriptorPool::internal_generated_pool();\n" - "\n", - "builddescriptorsname", GlobalBuildDescriptorsName(file_->name())); - printer->Indent(); - - // Call the BuildDescriptors() methods for all of our dependencies, to make - // sure they get initialized first. - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor* dependency = file_->dependency(i); - // Print the namespace prefix for the dependency. - vector<string> dependency_package_parts; - SplitStringUsing(dependency->package(), ".", &dependency_package_parts); - printer->Print("::"); - for (int i = 0; i < dependency_package_parts.size(); i++) { - printer->Print("$name$::", - "name", dependency_package_parts[i]); - } - // Call its BuildDescriptors function. - printer->Print( - "$name$();\n", - "name", GlobalBuildDescriptorsName(dependency->name())); - } - - // Embed the descriptor. We simply serialize the entire FileDescriptorProto - // and embed it as a string literal, which is parsed and built into real - // descriptors at initialization time. - FileDescriptorProto file_proto; - file_->CopyTo(&file_proto); - string file_data; - file_proto.SerializeToString(&file_data); - - printer->Print( - "const ::google::protobuf::FileDescriptor* file = pool->InternalBuildGeneratedFile("); - - // Only write 40 bytes per line. - static const int kBytesPerLine = 40; - for (int i = 0; i < file_data.size(); i += kBytesPerLine) { - printer->Print("\n \"$data$\"", - "data", CEscape(file_data.substr(i, kBytesPerLine))); - } - printer->Print( - ", $size$);\n", - "size", SimpleItoa(file_data.size())); - - // Assign all global descriptors. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - for (int i = 0; i < file_->service_count(); i++) { - service_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - - printer->Outdent(); - printer->Print( - "}\n" - "\n" - "// Force BuildDescriptors() to be called at static initialization time.\n" - "struct StaticDescriptorInitializer_$filename$ {\n" - " StaticDescriptorInitializer_$filename$() {\n" - " $builddescriptorsname$();\n" - " }\n" - "} static_descriptor_initializer_$filename$_;\n" - "\n", - "builddescriptorsname", GlobalBuildDescriptorsName(file_->name()), - "filename", FilenameIdentifier(file_->name())); -} - -void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { - if (package_parts_.size() > 0) printer->Print("\n"); - - for (int i = 0; i < package_parts_.size(); i++) { - printer->Print("namespace $part$ {\n", - "part", package_parts_[i]); - } -} - -void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { - if (package_parts_.size() > 0) printer->Print("\n"); - - for (int i = package_parts_.size() - 1; i >= 0; i--) { - printer->Print("} // namespace $part$\n", - "part", package_parts_[i]); - } -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h deleted file mode 100644 index f2255ee1..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ /dev/null @@ -1,82 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ - -#include <string> -#include <vector> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { - class FileDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -class EnumGenerator; // enum.h -class MessageGenerator; // message.h -class ServiceGenerator; // service.h -class ExtensionGenerator; // extension.h - -class FileGenerator { - public: - // See generator.cc for the meaning of dllexport_decl. - explicit FileGenerator(const FileDescriptor* file, - const string& dllexport_decl); - ~FileGenerator(); - - void GenerateHeader(io::Printer* printer); - void GenerateSource(io::Printer* printer); - - private: - // Generate the BuildDescriptors() procedure, which builds all descriptors - // for types defined in the file. - void GenerateBuildDescriptors(io::Printer* printer); - - void GenerateNamespaceOpeners(io::Printer* printer); - void GenerateNamespaceClosers(io::Printer* printer); - - const FileDescriptor* file_; - - scoped_array<scoped_ptr<MessageGenerator> > message_generators_; - scoped_array<scoped_ptr<EnumGenerator> > enum_generators_; - scoped_array<scoped_ptr<ServiceGenerator> > service_generators_; - scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_; - - // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}. - vector<string> package_parts_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc deleted file mode 100644 index 200f6358..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ /dev/null @@ -1,135 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_generator.h> - -#include <vector> -#include <utility> - -#include <google/protobuf/compiler/cpp/cpp_file.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -namespace { - -// Parses a set of comma-delimited name/value pairs, e.g.: -// "foo=bar,baz,qux=corge" -// parses to the pairs: -// ("foo", "bar"), ("baz", ""), ("qux", "corge") -void ParseOptions(const string& text, vector<pair<string, string> >* output) { - vector<string> parts; - SplitStringUsing(text, ",", &parts); - - for (int i = 0; i < parts.size(); i++) { - string::size_type equals_pos = parts[i].find_first_of('='); - pair<string, string> value; - if (equals_pos == string::npos) { - value.first = parts[i]; - value.second = ""; - } else { - value.first = parts[i].substr(0, equals_pos); - value.second = parts[i].substr(equals_pos + 1); - } - output->push_back(value); - } -} - -} // namespace - -CppGenerator::CppGenerator() {} -CppGenerator::~CppGenerator() {} - -bool CppGenerator::Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - vector<pair<string, string> > options; - ParseOptions(parameter, &options); - - // ----------------------------------------------------------------- - // parse generator options - - // TODO(kenton): If we ever have more options, we may want to create a - // class that encapsulates them which we can pass down to all the - // generator classes. Currently we pass dllexport_decl down to all of - // them via the constructors, but we don't want to have to add another - // constructor parameter for every option. - - // If the dllexport_decl option is passed to the compiler, we need to write - // it in front of every symbol that should be exported if this .proto is - // compiled into a Windows DLL. E.g., if the user invokes the protocol - // compiler as: - // protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto - // then we'll define classes like this: - // class FOO_EXPORT Foo { - // ... - // } - // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or - // __declspec(dllimport) depending on what is being compiled. - string dllexport_decl; - - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "dllexport_decl") { - dllexport_decl = options[i].second; - } else { - *error = "Unknown generator option: " + options[i].first; - return false; - } - } - - // ----------------------------------------------------------------- - - - string basename = StripProto(file->name()); - basename.append(".pb"); - - FileGenerator file_generator(file, dllexport_decl); - - // Generate header. - { - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(basename + ".h")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateHeader(&printer); - } - - // Generate cc file. - { - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(basename + ".cc")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateSource(&printer); - } - - return true; -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h deleted file mode 100644 index 26fb8e97..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_generator.h +++ /dev/null @@ -1,58 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Generates C++ code for a given .proto file. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ - -#include <string> -#include <google/protobuf/compiler/code_generator.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -// CodeGenerator implementation which generates a C++ source file and -// header. If you create your own protocol compiler binary and you want -// it to support C++ output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator { - public: - CppGenerator(); - ~CppGenerator(); - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc deleted file mode 100644 index 6a49f815..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ /dev/null @@ -1,197 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> -#include <google/protobuf/stubs/hash.h> - -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -namespace { - -string DotsToUnderscores(const string& name) { - return StringReplace(name, ".", "_", true); -} - -string DotsToColons(const string& name) { - return StringReplace(name, ".", "::", true); -} - -const char* const kKeywordList[] = { - "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case", - "catch", "char", "class", "compl", "const", "const_cast", "continue", - "default", "delete", "do", "double", "dynamic_cast", "else", "enum", - "explicit", "extern", "false", "float", "for", "friend", "goto", "if", - "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", - "operator", "or", "or_eq", "private", "protected", "public", "register", - "reinterpret_cast", "return", "short", "signed", "sizeof", "static", - "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", - "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", - "void", "volatile", "wchar_t", "while", "xor", "xor_eq" -}; - -hash_set<string> MakeKeywordsMap() { - hash_set<string> result; - for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) { - result.insert(kKeywordList[i]); - } - return result; -} - -hash_set<string> kKeywords = MakeKeywordsMap(); - -} // namespace - -const char kThickSeparator[] = - "// ===================================================================\n"; -const char kThinSeparator[] = - "// -------------------------------------------------------------------\n"; - -string ClassName(const Descriptor* descriptor, bool qualified) { - // Find "outer", the descriptor of the top-level message in which - // "descriptor" is embedded. - const Descriptor* outer = descriptor; - while (outer->containing_type() != NULL) outer = outer->containing_type(); - - const string& outer_name = outer->full_name(); - string inner_name = descriptor->full_name().substr(outer_name.size()); - - if (qualified) { - return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name); - } else { - return outer->name() + DotsToUnderscores(inner_name); - } -} - -string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { - if (enum_descriptor->containing_type() == NULL) { - if (qualified) { - return DotsToColons(enum_descriptor->full_name()); - } else { - return enum_descriptor->name(); - } - } else { - string result = ClassName(enum_descriptor->containing_type(), qualified); - result += '_'; - result += enum_descriptor->name(); - return result; - } -} - -string FieldName(const FieldDescriptor* field) { - string result = field->name(); - LowerString(&result); - if (kKeywords.count(result) > 0) { - result.append("_"); - } - return result; -} - -string StripProto(const string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - -const char* PrimitiveTypeName(FieldDescriptor::CppType type) { - switch (type) { - case FieldDescriptor::CPPTYPE_INT32 : return "::google::protobuf::int32"; - case FieldDescriptor::CPPTYPE_INT64 : return "::google::protobuf::int64"; - case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32"; - case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64"; - case FieldDescriptor::CPPTYPE_DOUBLE : return "double"; - case FieldDescriptor::CPPTYPE_FLOAT : return "float"; - case FieldDescriptor::CPPTYPE_BOOL : return "bool"; - case FieldDescriptor::CPPTYPE_ENUM : return "int"; - case FieldDescriptor::CPPTYPE_STRING : return "::std::string"; - case FieldDescriptor::CPPTYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // CppTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -const char* DeclaredTypeMethodName(FieldDescriptor::Type type) { - switch (type) { - case FieldDescriptor::TYPE_INT32 : return "Int32"; - case FieldDescriptor::TYPE_INT64 : return "Int64"; - case FieldDescriptor::TYPE_UINT32 : return "UInt32"; - case FieldDescriptor::TYPE_UINT64 : return "UInt64"; - case FieldDescriptor::TYPE_SINT32 : return "SInt32"; - case FieldDescriptor::TYPE_SINT64 : return "SInt64"; - case FieldDescriptor::TYPE_FIXED32 : return "Fixed32"; - case FieldDescriptor::TYPE_FIXED64 : return "Fixed64"; - case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; - case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; - case FieldDescriptor::TYPE_FLOAT : return "Float"; - case FieldDescriptor::TYPE_DOUBLE : return "Double"; - - case FieldDescriptor::TYPE_BOOL : return "Bool"; - case FieldDescriptor::TYPE_ENUM : return "Enum"; - - case FieldDescriptor::TYPE_STRING : return "String"; - case FieldDescriptor::TYPE_BYTES : return "Bytes"; - case FieldDescriptor::TYPE_GROUP : return "Group"; - case FieldDescriptor::TYPE_MESSAGE : return "Message"; - - // No default because we want the compiler to complain if any new - // types are added. - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; -} - -// Convert a file name into a valid identifier. -string FilenameIdentifier(const string& filename) { - string result; - for (int i = 0; i < filename.size(); i++) { - if (ascii_isalnum(filename[i])) { - result.push_back(filename[i]); - } else { - // Not alphanumeric. To avoid any possibility of name conflicts we - // use the hex code for the character. - result.push_back('_'); - char buffer[kFastToBufferSize]; - result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer)); - } - } - return result; -} - -// Return the name of the BuildDescriptors() function for a given file. -string GlobalBuildDescriptorsName(const string& filename) { - return "protobuf_BuildDesc_" + FilenameIdentifier(filename); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h deleted file mode 100644 index 7f57d694..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ /dev/null @@ -1,86 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ - -#include <string> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -// Commonly-used separator comments. Thick is a line of '=', thin is a line -// of '-'. -extern const char kThickSeparator[]; -extern const char kThinSeparator[]; - -// Returns the non-nested type name for the given type. If "qualified" is -// true, prefix the type with the full namespace. For example, if you had: -// package foo.bar; -// message Baz { message Qux {} } -// Then the qualified ClassName for Qux would be: -// ::foo::bar::Baz_Qux -// While the non-qualified version would be: -// Baz_Qux -string ClassName(const Descriptor* descriptor, bool qualified); -string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); - -// Get the (unqualified) name that should be used for this field in C++ code. -// The name is coerced to lower-case to emulate proto1 behavior. People -// should be using lowercase-with-underscores style for proto field names -// anyway, so normally this just returns field->name(). -string FieldName(const FieldDescriptor* field); - -// Returns the scope where the field was defined (for extensions, this is -// different from the message type to which the field applies). -inline const Descriptor* FieldScope(const FieldDescriptor* field) { - return field->is_extension() ? - field->extension_scope() : field->containing_type(); -} - -// Strips ".proto" or ".protodevel" from the end of a filename. -string StripProto(const string& filename); - -// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). -// Note: non-built-in type names will be qualified, meaning they will start -// with a ::. If you are using the type as a template parameter, you will -// need to insure there is a space between the < and the ::, because the -// ridiculous C++ standard defines "<:" to be a synonym for "[". -const char* PrimitiveTypeName(FieldDescriptor::CppType type); - -// Get the declared type name in CamelCase format, as is used e.g. for the -// methods of WireFormat. For example, TYPE_INT32 becomes "Int32". -const char* DeclaredTypeMethodName(FieldDescriptor::Type type); - -// Convert a file name into a valid identifier. -string FilenameIdentifier(const string& filename); - -// Return the name of the BuildDescriptors() function for a given file. -string GlobalBuildDescriptorsName(const string& filename); - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc deleted file mode 100644 index afd99314..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ /dev/null @@ -1,1466 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/cpp/cpp_message.h> -#include <google/protobuf/compiler/cpp/cpp_enum.h> -#include <google/protobuf/compiler/cpp/cpp_extension.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -using internal::WireFormat; - -namespace { - -void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { - // Print the field's proto-syntax definition as a comment. We don't want to - // print group bodies so we cut off after the first line. - string def = field->DebugString(); - printer->Print("// $def$\n", - "def", def.substr(0, def.find_first_of('\n'))); -} - -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -const char* kWireTypeNames[] = { - "VARINT", - "FIXED64", - "LENGTH_DELIMITED", - "START_GROUP", - "END_GROUP", - "FIXED32", -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor*[descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); - return fields; -} - -// Functor for sorting extension ranges by their "start" field number. -struct ExtensionRangeSorter { - bool operator()(const Descriptor::ExtensionRange* left, - const Descriptor::ExtensionRange* right) const { - return left->start < right->start; - } -}; - -// Returns true if the message type has any required fields. If it doesn't, -// we can optimize out calls to its IsInitialized() method. -// -// already_seen is used to avoid checking the same type multiple times -// (and also to protect against recursion). -static bool HasRequiredFields( - const Descriptor* type, - hash_set<const Descriptor*>* already_seen) { - if (already_seen->count(type) > 0) { - // Since the first occurrence of a required field causes the whole - // function to return true, we can assume that if the type is already - // in the cache it didn't have any required fields. - return false; - } - already_seen->insert(type); - - // If the type has extensions, an extension with message type could contain - // required fields, so we have to be conservative and assume such an - // extension exists. - if (type->extension_range_count() > 0) return true; - - for (int i = 0; i < type->field_count(); i++) { - const FieldDescriptor* field = type->field(i); - if (field->is_required()) { - return true; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (HasRequiredFields(field->message_type(), already_seen)) { - return true; - } - } - } - - return false; -} - -static bool HasRequiredFields(const Descriptor* type) { - hash_set<const Descriptor*> already_seen; - return HasRequiredFields(type, &already_seen); -} - -} - -// =================================================================== - -MessageGenerator::MessageGenerator(const Descriptor* descriptor, - const string& dllexport_decl) - : descriptor_(descriptor), - classname_(ClassName(descriptor, false)), - dllexport_decl_(dllexport_decl), - field_generators_(descriptor), - nested_generators_(new scoped_ptr<MessageGenerator>[ - descriptor->nested_type_count()]), - enum_generators_(new scoped_ptr<EnumGenerator>[ - descriptor->enum_type_count()]), - extension_generators_(new scoped_ptr<ExtensionGenerator>[ - descriptor->extension_count()]) { - - for (int i = 0; i < descriptor->nested_type_count(); i++) { - nested_generators_[i].reset( - new MessageGenerator(descriptor->nested_type(i), dllexport_decl)); - } - - for (int i = 0; i < descriptor->enum_type_count(); i++) { - enum_generators_[i].reset( - new EnumGenerator(descriptor->enum_type(i), dllexport_decl)); - } - - for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset( - new ExtensionGenerator(descriptor->extension(i), dllexport_decl)); - } -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator:: -GenerateForwardDeclaration(io::Printer* printer) { - printer->Print("class $classname$;\n", - "classname", classname_); - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateForwardDeclaration(printer); - } -} - -void MessageGenerator:: -GenerateEnumDefinitions(io::Printer* printer) { - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateEnumDefinitions(printer); - } - - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDefinition(printer); - } -} - -void MessageGenerator:: -GenerateFieldAccessorDeclarations(io::Printer* printer) { - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - PrintFieldComment(printer, field); - - map<string, string> vars; - vars["name"] = FieldName(field); - - if (field->is_repeated()) { - printer->Print(vars, "inline int $name$_size() const;\n"); - } else { - printer->Print(vars, "inline bool has_$name$() const;\n"); - } - - printer->Print(vars, "inline void clear_$name$();\n"); - - // Generate type-specific accessor declarations. - field_generators_.get(field).GenerateAccessorDeclarations(printer); - - printer->Print("\n"); - } - - if (descriptor_->extension_range_count() > 0) { - // Generate accessors for extensions. - - // Normally I'd generate prototypes here and generate the actual - // definitions of these methods in GenerateFieldAccessorDefinitions, but - // the prototypes for these silly methods are so absurdly complicated that - // it meant way too much repitition. - // - // We use "_proto_TypeTraits" as a type name below because "TypeTraits" - // causes problems if the class has a nested message or enum type with that - // name and "_TypeTraits" is technically reserved for the C++ library since - // it starts with an underscore followed by a capital letter. - printer->Print( - // Has, Size, Clear - "template <typename _proto_TypeTraits>\n" - "inline bool HasExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) const {\n" - " return _extensions_.Has(id.number());\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline void ClearExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) {\n" - " _extensions_.ClearExtension(id.number());\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline int ExtensionSize(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) const {\n" - " return _extensions_.ExtensionSize(id.number());\n" - "}\n" - "\n" - - // Singular accessors - "template <typename _proto_TypeTraits>\n" - "inline typename _proto_TypeTraits::ConstType GetExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) const {\n" - " return _proto_TypeTraits::Get(id.number(), _extensions_);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline typename _proto_TypeTraits::MutableType MutableExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) {\n" - " return _proto_TypeTraits::Mutable(id.number(), &_extensions_);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline void SetExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id,\n" - " typename _proto_TypeTraits::ConstType value) {\n" - " _proto_TypeTraits::Set(id.number(), value, &_extensions_);\n" - "}\n" - "\n" - - // Repeated accessors - "template <typename _proto_TypeTraits>\n" - "inline typename _proto_TypeTraits::ConstType GetExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id,\n" - " int index) const {\n" - " return _proto_TypeTraits::Get(id.number(), _extensions_, index);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline typename _proto_TypeTraits::MutableType MutableExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id,\n" - " int index) {\n" - " return _proto_TypeTraits::Mutable(id.number(),index,&_extensions_);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline void SetExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id,\n" - " int index, typename _proto_TypeTraits::ConstType value) {\n" - " _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline typename _proto_TypeTraits::MutableType AddExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id) {\n" - " return _proto_TypeTraits::Add(id.number(), &_extensions_);\n" - "}\n" - "\n" - "template <typename _proto_TypeTraits>\n" - "inline void AddExtension(\n" - " const ::google::protobuf::internal::ExtensionIdentifier<\n" - " $classname$, _proto_TypeTraits>& id,\n" - " typename _proto_TypeTraits::ConstType value) {\n" - " _proto_TypeTraits::Add(id.number(), value, &_extensions_);\n" - "}\n", - "classname", classname_); - } -} - -void MessageGenerator:: -GenerateFieldAccessorDefinitions(io::Printer* printer) { - printer->Print("// $classname$\n\n", "classname", classname_); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - PrintFieldComment(printer, field); - - map<string, string> vars; - vars["name"] = FieldName(field); - vars["index"] = SimpleItoa(field->index()); - vars["classname"] = classname_; - - // Generate has_$name$() or $name$_size(). - if (field->is_repeated()) { - printer->Print(vars, - "inline int $classname$::$name$_size() const {\n" - " return $name$_.size();\n" - "}\n"); - } else { - // Singular field. - printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" - " return _has_bit($index$);\n" - "}\n"); - } - - // Generate clear_$name$() - printer->Print(vars, - "inline void $classname$::clear_$name$() {\n"); - - printer->Indent(); - field_generators_.get(field).GenerateClearingCode(printer); - printer->Outdent(); - - if (!field->is_repeated()) { - printer->Print(vars, " _clear_bit($index$);\n"); - } - - printer->Print("}\n"); - - // Generate type-specific accessors. - field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); - - printer->Print("\n"); - } -} - -void MessageGenerator:: -GenerateClassDefinition(io::Printer* printer) { - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateClassDefinition(printer); - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - - map<string, string> vars; - vars["classname"] = classname_; - vars["field_count"] = SimpleItoa(descriptor_->field_count()); - if (dllexport_decl_.empty()) { - vars["dllexport"] = ""; - } else { - vars["dllexport"] = dllexport_decl_ + " "; - } - vars["builddescriptorsname"] = - GlobalBuildDescriptorsName(descriptor_->file()->name()); - - printer->Print(vars, - "class $dllexport$$classname$ : public ::google::protobuf::Message {\n" - " public:\n"); - printer->Indent(); - - printer->Print(vars, - "$classname$();\n" - "virtual ~$classname$();\n" - "\n" - "$classname$(const $classname$& from);\n" - "\n" - "inline $classname$& operator=(const $classname$& from) {\n" - " CopyFrom(from);\n" - " return *this;\n" - "}\n" - "\n" - "inline static const $classname$& default_instance() {\n" - " return default_instance_;\n" - "}\n" - "\n" - "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n" - " return _unknown_fields_;\n" - "}\n" - "\n" - "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n" - " return &_unknown_fields_;\n" - "}\n" - "\n" - "static const ::google::protobuf::Descriptor* descriptor();\n" - "\n" - "// implements Message ----------------------------------------------\n" - "\n" - "$classname$* New() const;\n"); - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - printer->Print(vars, - "void CopyFrom(const ::google::protobuf::Message& from);\n" - "void MergeFrom(const ::google::protobuf::Message& from);\n" - "void CopyFrom(const $classname$& from);\n" - "void MergeFrom(const $classname$& from);\n" - "void Clear();\n" - "bool IsInitialized() const;\n" - "int ByteSize() const;\n" - "\n" - "bool MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input);\n" - "bool SerializeWithCachedSizes(\n" - " ::google::protobuf::io::CodedOutputStream* output) const;\n"); - } - - printer->Print(vars, - "int GetCachedSize() const { return _cached_size_; }\n" - "private:\n" - "void SetCachedSize(int size) const { _cached_size_ = size; }\n" - "public:\n" - "\n" - "const ::google::protobuf::Descriptor* GetDescriptor() const;\n" - "const ::google::protobuf::Reflection* GetReflection() const;\n" - "\n" - "// nested types ----------------------------------------------------\n" - "\n"); - - // Import all nested message classes into this class's scope with typedefs. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - const Descriptor* nested_type = descriptor_->nested_type(i); - printer->Print("typedef $nested_full_name$ $nested_name$;\n", - "nested_name", nested_type->name(), - "nested_full_name", ClassName(nested_type, false)); - } - - if (descriptor_->nested_type_count() > 0) { - printer->Print("\n"); - } - - // Import all nested enums and their values into this class's scope with - // typedefs and constants. - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - enum_generators_[i]->GenerateSymbolImports(printer); - printer->Print("\n"); - } - - printer->Print( - "// accessors -------------------------------------------------------\n" - "\n"); - - // Generate accessor methods for all fields. - GenerateFieldAccessorDeclarations(printer); - - // Declare extension identifiers. - for (int i = 0; i < descriptor_->extension_count(); i++) { - extension_generators_[i]->GenerateDeclaration(printer); - } - - // Generate private members for fields. - printer->Outdent(); - printer->Print(" private:\n"); - printer->Indent(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "::google::protobuf::internal::ExtensionSet _extensions_;\n"); - } - - // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. - printer->Print( - "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" - "mutable int _cached_size_;\n" - "\n"); - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GeneratePrivateMembers(printer); - } - - // Generate offsets and _has_bits_ boilerplate. - printer->Print(vars, - "friend void $builddescriptorsname$();\n" - "static const $classname$ default_instance_;\n"); - - if (descriptor_->field_count() > 0) { - printer->Print(vars, - "static const int _offsets_[$field_count$];\n" - "\n" - "::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( - "static const int _offsets_[1];\n" - "\n" - "::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"); - - printer->Outdent(); - printer->Print(vars, "};"); -} - -void MessageGenerator:: -GenerateInlineMethods(io::Printer* printer) { - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateInlineMethods(printer); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - - GenerateFieldAccessorDefinitions(printer); -} - -void MessageGenerator:: -GenerateDescriptorDeclarations(io::Printer* printer) { - printer->Print( - "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" - "const ::google::protobuf::internal::GeneratedMessageReflection*\n" - " $name$_reflection_ = NULL;\n", - "name", classname_); - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateDescriptorDeclarations(printer); - } - - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - printer->Print( - "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", - "name", ClassName(descriptor_->enum_type(i), false)); - } -} - -void MessageGenerator:: -GenerateDescriptorInitializer(io::Printer* printer, int index) { - // TODO(kenton): Passing the index to this method is redundant; just use - // descriptor_->index() instead. - map<string, string> vars; - vars["classname"] = classname_; - vars["index"] = SimpleItoa(index); - - // Obtain the descriptor from the parent's descriptor. - if (descriptor_->containing_type() == NULL) { - printer->Print(vars, - "$classname$_descriptor_ = file->message_type($index$);\n"); - } else { - vars["parent"] = ClassName(descriptor_->containing_type(), false); - printer->Print(vars, - "$classname$_descriptor_ = " - "$parent$_descriptor_->nested_type($index$);\n"); - } - - // Construct the reflection object. - printer->Print(vars, - "$classname$_reflection_ =\n" - " new ::google::protobuf::internal::GeneratedMessageReflection(\n" - " $classname$_descriptor_,\n" - " &$classname$::default_instance(),\n" - " $classname$::_offsets_,\n" - " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n" - " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" - "$classname$, _unknown_fields_),\n"); - if (descriptor_->extension_range_count() > 0) { - printer->Print(vars, - " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" - "$classname$, _extensions_),\n"); - } else { - // No extensions. - printer->Print(vars, - " -1,\n"); - } - printer->Print(vars, - " ::google::protobuf::DescriptorPool::generated_pool());\n"); - - // Handle nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDescriptorInitializer(printer, i); - } - - // Register this message type with the message factory. - printer->Print(vars, - "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" - " $classname$_descriptor_, &$classname$::default_instance());\n"); -} - -void MessageGenerator:: -GenerateClassMethods(io::Printer* printer) { - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - enum_generators_[i]->GenerateMethods(printer); - } - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->GenerateClassMethods(printer); - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - - printer->Print( - "const $classname$ $classname$::default_instance_;\n" - "\n", - "classname", classname_); - - // Generate non-inline field definitions. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateNonInlineAccessorDefinitions(printer); - printer->Print("\n"); - } - - // Define extension identifiers. - for (int i = 0; i < descriptor_->extension_count(); i++) { - extension_generators_[i]->GenerateDefinition(printer); - } - - GenerateOffsets(printer); - printer->Print("\n"); - - GenerateStructors(printer); - printer->Print("\n"); - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - GenerateClear(printer); - printer->Print("\n"); - - GenerateMergeFromCodedStream(printer); - printer->Print("\n"); - - GenerateSerializeWithCachedSizes(printer); - printer->Print("\n"); - - GenerateByteSize(printer); - printer->Print("\n"); - - GenerateMergeFrom(printer); - printer->Print("\n"); - - GenerateCopyFrom(printer); - printer->Print("\n"); - - GenerateIsInitialized(printer); - printer->Print("\n"); - } - - printer->Print( - "const ::google::protobuf::Descriptor* $classname$::GetDescriptor() const {\n" - " return descriptor();\n" - "}\n" - "\n" - "const ::google::protobuf::Reflection* $classname$::GetReflection() const {\n" - " if ($classname$_reflection_ == NULL) $builddescriptorsname$();\n" - " return $classname$_reflection_;\n" - "}\n", - "classname", classname_, - "builddescriptorsname", - GlobalBuildDescriptorsName(descriptor_->file()->name())); -} - -void MessageGenerator:: -GenerateOffsets(io::Printer* printer) { - printer->Print( - "const int $classname$::_offsets_[$field_count$] = {\n", - "classname", classname_, - "field_count", SimpleItoa(max(1, descriptor_->field_count()))); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - printer->Print( - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", - "classname", classname_, - "name", FieldName(field)); - } - - printer->Outdent(); - printer->Print("};\n"); -} - -void MessageGenerator:: -GenerateInitializerList(io::Printer* printer) { - printer->Indent(); - printer->Indent(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "_extensions_(&$classname$_descriptor_,\n" - " ::google::protobuf::DescriptorPool::generated_pool(),\n" - " ::google::protobuf::MessageFactory::generated_factory()),\n", - "classname", classname_); - } - - printer->Print( - "_cached_size_(0)"); - - // Write the initializers for each field. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateInitializer(printer); - } - - printer->Outdent(); - printer->Outdent(); -} - -void MessageGenerator:: -GenerateStructors(io::Printer* printer) { - // Generate the default constructor. - printer->Print( - "$classname$::$classname$()\n" - " : ", - "classname", classname_); - GenerateInitializerList(printer); - printer->Print(" {\n" - " ::memset(_has_bits_, 0, sizeof(_has_bits_));\n" - " if (this == &default_instance_) {\n"); - - // The default instance needs all of its embedded message pointers - // cross-linked to other default instances. - // TODO(kenton): Maybe all message fields (even for non-default messages) - // should be initialized to point at default instances rather than NULL? - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (!field->is_repeated() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", - "name", FieldName(field), - "type", ClassName(field->message_type(), true)); - } - } - printer->Print( - " }\n" - "}\n" - "\n"); - - // Generate the copy constructor. - printer->Print( - "$classname$::$classname$(const $classname$& from)\n" - " : ", - "classname", classname_); - GenerateInitializerList(printer); - printer->Print(" {\n" - " ::memset(_has_bits_, 0, sizeof(_has_bits_));\n" - " MergeFrom(from);\n" - "}\n" - "\n"); - - // Generate the destructor. - printer->Print( - "$classname$::~$classname$() {\n", - "classname", classname_); - - printer->Indent(); - - // Write the destructors for each field. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateDestructorCode(printer); - } - - printer->Print( - "if (this != &default_instance_) {\n"); - - // We need to delete all embedded messages. - // TODO(kenton): If we make unset messages point at default instances - // instead of NULL, then it would make sense to move this code into - // MessageFieldGenerator::GenerateDestructorCode(). - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (!field->is_repeated() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print(" delete $name$_;\n", - "name", FieldName(field)); - } - } - - printer->Outdent(); - - printer->Print( - " }\n" - "}\n" - "\n" - "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" - " if ($classname$_descriptor_ == NULL) $builddescriptorsname$();\n" - " return $classname$_descriptor_;\n" - "}\n" - "\n" - "$classname$* $classname$::New() const {\n" - " return new $classname$;\n" - "}\n", - "classname", classname_, - "builddescriptorsname", - GlobalBuildDescriptorsName(descriptor_->file()->name())); -} - -void MessageGenerator:: -GenerateClear(io::Printer* printer) { - printer->Print("void $classname$::Clear() {\n", - "classname", classname_); - printer->Indent(); - - int last_index = -1; - - if (descriptor_->extension_range_count() > 0) { - printer->Print("_extensions_.Clear();\n"); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - 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 - // of Clear() for messages which contain a very large number of - // optional fields of which only a few are used at a time. Here, - // we've chosen to check 8 bits at a time rather than 32. - if (i / 8 != last_index / 8 || last_index < 0) { - if (last_index >= 0) { - printer->Outdent(); - printer->Print("}\n"); - } - printer->Print(vars, - "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n"); - printer->Indent(); - } - last_index = i; - - // It's faster to just overwrite primitive types, but we should - // only clear strings and messages if they were set. - // TODO(kenton): Let the CppFieldGenerator decide this somehow. - bool should_check_bit = - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; - - if (should_check_bit) { - printer->Print(vars, "if (_has_bit($index$)) {\n"); - printer->Indent(); - } - - field_generators_.get(field).GenerateClearingCode(printer); - - if (should_check_bit) { - printer->Outdent(); - printer->Print("}\n"); - } - } - } - - if (last_index >= 0) { - printer->Outdent(); - printer->Print("}\n"); - } - - // Repeated fields don't use _has_bits_ so we clear them in a separate - // pass. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_repeated()) { - field_generators_.get(field).GenerateClearingCode(printer); - } - } - - printer->Print( - "::memset(_has_bits_, 0, sizeof(_has_bits_));\n" - "mutable_unknown_fields()->Clear();\n"); - - printer->Outdent(); - printer->Print("}\n"); -} - -void MessageGenerator:: -GenerateMergeFrom(io::Printer* printer) { - // Generate the generalized MergeFrom (aka that which takes in the Message - // base class as a parameter). - printer->Print( - "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n" - " GOOGLE_CHECK_NE(&from, this);\n", - "classname", classname_); - printer->Indent(); - - if (descriptor_->field_count() > 0) { - // Cast the message to the proper type. If we find that the message is - // *not* of the proper type, we can still call Merge via the reflection - // system, as the GOOGLE_CHECK above ensured that we have the same descriptor - // for each message. - printer->Print( - "const $classname$* source =\n" - " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n" - " &from);\n" - "if (source == NULL) {\n" - " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" - "} else {\n" - " MergeFrom(*source);\n" - "}\n", - "classname", classname_); - } - - printer->Outdent(); - printer->Print("}\n\n"); - - // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. - printer->Print( - "void $classname$::MergeFrom(const $classname$& from) {\n" - " GOOGLE_CHECK_NE(&from, this);\n", - "classname", classname_); - printer->Indent(); - - // Merge Repeated fields. These fields do not require a - // check as we can simply iterate over them. - for (int i = 0; i < descriptor_->field_count(); ++i) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_repeated()) { - field_generators_.get(field).GenerateMergingCode(printer); - } - } - - // Merge Optional and Required fields (after a _has_bit check). - int last_index = -1; - - for (int i = 0; i < descriptor_->field_count(); ++i) { - 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->Indent(); - } - - last_index = i; - - printer->Print(vars, - "if (from._has_bit($index$)) {\n"); - printer->Indent(); - - field_generators_.get(field).GenerateMergingCode(printer); - - printer->Outdent(); - printer->Print("}\n"); - } - } - - if (last_index >= 0) { - printer->Outdent(); - printer->Print("}\n"); - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); - } - - printer->Print( - "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"); - - printer->Outdent(); - printer->Print("}\n"); -} - -void MessageGenerator:: -GenerateCopyFrom(io::Printer* printer) { - // Generate the generalized CopyFrom (aka that which takes in the Message - // base class as a parameter). - printer->Print( - "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n", - "classname", classname_); - printer->Indent(); - - printer->Print( - "if (&from == this) return;\n" - "Clear();\n" - "MergeFrom(from);\n"); - - printer->Outdent(); - printer->Print("}\n\n"); - - // Generate the class-specific CopyFrom. - printer->Print( - "void $classname$::CopyFrom(const $classname$& from) {\n", - "classname", classname_); - printer->Indent(); - - printer->Print( - "if (&from == this) return;\n" - "Clear();\n" - "MergeFrom(from);\n"); - - printer->Outdent(); - printer->Print("}\n"); -} - -void MessageGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) { - if (descriptor_->options().message_set_wire_format()) { - // For message_set_wire_format, we don't generate a parser, for two - // reasons: - // - WireFormat already needs to special-case this, and we'd like to - // avoid having multiple implementations of MessageSet wire format - // lying around the code base. - // - All fields are extensions, and extension parsing falls back to - // reflection anyway, so it wouldn't be any faster. - printer->Print( - "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n" - " return ::google::protobuf::internal::WireFormat::ParseAndMergePartial(\n" - " input, this);\n" - "}\n", - "classname", classname_); - return; - } - - printer->Print( - "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n" - "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" - " ::google::protobuf::uint32 tag;\n" - " while ((tag = input->ReadTag()) != 0) {\n", - "classname", classname_); - - printer->Indent(); - printer->Indent(); - - if (descriptor_->field_count() > 0) { - // We don't even want to print the switch() if we have no fields because - // MSVC dislikes switch() statements that contain only a default value. - - // Note: If we just switched on the tag rather than the field number, we - // could avoid the need for the if() to check the wire type at the beginning - // of each case. However, this is actually a bit slower in practice as it - // creates a jump table that is 8x larger and sparser, and meanwhile the - // if()s are highly predictable. - printer->Print( - "switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) {\n"); - - printer->Indent(); - - scoped_array<const FieldDescriptor*> ordered_fields( - SortFieldsByNumber(descriptor_)); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = ordered_fields[i]; - - PrintFieldComment(printer, field); - - printer->Print( - "case $number$: {\n" - " if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=\n" - " ::google::protobuf::internal::WireFormat::WIRETYPE_$wiretype$) {\n" - " goto handle_uninterpreted;\n" - " }\n", - "number", SimpleItoa(field->number()), - "wiretype", kWireTypeNames[ - WireFormat::WireTypeForFieldType(field->type())]); - - if (i > 0 || field->is_repeated()) { - printer->Print( - " parse_$name$:\n", - "name", field->name()); - } - - printer->Indent(); - - field_generators_.get(field).GenerateMergeFromCodedStream(printer); - - // switch() is slow since it can't be predicted well. Insert some if()s - // here that attempt to predict the next tag. - if (field->is_repeated()) { - // Expect repeats of this field. - printer->Print( - "if (input->ExpectTag($tag$)) goto parse_$name$;\n", - "tag", SimpleItoa(WireFormat::MakeTag(field)), - "name", field->name()); - } - - if (i + 1 < descriptor_->field_count()) { - // Expect the next field in order. - const FieldDescriptor* next_field = ordered_fields[i + 1]; - printer->Print( - "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", - "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), - "next_name", next_field->name()); - } else { - // Expect EOF. - // TODO(kenton): Expect group end-tag? - printer->Print( - "if (input->ExpectAtEnd()) return true;\n"); - } - - printer->Print( - "break;\n"); - - printer->Outdent(); - printer->Print("}\n\n"); - } - - printer->Print( - "default: {\n" - "handle_uninterpreted:\n"); - printer->Indent(); - } - - // Is this an end-group tag? If so, this must be the end of the message. - printer->Print( - "if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) ==\n" - " ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) {\n" - " return true;\n" - "}\n"); - - // Handle extension ranges. - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "if ("); - for (int i = 0; i < descriptor_->extension_range_count(); i++) { - const Descriptor::ExtensionRange* range = - descriptor_->extension_range(i); - if (i > 0) printer->Print(" &&\n "); - - uint32 start_tag = WireFormat::MakeTag( - range->start, static_cast<WireFormat::WireType>(0)); - uint32 end_tag = WireFormat::MakeTag( - range->end, static_cast<WireFormat::WireType>(0)); - - if (range->end > FieldDescriptor::kMaxNumber) { - printer->Print( - "($start$u <= tag)", - "start", SimpleItoa(start_tag)); - } else { - printer->Print( - "($start$u <= tag && tag < $end$u)", - "start", SimpleItoa(start_tag), - "end", SimpleItoa(end_tag)); - } - } - printer->Print(") {\n" - " DO_(_extensions_.ParseField(tag, input, this));\n" - " continue;\n" - "}\n"); - } - - // We really don't recognize this tag. Skip it. - printer->Print( - "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" - " input, tag, mutable_unknown_fields()));\n"); - - if (descriptor_->field_count() > 0) { - printer->Print("break;\n"); - printer->Outdent(); - printer->Print("}\n"); // default: - printer->Outdent(); - printer->Print("}\n"); // switch - } - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // while - " return true;\n" - "#undef DO_\n" - "}\n"); -} - -void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field) { - PrintFieldComment(printer, field); - - if (field->is_repeated()) { - printer->Print( - "for (int i = 0; i < $name$_.size(); i++) {\n", - "name", FieldName(field)); - } else { - printer->Print( - "if (_has_bit($index$)) {\n", - "index", SimpleItoa(field->index())); - } - - printer->Indent(); - - field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); - - printer->Outdent(); - printer->Print("}\n\n"); -} - -void MessageGenerator::GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range) { - map<string, string> vars; - vars["start"] = SimpleItoa(range->start); - vars["end"] = SimpleItoa(range->end); - printer->Print(vars, - "// Extension range [$start$, $end$)\n" - "DO_(_extensions_.SerializeWithCachedSizes(\n" - " $start$, $end$, *this, output));\n\n"); -} - -void MessageGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) { - printer->Print( - "bool $classname$::SerializeWithCachedSizes(\n" - " ::google::protobuf::io::CodedOutputStream* output) const {\n" - "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n", - "classname", classname_); - printer->Indent(); - - scoped_array<const FieldDescriptor*> ordered_fields( - SortFieldsByNumber(descriptor_)); - - vector<const Descriptor::ExtensionRange*> sorted_extensions; - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { - sorted_extensions.push_back(descriptor_->extension_range(i)); - } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeSorter()); - - // Merge the fields and the extension ranges, both sorted by field number. - int i, j; - for (i = 0, j = 0; - i < descriptor_->field_count() || j < sorted_extensions.size(); - ) { - if (i == descriptor_->field_count()) { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } else if (j == sorted_extensions.size()) { - GenerateSerializeOneField(printer, ordered_fields[i++]); - } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { - GenerateSerializeOneField(printer, ordered_fields[i++]); - } else { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } - } - - printer->Print("if (!unknown_fields().empty()) {\n"); - printer->Indent(); - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "DO_(::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" - " unknown_fields(), output));\n"); - } else { - printer->Print( - "DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" - " unknown_fields(), output));\n"); - } - printer->Outdent(); - printer->Print( - "}\n" - "return true;\n"); - - printer->Outdent(); - printer->Print( - "#undef DO_\n" - "}\n"); -} - -void MessageGenerator:: -GenerateByteSize(io::Printer* printer) { - printer->Print( - "int $classname$::ByteSize() const {\n", - "classname", classname_); - printer->Indent(); - printer->Print( - "int total_size = 0;\n" - "\n"); - - int last_index = -1; - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (!field->is_repeated()) { - // See above in GenerateClear for an explanation of this. - // TODO(kenton): Share code? Unclear how to do so without - // over-engineering. - if ((i / 8) != (last_index / 8) || - last_index < 0) { - if (last_index >= 0) { - printer->Outdent(); - printer->Print("}\n"); - } - printer->Print( - "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", - "index", SimpleItoa(field->index())); - printer->Indent(); - } - last_index = i; - - PrintFieldComment(printer, field); - - printer->Print( - "if (has_$name$()) {\n", - "name", FieldName(field)); - printer->Indent(); - - field_generators_.get(field).GenerateByteSize(printer); - - printer->Outdent(); - printer->Print( - "}\n" - "\n"); - } - } - - if (last_index >= 0) { - printer->Outdent(); - printer->Print("}\n"); - } - - // Repeated fields don't use _has_bits_ so we count them in a separate - // pass. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_repeated()) { - PrintFieldComment(printer, field); - field_generators_.get(field).GenerateByteSize(printer); - printer->Print("\n"); - } - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "total_size += _extensions_.ByteSize(*this);\n" - "\n"); - } - - printer->Print("if (!unknown_fields().empty()) {\n"); - printer->Indent(); - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "total_size +=\n" - " ::google::protobuf::internal::WireFormat::ComputeUnknownMessageSetItemsSize(\n" - " unknown_fields());\n"); - } else { - printer->Print( - "total_size +=\n" - " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" - " unknown_fields());\n"); - } - printer->Outdent(); - printer->Print("}\n"); - - // We update _cached_size_ even though this is a const method. In theory, - // this is not thread-compatible, because concurrent writes have undefined - // results. In practice, since any concurrent writes will be writing the - // exact same value, it works on all common processors. In a future version - // of C++, _cached_size_ should be made into an atomic<int>. - printer->Print( - "_cached_size_ = total_size;\n" - "return total_size;\n"); - - printer->Outdent(); - printer->Print("}\n"); -} - -void MessageGenerator:: -GenerateIsInitialized(io::Printer* printer) { - printer->Print( - "bool $classname$::IsInitialized() const {\n", - "classname", classname_); - printer->Indent(); - - // Check that all required fields in this message are set. We can do this - // most efficiently by checking 32 "has bits" at a time. - int has_bits_array_size = (descriptor_->field_count() + 31) / 32; - for (int i = 0; i < has_bits_array_size; i++) { - uint32 mask = 0; - for (int bit = 0; bit < 32; bit++) { - int index = i * 32 + bit; - if (index >= descriptor_->field_count()) break; - const FieldDescriptor* field = descriptor_->field(index); - - if (field->is_required()) { - mask |= 1 << bit; - } - } - - if (mask != 0) { - char buffer[kFastToBufferSize]; - printer->Print( - "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", - "i", SimpleItoa(i), - "mask", FastHex32ToBuffer(mask, buffer)); - } - } - - // Now check that all embedded messages are initialized. - printer->Print("\n"); - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - HasRequiredFields(field->message_type())) { - if (field->is_repeated()) { - printer->Print( - "for (int i = 0; i < $name$_size(); i++) {\n" - " if (!this->$name$(i).IsInitialized()) return false;\n" - "}\n", - "name", FieldName(field)); - } else { - printer->Print( - "if (has_$name$()) {\n" - " if (!this->$name$().IsInitialized()) return false;\n" - "}\n", - "name", FieldName(field)); - } - } - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "\n" - "if (!_extensions_.IsInitialized()) return false;"); - } - - printer->Outdent(); - printer->Print( - " return true;\n" - "}\n"); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h deleted file mode 100644 index 904e0487..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ /dev/null @@ -1,125 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -class EnumGenerator; // enum.h -class ExtensionGenerator; // extension.h - -class MessageGenerator { - public: - // See generator.cc for the meaning of dllexport_decl. - explicit MessageGenerator(const Descriptor* descriptor, - const string& dllexport_decl); - ~MessageGenerator(); - - // Header stuff. - - // Generate foward declarations for this class and all its nested types. - void GenerateForwardDeclaration(io::Printer* printer); - - // Generate definitions of all nested enums (must come before class - // definitions because those classes use the enums definitions). - void GenerateEnumDefinitions(io::Printer* printer); - - // Generate definitions for this class and all its nested types. - void GenerateClassDefinition(io::Printer* printer); - - // Generate definitions of inline methods (placed at the end of the header - // file). - void GenerateInlineMethods(io::Printer* printer); - - // Source file stuff. - - // Generate code which declares all the global descriptor pointers which - // will be initialized by the methods below. - void GenerateDescriptorDeclarations(io::Printer* printer); - - // Generate code that initializes the global variable storing the message's - // descriptor. - void GenerateDescriptorInitializer(io::Printer* printer, int index); - - // Generate all non-inline methods for this class. - void GenerateClassMethods(io::Printer* printer); - - private: - // Generate declarations and definitions of accessors for fields. - void GenerateFieldAccessorDeclarations(io::Printer* printer); - void GenerateFieldAccessorDefinitions(io::Printer* printer); - - // Generate the field offsets array. - void GenerateOffsets(io::Printer* printer); - - // Generate constructors and destructor. - void GenerateStructors(io::Printer* printer); - - // Generate the member initializer list for the constructors. The member - // initializer list is shared between the default constructor and the copy - // constructor. - void GenerateInitializerList(io::Printer* printer); - - // Generate standard Message methods. - void GenerateClear(io::Printer* printer); - void GenerateMergeFromCodedStream(io::Printer* printer); - void GenerateSerializeWithCachedSizes(io::Printer* printer); - void GenerateByteSize(io::Printer* printer); - void GenerateMergeFrom(io::Printer* printer); - void GenerateCopyFrom(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer); - - // Helpers for GenerateSerializeWithCachedSizes(). - void GenerateSerializeOneField(io::Printer* printer, - const FieldDescriptor* field); - void GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range); - - const Descriptor* descriptor_; - string classname_; - string dllexport_decl_; - FieldGeneratorMap field_generators_; - scoped_array<scoped_ptr<MessageGenerator> > nested_generators_; - scoped_array<scoped_ptr<EnumGenerator> > enum_generators_; - scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc deleted file mode 100644 index 501ca569..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ /dev/null @@ -1,229 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_message_field.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format_inl.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -using internal::WireFormat; - -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, - map<string, string>* variables) { - (*variables)["name"] = FieldName(descriptor); - (*variables)["type"] = ClassName(descriptor->message_type(), true); - (*variables)["index"] = SimpleItoa(descriptor->index()); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["classname"] = ClassName(FieldScope(descriptor), false); - (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); -} - -} // namespace - -// =================================================================== - -MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -MessageFieldGenerator::~MessageFieldGenerator() {} - -void MessageFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "$type$* $name$_;\n"); -} - -void MessageFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $name$() const;\n" - "inline $type$* mutable_$name$();\n"); -} - -void MessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" - " return $name$_ != NULL ? *$name$_ : *default_instance_.$name$_;\n" - "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" - " _set_bit($index$);\n" - " if ($name$_ == NULL) $name$_ = new $type$;\n" - " return $name$_;\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($name$_ != NULL) $name$_->$type$::Clear();\n"); -} - -void MessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "mutable_$name$()->$type$::MergeFrom(from.$name$());\n"); -} - -void MessageFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - printer->Print(variables_, ",\n$name$_(NULL)"); -} - -void MessageFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n" - " input, mutable_$name$()));\n"); - } else { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual(" - "$number$, input, mutable_$name$()));\n"); - } -} - -void MessageFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual(" - "$number$, this->$name$(), output));\n"); -} - -void MessageFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n" - " this->$name$());\n"); -} - -// =================================================================== - -RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} - -void RepeatedMessageFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, - "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >& $name$() const;\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >* mutable_$name$();\n" - "inline const $type$& $name$(int index) const;\n" - "inline $type$* mutable_$name$(int index);\n" - "inline $type$* add_$name$();\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" - "inline const $type$& $classname$::$name$(int index) const {\n" - " return $name$_.Get(index);\n" - "}\n" - "inline $type$* $classname$::mutable_$name$(int index) {\n" - " return $name$_.Mutable(index);\n" - "}\n" - "inline $type$* $classname$::add_$name$() {\n" - " return $name$_.Add();\n" - "}\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Clear();\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedMessageFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual(\n" - " input, add_$name$()));\n"); - } else { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::ReadGroupNoVirtual(" - "$number$, input, add_$name$()));\n"); - } -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$NoVirtual(" - "$number$, this->$name$(i), output));\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ * $name$_size();\n" - "for (int i = 0; i < $name$_size(); i++) {\n" - " total_size +=\n" - " ::google::protobuf::internal::WireFormat::$declared_type$SizeNoVirtual(\n" - " this->$name$(i));\n" - "}\n"); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h deleted file mode 100644 index a2be6b65..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -class MessageFieldGenerator : public FieldGenerator { - public: - explicit MessageFieldGenerator(const FieldDescriptor* descriptor); - ~MessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); -}; - -class RepeatedMessageFieldGenerator : public FieldGenerator { - public: - explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedMessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc deleted file mode 100644 index 312ed031..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ /dev/null @@ -1,294 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_primitive_field.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format_inl.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -using internal::WireFormat; - -namespace { - -// For encodings with fixed sizes, returns that size in bytes. Otherwise -// returns -1. -int FixedSize(FieldDescriptor::Type type) { - switch (type) { - case FieldDescriptor::TYPE_INT32 : return -1; - case FieldDescriptor::TYPE_INT64 : return -1; - case FieldDescriptor::TYPE_UINT32 : return -1; - case FieldDescriptor::TYPE_UINT64 : return -1; - case FieldDescriptor::TYPE_SINT32 : return -1; - case FieldDescriptor::TYPE_SINT64 : return -1; - case FieldDescriptor::TYPE_FIXED32 : return WireFormat::kFixed32Size; - case FieldDescriptor::TYPE_FIXED64 : return WireFormat::kFixed64Size; - case FieldDescriptor::TYPE_SFIXED32: return WireFormat::kSFixed32Size; - case FieldDescriptor::TYPE_SFIXED64: return WireFormat::kSFixed64Size; - case FieldDescriptor::TYPE_FLOAT : return WireFormat::kFloatSize; - case FieldDescriptor::TYPE_DOUBLE : return WireFormat::kDoubleSize; - - case FieldDescriptor::TYPE_BOOL : return WireFormat::kBoolSize; - case FieldDescriptor::TYPE_ENUM : return -1; - - case FieldDescriptor::TYPE_STRING : return -1; - case FieldDescriptor::TYPE_BYTES : return -1; - case FieldDescriptor::TYPE_GROUP : return -1; - case FieldDescriptor::TYPE_MESSAGE : return -1; - - // No default because we want the compiler to complain if any new - // types are added. - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return -1; -} - -string DefaultValue(const FieldDescriptor* field) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return SimpleItoa(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - return SimpleItoa(field->default_value_uint32()) + "u"; - case FieldDescriptor::CPPTYPE_INT64: - return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")"; - case FieldDescriptor::CPPTYPE_UINT64: - return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()); - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field->default_value_float()); - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_STRING: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Shouldn't get here."; - return ""; - } - // Can't actually get here; make compiler happy. (We could add a default - // case above but then we wouldn't get the nice compiler warning when a - // new type is added.) - return ""; -} - -// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of -// repeat code between this and the other field types. -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { - (*variables)["name"] = FieldName(descriptor); - (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type()); - (*variables)["default"] = DefaultValue(descriptor); - (*variables)["index"] = SimpleItoa(descriptor->index()); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["classname"] = ClassName(FieldScope(descriptor), false); - (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); - - int fixed_size = FixedSize(descriptor->type()); - if (fixed_size != -1) { - (*variables)["fixed_size"] = SimpleItoa(fixed_size); - } -} - -} // namespace - -// =================================================================== - -PrimitiveFieldGenerator:: -PrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} - -void PrimitiveFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "$type$ $name$_;\n"); -} - -void PrimitiveFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $name$() const;\n" - "inline void set_$name$($type$ value);\n"); -} - -void PrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" - " _set_bit($index$);\n" - " $name$_ = value;\n" - "}\n"); -} - -void PrimitiveFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $default$;\n"); -} - -void PrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "set_$name$(from.$name$());\n"); -} - -void PrimitiveFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - printer->Print(variables_, ",\n$name$_($default$)"); -} - -void PrimitiveFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n" - " input, &$name$_));\n" - "_set_bit($index$);\n"); -} - -void PrimitiveFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$(" - "$number$, this->$name$(), output));\n"); -} - -void PrimitiveFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - int fixed_size = FixedSize(descriptor_->type()); - if (fixed_size == -1) { - printer->Print(variables_, - "total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormat::$declared_type$Size(\n" - " this->$name$());\n"); - } else { - printer->Print(variables_, - "total_size += $tag_size$ + $fixed_size$;\n"); - } -} - -// =================================================================== - -RepeatedPrimitiveFieldGenerator:: -RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} - -void RepeatedPrimitiveFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, - "::google::protobuf::RepeatedField< $type$ > $name$_;\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >& $name$() const;\n" - "inline ::google::protobuf::RepeatedField< $type$ >* mutable_$name$();\n" - "inline $type$ $name$(int index) const;\n" - "inline void set_$name$(int index, $type$ value);\n" - "inline void add_$name$($type$ value);\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" - "inline $type$ $classname$::$name$(int index) const {\n" - " return $name$_.Get(index);\n" - "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n" - " $name$_.Set(index, value);\n" - "}\n" - "inline void $classname$::add_$name$($type$ value) {\n" - " $name$_.Add(value);\n" - "}\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Clear();\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "$type$ value;\n" - "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(input, &value));\n" - "add_$name$(value);\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$(" - "$number$, this->$name$(i), output));\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - int fixed_size = FixedSize(descriptor_->type()); - if (fixed_size == -1) { - printer->Print(variables_, - "total_size += $tag_size$ * $name$_size();\n" - "for (int i = 0; i < $name$_size(); i++) {\n" - " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n" - " this->$name$(i));\n" - "}\n"); - } else { - printer->Print(variables_, - "total_size += ($tag_size$ + $fixed_size$) * $name$_size();\n"); - } -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h deleted file mode 100644 index 832b2411..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -class PrimitiveFieldGenerator : public FieldGenerator { - public: - explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~PrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); -}; - -class RepeatedPrimitiveFieldGenerator : public FieldGenerator { - public: - explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedPrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc deleted file mode 100644 index 124f3b43..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_service.cc +++ /dev/null @@ -1,318 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_service.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor, - const string& dllexport_decl) - : descriptor_(descriptor) { - vars_["classname"] = descriptor_->name(); - vars_["full_name"] = descriptor_->full_name(); - if (dllexport_decl.empty()) { - vars_["dllexport"] = ""; - } else { - vars_["dllexport"] = dllexport_decl + " "; - } -} - -ServiceGenerator::~ServiceGenerator() {} - -void ServiceGenerator::GenerateDeclarations(io::Printer* printer) { - // Forward-declare the stub type. - printer->Print(vars_, - "class $classname$_Stub;\n" - "\n"); - - GenerateInterface(printer); - GenerateStubDefinition(printer); -} - -void ServiceGenerator::GenerateInterface(io::Printer* printer) { - printer->Print(vars_, - "class $dllexport$$classname$ : public ::google::protobuf::Service {\n" - " protected:\n" - " // This class should be treated as an abstract interface.\n" - " inline $classname$() {};\n" - " public:\n" - " virtual ~$classname$();\n"); - printer->Indent(); - - printer->Print(vars_, - "\n" - "typedef $classname$_Stub Stub;\n" - "\n" - "static const ::google::protobuf::ServiceDescriptor* descriptor();\n" - "\n"); - - GenerateMethodSignatures(VIRTUAL, printer); - - printer->Print( - "\n" - "// implements Service ----------------------------------------------\n" - "\n" - "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n" - "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n" - " ::google::protobuf::RpcController* controller,\n" - " const ::google::protobuf::Message* request,\n" - " ::google::protobuf::Message* response,\n" - " ::google::protobuf::Closure* done);\n" - "const ::google::protobuf::Message& GetRequestPrototype(\n" - " const ::google::protobuf::MethodDescriptor* method) const;\n" - "const ::google::protobuf::Message& GetResponsePrototype(\n" - " const ::google::protobuf::MethodDescriptor* method) const;\n"); - - printer->Outdent(); - printer->Print(vars_, - "\n" - " private:\n" - " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n" - "};\n" - "\n"); -} - -void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) { - printer->Print(vars_, - "class $dllexport$$classname$_Stub : public $classname$ {\n" - " public:\n"); - - printer->Indent(); - - printer->Print(vars_, - "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n" - "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n" - " ::google::protobuf::Service::ChannelOwnership ownership);\n" - "~$classname$_Stub();\n" - "\n" - "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n" - "\n" - "// implements $classname$ ------------------------------------------\n" - "\n"); - - GenerateMethodSignatures(NON_VIRTUAL, printer); - - printer->Outdent(); - printer->Print(vars_, - " private:\n" - " ::google::protobuf::RpcChannel* channel_;\n" - " bool owns_channel_;\n" - " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n" - "};\n" - "\n"); -} - -void ServiceGenerator::GenerateMethodSignatures( - VirtualOrNon virtual_or_non, io::Printer* printer) { - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> sub_vars; - sub_vars["name"] = method->name(); - sub_vars["input_type"] = ClassName(method->input_type(), true); - sub_vars["output_type"] = ClassName(method->output_type(), true); - sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : ""; - - printer->Print(sub_vars, - "$virtual$void $name$(::google::protobuf::RpcController* controller,\n" - " const $input_type$* request,\n" - " $output_type$* response,\n" - " ::google::protobuf::Closure* done);\n"); - } -} - -// =================================================================== - -void ServiceGenerator::GenerateDescriptorInitializer( - io::Printer* printer, int index) { - map<string, string> vars; - vars["classname"] = descriptor_->name(); - vars["index"] = SimpleItoa(index); - - printer->Print(vars, - "$classname$_descriptor_ = file->service($index$);\n"); -} - -// =================================================================== - -void ServiceGenerator::GenerateImplementation(io::Printer* printer) { - printer->Print(vars_, - "$classname$::~$classname$() {}\n" - "\n" - "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n" - " return $classname$_descriptor_;\n" - "}\n" - "\n" - "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n" - " return $classname$_descriptor_;\n" - "}\n" - "\n"); - - // Generate methods of the interface. - GenerateNotImplementedMethods(printer); - GenerateCallMethod(printer); - GenerateGetPrototype(REQUEST, printer); - GenerateGetPrototype(RESPONSE, printer); - - // Generate stub implementation. - printer->Print(vars_, - "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n" - " : channel_(channel), owns_channel_(false) {}\n" - "$classname$_Stub::$classname$_Stub(\n" - " ::google::protobuf::RpcChannel* channel,\n" - " ::google::protobuf::Service::ChannelOwnership ownership)\n" - " : channel_(channel),\n" - " owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n" - "$classname$_Stub::~$classname$_Stub() {\n" - " if (owns_channel_) delete channel_;\n" - "}\n" - "\n"); - - GenerateStubMethods(printer); -} - -void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) { - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> sub_vars; - sub_vars["classname"] = descriptor_->name(); - sub_vars["name"] = method->name(); - sub_vars["index"] = SimpleItoa(i); - sub_vars["input_type"] = ClassName(method->input_type(), true); - sub_vars["output_type"] = ClassName(method->output_type(), true); - - printer->Print(sub_vars, - "void $classname$::$name$(::google::protobuf::RpcController* controller,\n" - " const $input_type$* request,\n" - " $output_type$* response,\n" - " ::google::protobuf::Closure* done) {\n" - " controller->SetFailed(\"Method $name$() not implemented.\");\n" - " done->Run();\n" - "}\n" - "\n"); - } -} - -void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { - printer->Print(vars_, - "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n" - " ::google::protobuf::RpcController* controller,\n" - " const ::google::protobuf::Message* request,\n" - " ::google::protobuf::Message* response,\n" - " ::google::protobuf::Closure* done) {\n" - " GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n" - " switch(method->index()) {\n"); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> sub_vars; - sub_vars["name"] = method->name(); - sub_vars["index"] = SimpleItoa(i); - sub_vars["input_type"] = ClassName(method->input_type(), true); - sub_vars["output_type"] = ClassName(method->output_type(), true); - - // Note: ::google::protobuf::down_cast does not work here because it only works on pointers, - // not references. - printer->Print(sub_vars, - " case $index$:\n" - " $name$(controller,\n" - " ::google::protobuf::down_cast<const $input_type$*>(request),\n" - " ::google::protobuf::down_cast< $output_type$*>(response),\n" - " done);\n" - " break;\n"); - } - - printer->Print(vars_, - " default:\n" - " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n" - " break;\n" - " }\n" - "}\n" - "\n"); -} - -void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, - io::Printer* printer) { - if (which == REQUEST) { - printer->Print(vars_, - "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n"); - } else { - printer->Print(vars_, - "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n"); - } - - printer->Print(vars_, - " const ::google::protobuf::MethodDescriptor* method) const {\n" - " GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n" - " switch(method->index()) {\n"); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - const Descriptor* type = - (which == REQUEST) ? method->input_type() : method->output_type(); - - map<string, string> sub_vars; - sub_vars["index"] = SimpleItoa(i); - sub_vars["type"] = ClassName(type, true); - - printer->Print(sub_vars, - " case $index$:\n" - " return $type$::default_instance();\n"); - } - - printer->Print(vars_, - " default:\n" - " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n" - " return *reinterpret_cast< ::google::protobuf::Message*>(NULL);\n" - " }\n" - "}\n" - "\n"); -} - -void ServiceGenerator::GenerateStubMethods(io::Printer* printer) { - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> sub_vars; - sub_vars["classname"] = descriptor_->name(); - sub_vars["name"] = method->name(); - sub_vars["index"] = SimpleItoa(i); - sub_vars["input_type"] = ClassName(method->input_type(), true); - sub_vars["output_type"] = ClassName(method->output_type(), true); - - printer->Print(sub_vars, - "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n" - " const $input_type$* request,\n" - " $output_type$* response,\n" - " ::google::protobuf::Closure* done) {\n" - " channel_->CallMethod($classname$_descriptor_->method($index$),\n" - " controller, request, response, done);\n" - "}\n"); - } -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_service.h b/src/google/protobuf/compiler/cpp/cpp_service.h deleted file mode 100644 index bccb64e4..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_service.h +++ /dev/null @@ -1,104 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ - -#include <map> -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace cpp { - -class ServiceGenerator { - public: - // See generator.cc for the meaning of dllexport_decl. - explicit ServiceGenerator(const ServiceDescriptor* descriptor, - const string& dllexport_decl); - ~ServiceGenerator(); - - // Header stuff. - - // Generate the class definitions for the service's interface and the - // stub implementation. - void GenerateDeclarations(io::Printer* printer); - - // Source file stuff. - - // Generate code that initializes the global variable storing the service's - // descriptor. - void GenerateDescriptorInitializer(io::Printer* printer, int index); - - // Generate implementations of everything declared by GenerateDeclarations(). - void GenerateImplementation(io::Printer* printer); - - private: - enum RequestOrResponse { REQUEST, RESPONSE }; - enum VirtualOrNon { VIRTUAL, NON_VIRTUAL }; - - // Header stuff. - - // Generate the service abstract interface. - void GenerateInterface(io::Printer* printer); - - // Generate the stub class definition. - void GenerateStubDefinition(io::Printer* printer); - - // Prints signatures for all methods in the - void GenerateMethodSignatures(VirtualOrNon virtual_or_non, - io::Printer* printer); - - // Source file stuff. - - // Generate the default implementations of the service methods, which - // produce a "not implemented" error. - void GenerateNotImplementedMethods(io::Printer* printer); - - // Generate the CallMethod() method of the service. - void GenerateCallMethod(io::Printer* printer); - - // Generate the Get{Request,Response}Prototype() methods. - void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); - - // Generate the stub's implementations of the service methods. - void GenerateStubMethods(io::Printer* printer); - - const ServiceDescriptor* descriptor_; - map<string, string> vars_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc deleted file mode 100644 index 8590df7e..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ /dev/null @@ -1,370 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/cpp/cpp_string_field.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format_inl.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -using internal::WireFormat; - -namespace { - -// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of -// repeat code between this and the other field types. -void SetStringVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { - (*variables)["name"] = FieldName(descriptor); - (*variables)["default"] = - "\"" + CEscape(descriptor->default_value_string()) + "\""; - (*variables)["index"] = SimpleItoa(descriptor->index()); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["classname"] = ClassName(FieldScope(descriptor), false); - (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - (*variables)["tag_size"] = SimpleItoa( - WireFormat::TagSize(descriptor->number(), descriptor->type())); -} - -} // namespace - -// =================================================================== - -StringFieldGenerator:: -StringFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetStringVariables(descriptor, &variables_); -} - -StringFieldGenerator::~StringFieldGenerator() {} - -void StringFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, - "::std::string* $name$_;\n" - "static const ::std::string _default_$name$_;\n"); -} - -void StringFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - // If we're using StringFieldGenerator for a field with a ctype, it's - // because that ctype isn't actually implemented. In particular, this is - // true of ctype=CORD and ctype=STRING_PIECE in the open source release. - // We aren't releasing Cord because it has too many Google-specific - // dependencies and we aren't releasing StringPiece because it's hardly - // useful outside of Google and because it would get confusing to have - // multiple instances of the StringPiece class in different libraries (PCRE - // already includes it for their C++ bindings, which came from Google). - // - // In any case, we make all the accessors private while still actually - // using a string to represent the field internally. This way, we can - // guarantee that if we do ever implement the ctype, it won't break any - // existing users who might be -- for whatever reason -- already using .proto - // files that applied the ctype. The field can still be accessed via the - // reflection interface since the reflection interface is independent of - // the string's underlying representation. - if (descriptor_->options().has_ctype()) { - printer->Outdent(); - printer->Print( - " private:\n" - " // Hidden due to unknown ctype option.\n"); - printer->Indent(); - } - - printer->Print(variables_, - "inline const ::std::string& $name$() const;\n" - "inline void set_$name$(const ::std::string& value);\n" - "inline void set_$name$(const char* value);\n"); - if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) { - printer->Print(variables_, - "inline void set_$name$(const void* value, size_t size);\n"); - } - - printer->Print(variables_, - "inline ::std::string* mutable_$name$();\n"); - - if (descriptor_->options().has_ctype()) { - printer->Outdent(); - printer->Print(" public:\n"); - printer->Indent(); - } -} - -void StringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" - " return *$name$_;\n" - "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\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" - " $name$_ = new ::std::string;\n" - " }\n" - " $name$_->assign(value);\n" - "}\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) { - printer->Print(variables_, - "inline void $classname$::set_$name$(const void* value, size_t size) {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n" - " $name$_ = new ::std::string;\n" - " }\n" - " $name$_->assign(reinterpret_cast<const char*>(value), size);\n" - "}\n"); - } - - printer->Print(variables_, - "inline ::std::string* $classname$::mutable_$name$() {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n"); - if (descriptor_->has_default_value()) { - printer->Print(variables_, - " $name$_ = new ::std::string(_default_$name$_);\n"); - } else { - printer->Print(variables_, - " $name$_ = new ::std::string;\n"); - } - printer->Print(variables_, - " }\n" - " return $name$_;\n" - "}\n"); -} - -void StringFieldGenerator:: -GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { - if (descriptor_->has_default_value()) { - printer->Print(variables_, - "const ::std::string $classname$::_default_$name$_($default$);"); - } else { - printer->Print(variables_, - "const ::std::string $classname$::_default_$name$_;"); - } -} - -void StringFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - if (descriptor_->has_default_value()) { - printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" - " $name$_->assign(_default_$name$_);\n" - "}\n"); - } else { - printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" - " $name$_->clear();\n" - "}\n"); - } -} - -void StringFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "set_$name$(from.$name$());\n"); -} - -void StringFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - printer->Print(variables_, - ",\n$name$_(const_cast< ::std::string*>(&_default_$name$_))"); -} - -void StringFieldGenerator:: -GenerateDestructorCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" - " delete $name$_;\n" - "}\n"); -} - -void StringFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(" - "input, mutable_$name$()));\n"); -} - -void StringFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$(" - "$number$, this->$name$(), output));\n"); -} - -void StringFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormat::$declared_type$Size(this->$name$());\n"); -} - -// =================================================================== - -RepeatedStringFieldGenerator:: -RepeatedStringFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetStringVariables(descriptor, &variables_); -} - -RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {} - -void RepeatedStringFieldGenerator:: -GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, - "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n"); -} - -void RepeatedStringFieldGenerator:: -GenerateAccessorDeclarations(io::Printer* printer) const { - // See comment above about unknown ctypes. - if (descriptor_->options().has_ctype()) { - printer->Outdent(); - printer->Print( - " private:\n" - " // Hidden due to unknown ctype option.\n"); - printer->Indent(); - } - - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const;\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$();\n" - "inline const ::std::string& $name$(int index) const;\n" - "inline ::std::string* mutable_$name$(int index);\n" - "inline void set_$name$(int index, const ::std::string& value);\n" - "inline void set_$name$(int index, const char* value);\n" - "inline ::std::string* add_$name$();\n" - "inline void add_$name$(const ::std::string& value);\n" - "inline void add_$name$(const char* value);\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) { - printer->Print(variables_, - "inline void set_$name$(int index, const void* value, size_t size);\n" - "inline void add_$name$(const void* value, size_t size);\n"); - } - - if (descriptor_->options().has_ctype()) { - printer->Outdent(); - printer->Print(" public:\n"); - printer->Indent(); - } -} - -void RepeatedStringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" - "$classname$::$name$() const {\n" - " return $name$_;\n" - "}\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" - "$classname$::mutable_$name$() {\n" - " return &$name$_;\n" - "}\n" - "inline const ::std::string& $classname$::$name$(int index) const {\n" - " return $name$_.Get(index);\n" - "}\n" - "inline ::std::string* $classname$::mutable_$name$(int index) {\n" - " return $name$_.Mutable(index);\n" - "}\n" - "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n" - " $name$_.Mutable(index)->assign(value);\n" - "}\n" - "inline void $classname$::set_$name$(int index, const char* value) {\n" - " $name$_.Mutable(index)->assign(value);\n" - "}\n" - "inline ::std::string* $classname$::add_$name$() {\n" - " return $name$_.Add();\n" - "}\n" - "inline void $classname$::add_$name$(const ::std::string& value) {\n" - " $name$_.Add()->assign(value);\n" - "}\n" - "inline void $classname$::add_$name$(const char* value) {\n" - " $name$_.Add()->assign(value);\n" - "}\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) { - printer->Print(variables_, - "inline void " - "$classname$::set_$name$(int index, const void* value, size_t size) {\n" - " $name$_.Mutable(index)->assign(\n" - " reinterpret_cast<const char*>(value), size);\n" - "}\n" - "inline void $classname$::add_$name$(const void* value, size_t size) {\n" - " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n" - "}\n"); - } -} - -void RepeatedStringFieldGenerator:: -GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Clear();\n"); -} - -void RepeatedStringFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); -} - -void RepeatedStringFieldGenerator:: -GenerateInitializer(io::Printer* printer) const { - // Not needed for repeated fields. -} - -void RepeatedStringFieldGenerator:: -GenerateMergeFromCodedStream(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n" - " input, add_$name$()));\n"); -} - -void RepeatedStringFieldGenerator:: -GenerateSerializeWithCachedSizes(io::Printer* printer) const { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$(" - "$number$, this->$name$(i), output));\n"); -} - -void RepeatedStringFieldGenerator:: -GenerateByteSize(io::Printer* printer) const { - printer->Print(variables_, - "total_size += $tag_size$ * $name$_size();\n" - "for (int i = 0; i < $name$_size(); i++) {\n" - " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n" - " this->$name$(i));\n" - "}\n"); -} - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h deleted file mode 100644 index 44ffd18c..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ /dev/null @@ -1,86 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/cpp/cpp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -class StringFieldGenerator : public FieldGenerator { - public: - explicit StringFieldGenerator(const FieldDescriptor* descriptor); - ~StringFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateDestructorCode(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); -}; - -class RepeatedStringFieldGenerator : public FieldGenerator { - public: - explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedStringFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateClearingCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateInitializer(io::Printer* printer) const; - void GenerateMergeFromCodedStream(io::Printer* printer) const; - void GenerateSerializeWithCachedSizes(io::Printer* printer) const; - void GenerateByteSize(io::Printer* printer) const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator); -}; - -} // namespace cpp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto deleted file mode 100644 index ee0499bf..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +++ /dev/null @@ -1,87 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file tests that various identifiers work as field and type names even -// though the same identifiers are used internally by the C++ code generator. - - -// 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; - -// Test that fields can have names like "input" and "i" which are also used -// internally by the code generator for local variables. -message TestConflictingSymbolNames { - message BuildDescriptors {} - message TypeTraits {} - - optional int32 input = 1; - optional int32 output = 2; - optional string length = 3; - repeated int32 i = 4; - repeated string new_element = 5 [ctype=STRING_PIECE]; - optional int32 total_size = 6; - optional int32 tag = 7; - - optional int32 source = 8; - optional int32 value = 9; - optional int32 file = 10; - optional int32 from = 11; - optional int32 handle_uninterpreted = 12; - repeated int32 index = 13; - optional int32 controller = 14; - optional int32 already_here = 15; - - optional uint32 uint32 = 16; - optional uint64 uint64 = 17; - optional string string = 18; - optional int32 memset = 19; - optional int32 int32 = 20; - optional int64 int64 = 21; - - optional uint32 cached_size = 22; - optional uint32 extensions = 23; - optional uint32 bit = 24; - optional uint32 bits = 25; - optional uint32 offsets = 26; - optional uint32 reflection = 27; - - message Cord {} - optional string some_cord = 28 [ctype=CORD]; - - message StringPiece {} - optional string some_string_piece = 29 [ctype=STRING_PIECE]; - - // Some keywords. - optional uint32 int = 30; - optional uint32 friend = 31; - - // The generator used to #define a macro called "DO" inside the .cc file. - message DO {} - optional DO do = 32; - - extensions 1000 to max; -} - -message DummyMessage {} - -service TestConflictingMethodNames { - rpc Closure(DummyMessage) returns (DummyMessage); -} diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc deleted file mode 100644 index 010843cf..00000000 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ /dev/null @@ -1,848 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// To test the code generator, we actually use it to generate code for -// google/protobuf/unittest.proto, then test that. This means that we -// are actually testing the parser and other parts of the system at the same -// time, and that problems in the generator may show up as compile-time errors -// rather than unittest failures, which may be surprising. However, testing -// the output of the C++ generator directly would be very hard. We can't very -// well just check it against golden files since those files would have to be -// updated for any small change; such a test would be very brittle and probably -// not very helpful. What we really want to test is that the code compiles -// correctly and produces the interfaces we expect, which is why this test -// is written this way. - -#include <vector> - -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/unittest_optimize_for.pb.h> -#include <google/protobuf/unittest_embed_optimize_for.pb.h> -#include <google/protobuf/test_util.h> -#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h> -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/dynamic_message.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace cpp { - -namespace { - - -class MockErrorCollector : public MultiFileErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", - filename, line, column, message); - } -}; - -// Test that generated code has proper descriptors: -// Parse a descriptor directly (using google::protobuf::compiler::Importer) and -// compare it to the one that was produced by generated code. -TEST(GeneratedDescriptorTest, IdenticalDescriptors) { - const FileDescriptor* generated_descriptor = - unittest::TestAllTypes::descriptor()->file(); - - // Set up the Importer. - MockErrorCollector error_collector; - DiskSourceTree source_tree; - source_tree.MapPath("", TestSourceDir()); - Importer importer(&source_tree, &error_collector); - - // Import (parse) unittest.proto. - const FileDescriptor* parsed_descriptor = - importer.Import("google/protobuf/unittest.proto"); - EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(parsed_descriptor != NULL); - - // Test that descriptors are generated correctly by converting them to - // FileDescriptorProtos and comparing. - FileDescriptorProto generated_decsriptor_proto, parsed_descriptor_proto; - generated_descriptor->CopyTo(&generated_decsriptor_proto); - parsed_descriptor->CopyTo(&parsed_descriptor_proto); - - EXPECT_EQ(parsed_descriptor_proto.DebugString(), - generated_decsriptor_proto.DebugString()); -} - -// =================================================================== - -TEST(GeneratedMessageTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllTypes message; - - TestUtil::ExpectClear(message); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -TEST(GeneratedMessageTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - TestUtil::ExpectAllFieldsSet(message); - - TestUtil::ModifyRepeatedFields(&message); - TestUtil::ExpectRepeatedFieldsModified(message); -} - -TEST(GeneratedMessageTest, MutableStringDefault) { - // mutable_foo() for a string should return a string initialized to its - // default value. - unittest::TestAllTypes message; - - EXPECT_EQ("hello", *message.mutable_default_string()); - - // Note that the first time we call mutable_foo(), we get a newly-allocated - // string, but if we clear it and call it again, we get the same object again. - // We should verify that it has its default value in both cases. - message.set_default_string("blah"); - message.Clear(); - - EXPECT_EQ("hello", *message.mutable_default_string()); -} - -TEST(GeneratedMessageTest, Clear) { - // Set every field to a unique value, clear the message, then check that - // it is cleared. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - message.Clear(); - TestUtil::ExpectClear(message); - - // Unlike with the defaults test, we do NOT expect that requesting embedded - // messages will return a pointer to the default instance. Instead, they - // should return the objects that were created when mutable_blah() was - // called. - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) { - unittest::TestAllTypes message; - - const char* value = "\0lalala\0\0"; - message.set_optional_bytes(value, 9); - ASSERT_EQ(9, message.optional_bytes().size()); - EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9)); - - message.add_repeated_bytes(value, 9); - ASSERT_EQ(9, message.repeated_bytes(0).size()); - EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9)); -} - -TEST(GeneratedMessageTest, ClearOneField) { - // Set every field to a unique value, then clear one value and insure that - // only that one value is cleared. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - int64 original_value = message.optional_int64(); - - // Clear the field and make sure it shows up as cleared. - message.clear_optional_int64(); - EXPECT_FALSE(message.has_optional_int64()); - EXPECT_EQ(0, message.optional_int64()); - - // Other adjacent fields should not be cleared. - EXPECT_TRUE(message.has_optional_int32()); - EXPECT_TRUE(message.has_optional_uint32()); - - // Make sure if we set it again, then all fields are set. - message.set_optional_int64(original_value); - TestUtil::ExpectAllFieldsSet(message); -} - - -TEST(GeneratedMessageTest, CopyFrom) { - unittest::TestAllTypes message1, message2; - string data; - - TestUtil::SetAllFields(&message1); - message2.CopyFrom(message1); - TestUtil::ExpectAllFieldsSet(message2); - - // Copying from self should be a no-op. - message2.CopyFrom(message2); - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageTest, CopyConstructor) { - unittest::TestAllTypes message1; - TestUtil::SetAllFields(&message1); - - unittest::TestAllTypes message2(message1); - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageTest, CopyAssignmentOperator) { - unittest::TestAllTypes message1; - TestUtil::SetAllFields(&message1); - - unittest::TestAllTypes message2; - message2 = message1; - TestUtil::ExpectAllFieldsSet(message2); - - // Make sure that self-assignment does something sane. - message2 = message2; - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageTest, UpcastCopyFrom) { - // Test the CopyFrom method that takes in the generic const Message& - // parameter. - unittest::TestAllTypes message1, message2; - - TestUtil::SetAllFields(&message1); - - const Message* source = implicit_cast<const Message*>(&message1); - message2.CopyFrom(*source); - - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageTest, DynamicMessageCopyFrom) { - // Test copying from a DynamicMessage, which must fall back to using - // reflection. - unittest::TestAllTypes message2; - - // Construct a new version of the dynamic message via the factory. - DynamicMessageFactory factory; - scoped_ptr<Message> message1; - message1.reset(factory.GetPrototype( - unittest::TestAllTypes::descriptor())->New()); - - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - reflection_tester.SetAllFieldsViaReflection(message1.get()); - - message2.CopyFrom(*message1); - - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(GeneratedMessageTest, NonEmptyMergeFrom) { - // Test merging with a non-empty message. Code is a modified form - // of that found in google/protobuf/reflection_ops_unittest.cc. - unittest::TestAllTypes message1, message2; - - TestUtil::SetAllFields(&message1); - - // This field will test merging into an empty spot. - message2.set_optional_int32(message1.optional_int32()); - message1.clear_optional_int32(); - - // This tests overwriting. - message2.set_optional_string(message1.optional_string()); - message1.set_optional_string("something else"); - - // This tests concatenating. - message2.add_repeated_int32(message1.repeated_int32(1)); - int32 i = message1.repeated_int32(0); - message1.clear_repeated_int32(); - message1.add_repeated_int32(i); - - message1.MergeFrom(message2); - - TestUtil::ExpectAllFieldsSet(message1); -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(GeneratedMessageTest, MergeFromSelf) { - unittest::TestAllTypes message; - EXPECT_DEATH(message.MergeFrom(message), "&from"); - EXPECT_DEATH(message.MergeFrom(implicit_cast<const Message&>(message)), - "&from"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(GeneratedMessageTest, Serialization) { - unittest::TestAllTypes message1, message2; - string data; - - TestUtil::SetAllFields(&message1); - message1.SerializeToString(&data); - EXPECT_TRUE(message2.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(message2); - -} - - -TEST(GeneratedMessageTest, Required) { - // Test that IsInitialized() returns false if required fields are missing. - unittest::TestRequired message; - - EXPECT_FALSE(message.IsInitialized()); - message.set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(GeneratedMessageTest, RequiredForeign) { - // Test that IsInitialized() returns false if required fields in nested - // messages are missing. - unittest::TestRequiredForeign message; - - EXPECT_TRUE(message.IsInitialized()); - - message.mutable_optional_message(); - EXPECT_FALSE(message.IsInitialized()); - - message.mutable_optional_message()->set_a(1); - message.mutable_optional_message()->set_b(2); - message.mutable_optional_message()->set_c(3); - EXPECT_TRUE(message.IsInitialized()); - - message.add_repeated_message(); - EXPECT_FALSE(message.IsInitialized()); - - message.mutable_repeated_message(0)->set_a(1); - message.mutable_repeated_message(0)->set_b(2); - message.mutable_repeated_message(0)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(GeneratedMessageTest, ForeignNested) { - // Test that TestAllTypes::NestedMessage can be embedded directly into - // another message. - unittest::TestForeignNested message; - - // If this compiles and runs without crashing, it must work. We have - // nothing more to test. - unittest::TestAllTypes::NestedMessage* nested = - message.mutable_foreign_nested(); - nested->set_bb(1); -} - -TEST(GeneratedMessageTest, ReallyLargeTagNumber) { - // Test that really large tag numbers don't break anything. - unittest::TestReallyLargeTagNumber message1, message2; - string data; - - // For the most part, if this compiles and runs then we're probably good. - // (The most likely cause for failure would be if something were attempting - // to allocate a lookup table of some sort using tag numbers as the index.) - // We'll try serializing just for fun. - message1.set_a(1234); - message1.set_bb(5678); - message1.SerializeToString(&data); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(1234, message2.a()); - EXPECT_EQ(5678, message2.bb()); -} - -TEST(GeneratedMessageTest, MutualRecursion) { - // Test that mutually-recursive message types work. - unittest::TestMutualRecursionA message; - unittest::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a(); - unittest::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a(); - - // Again, if the above compiles and runs, that's all we really have to - // test, but just for run we'll check that the system didn't somehow come - // up with a pointer loop... - EXPECT_NE(&message, nested); - EXPECT_NE(&message, nested2); - EXPECT_NE(nested, nested2); -} - -TEST(GeneratedMessageTest, CamelCaseFieldNames) { - // This test is mainly checking that the following compiles, which verifies - // that the field names were coerced to lower-case. - // - // Protocol buffers standard style is to use lowercase-with-underscores for - // field names. Some old proto1 .protos unfortunately used camel-case field - // names. In proto1, these names were forced to lower-case. So, we do the - // same thing in proto2. - - unittest::TestCamelCaseFieldNames message; - - message.set_primitivefield(2); - message.set_stringfield("foo"); - message.set_enumfield(unittest::FOREIGN_FOO); - message.mutable_messagefield()->set_c(6); - - message.add_repeatedprimitivefield(8); - message.add_repeatedstringfield("qux"); - message.add_repeatedenumfield(unittest::FOREIGN_BAR); - message.add_repeatedmessagefield()->set_c(15); - - EXPECT_EQ(2, message.primitivefield()); - EXPECT_EQ("foo", message.stringfield()); - EXPECT_EQ(unittest::FOREIGN_FOO, message.enumfield()); - EXPECT_EQ(6, message.messagefield().c()); - - EXPECT_EQ(8, message.repeatedprimitivefield(0)); - EXPECT_EQ("qux", message.repeatedstringfield(0)); - EXPECT_EQ(unittest::FOREIGN_BAR, message.repeatedenumfield(0)); - EXPECT_EQ(15, message.repeatedmessagefield(0).c()); -} - -TEST(GeneratedMessageTest, TestConflictingSymbolNames) { - // test_bad_identifiers.proto successfully compiled, then it works. The - // following is just a token usage to insure that the code is, in fact, - // being compiled and linked. - - protobuf_unittest::TestConflictingSymbolNames message; - message.set_uint32(1); - EXPECT_EQ(3, message.ByteSize()); - - message.set_friend_(5); - EXPECT_EQ(5, message.friend_()); -} - -TEST(GeneratedMessageTest, TestOptimizedForSize) { - // We rely on the tests in reflection_ops_unittest and wire_format_unittest - // to really test that reflection-based methods work. Here we are mostly - // just making sure that TestOptimizedForSize actually builds and seems to - // function. - - protobuf_unittest::TestOptimizedForSize message, message2; - message.set_i(1); - message.mutable_msg()->set_c(2); - message2.CopyFrom(message); - EXPECT_EQ(1, message2.i()); - EXPECT_EQ(2, message2.msg().c()); -} - -TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) { - // Verifies that something optimized for speed can contain something optimized - // for size. - - protobuf_unittest::TestEmbedOptimizedForSize message, message2; - message.mutable_optional_message()->set_i(1); - message.add_repeated_message()->mutable_msg()->set_c(2); - string data; - message.SerializeToString(&data); - ASSERT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(1, message2.optional_message().i()); - EXPECT_EQ(2, message2.repeated_message(0).msg().c()); -} - -// =================================================================== - -TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) { - // Test that our nested enum values can be used as switch cases. This test - // doesn't actually do anything, the proof that it works is that it - // compiles. - int i =0; - unittest::TestAllTypes::NestedEnum a = unittest::TestAllTypes::BAR; - switch (a) { - case unittest::TestAllTypes::FOO: - i = 1; - break; - case unittest::TestAllTypes::BAR: - i = 2; - break; - case unittest::TestAllTypes::BAZ: - i = 3; - break; - // no default case: We want to make sure the compiler recognizes that - // all cases are covered. (GCC warns if you do not cover all cases of - // an enum in a switch.) - } - - // Token check just for fun. - EXPECT_EQ(2, i); -} - -TEST(GeneratedEnumTest, IsValidValue) { - // Test enum IsValidValue. - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(1)); - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(2)); - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(3)); - - EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(0)); - EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(4)); - - // Make sure it also works when there are dups. - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(1)); - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(2)); - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(3)); - - EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(0)); - EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(4)); -} - -TEST(GeneratedEnumTest, MinAndMax) { - EXPECT_EQ(unittest::TestAllTypes::FOO,unittest::TestAllTypes::NestedEnum_MIN); - EXPECT_EQ(unittest::TestAllTypes::BAZ,unittest::TestAllTypes::NestedEnum_MAX); - - EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN); - EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX); - - EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN); - EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX); - - EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN); - EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX); - - // Make sure we can use _MIN and _MAX as switch cases. - switch(unittest::SPARSE_A) { - case unittest::TestSparseEnum_MIN: - case unittest::TestSparseEnum_MAX: - break; - default: - break; - } -} - -// =================================================================== - -// Support code for testing services. -class GeneratedServiceTest : public testing::Test { - protected: - class MockTestService : public unittest::TestService { - public: - MockTestService() - : called_(false), - method_(""), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL) {} - - ~MockTestService() {} - - void Reset() { called_ = false; } - - // implements TestService ---------------------------------------- - - void Foo(RpcController* controller, - const unittest::FooRequest* request, - unittest::FooResponse* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = "Foo"; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - void Bar(RpcController* controller, - const unittest::BarRequest* request, - unittest::BarResponse* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = "Bar"; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - // --------------------------------------------------------------- - - bool called_; - string method_; - RpcController* controller_; - const Message* request_; - Message* response_; - Closure* done_; - }; - - class MockRpcChannel : public RpcChannel { - public: - MockRpcChannel() - : called_(false), - method_(NULL), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL), - destroyed_(NULL) {} - - ~MockRpcChannel() { - if (destroyed_ != NULL) *destroyed_ = true; - } - - void Reset() { called_ = false; } - - // implements TestService ---------------------------------------- - - void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = method; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - // --------------------------------------------------------------- - - bool called_; - const MethodDescriptor* method_; - RpcController* controller_; - const Message* request_; - Message* response_; - Closure* done_; - bool* destroyed_; - }; - - class MockController : public RpcController { - public: - void Reset() { - ADD_FAILURE() << "Reset() not expected during this test."; - } - bool Failed() const { - ADD_FAILURE() << "Failed() not expected during this test."; - return false; - } - string ErrorText() const { - ADD_FAILURE() << "ErrorText() not expected during this test."; - return ""; - } - void StartCancel() { - ADD_FAILURE() << "StartCancel() not expected during this test."; - } - void SetFailed(const string& reason) { - ADD_FAILURE() << "SetFailed() not expected during this test."; - } - bool IsCanceled() const { - ADD_FAILURE() << "IsCanceled() not expected during this test."; - return false; - } - void NotifyOnCancel(Closure* callback) { - ADD_FAILURE() << "NotifyOnCancel() not expected during this test."; - } - }; - - GeneratedServiceTest() - : descriptor_(unittest::TestService::descriptor()), - foo_(descriptor_->FindMethodByName("Foo")), - bar_(descriptor_->FindMethodByName("Bar")), - stub_(&mock_channel_), - done_(NewPermanentCallback(&DoNothing)) {} - - virtual void SetUp() { - ASSERT_TRUE(foo_ != NULL); - ASSERT_TRUE(bar_ != NULL); - } - - const ServiceDescriptor* descriptor_; - const MethodDescriptor* foo_; - const MethodDescriptor* bar_; - - MockTestService mock_service_; - MockController mock_controller_; - - MockRpcChannel mock_channel_; - unittest::TestService::Stub stub_; - - // Just so we don't have to re-define these with every test. - unittest::FooRequest foo_request_; - unittest::FooResponse foo_response_; - unittest::BarRequest bar_request_; - unittest::BarResponse bar_response_; - scoped_ptr<Closure> done_; -}; - -TEST_F(GeneratedServiceTest, GetDescriptor) { - // Test that GetDescriptor() works. - - EXPECT_EQ(descriptor_, mock_service_.GetDescriptor()); -} - -TEST_F(GeneratedServiceTest, GetChannel) { - EXPECT_EQ(&mock_channel_, stub_.channel()); -} - -TEST_F(GeneratedServiceTest, OwnsChannel) { - MockRpcChannel* channel = new MockRpcChannel; - bool destroyed = false; - channel->destroyed_ = &destroyed; - - { - unittest::TestService::Stub owning_stub(channel, - Service::STUB_OWNS_CHANNEL); - EXPECT_FALSE(destroyed); - } - - EXPECT_TRUE(destroyed); -} - -TEST_F(GeneratedServiceTest, CallMethod) { - // Test that CallMethod() works. - - // Call Foo() via CallMethod(). - mock_service_.CallMethod(foo_, &mock_controller_, - &foo_request_, &foo_response_, done_.get()); - - ASSERT_TRUE(mock_service_.called_); - - EXPECT_EQ("Foo" , mock_service_.method_ ); - EXPECT_EQ(&mock_controller_, mock_service_.controller_); - EXPECT_EQ(&foo_request_ , mock_service_.request_ ); - EXPECT_EQ(&foo_response_ , mock_service_.response_ ); - EXPECT_EQ(done_.get() , mock_service_.done_ ); - - // Try again, but call Bar() instead. - mock_service_.Reset(); - mock_service_.CallMethod(bar_, &mock_controller_, - &bar_request_, &bar_response_, done_.get()); - - ASSERT_TRUE(mock_service_.called_); - EXPECT_EQ("Bar", mock_service_.method_); -} - -TEST_F(GeneratedServiceTest, CallMethodTypeFailure) { - // Verify death if we call Foo() with Bar's message types. - -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - EXPECT_DEBUG_DEATH( - mock_service_.CallMethod(foo_, &mock_controller_, - &foo_request_, &bar_response_, done_.get()), - "dynamic_cast"); - - mock_service_.Reset(); - EXPECT_DEBUG_DEATH( - mock_service_.CallMethod(foo_, &mock_controller_, - &bar_request_, &foo_response_, done_.get()), - "dynamic_cast"); -#endif // GTEST_HAS_DEATH_TEST -} - -TEST_F(GeneratedServiceTest, GetPrototypes) { - // Test Get{Request,Response}Prototype() methods. - - EXPECT_EQ(&unittest::FooRequest::default_instance(), - &mock_service_.GetRequestPrototype(foo_)); - EXPECT_EQ(&unittest::BarRequest::default_instance(), - &mock_service_.GetRequestPrototype(bar_)); - - EXPECT_EQ(&unittest::FooResponse::default_instance(), - &mock_service_.GetResponsePrototype(foo_)); - EXPECT_EQ(&unittest::BarResponse::default_instance(), - &mock_service_.GetResponsePrototype(bar_)); -} - -TEST_F(GeneratedServiceTest, Stub) { - // Test that the stub class works. - - // Call Foo() via the stub. - stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get()); - - ASSERT_TRUE(mock_channel_.called_); - - EXPECT_EQ(foo_ , mock_channel_.method_ ); - EXPECT_EQ(&mock_controller_, mock_channel_.controller_); - EXPECT_EQ(&foo_request_ , mock_channel_.request_ ); - EXPECT_EQ(&foo_response_ , mock_channel_.response_ ); - EXPECT_EQ(done_.get() , mock_channel_.done_ ); - - // Call Bar() via the stub. - mock_channel_.Reset(); - stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get()); - - ASSERT_TRUE(mock_channel_.called_); - EXPECT_EQ(bar_, mock_channel_.method_); -} - -TEST_F(GeneratedServiceTest, NotImplemented) { - // Test that failing to implement a method of a service causes it to fail - // with a "not implemented" error message. - - // A service which doesn't implement any methods. - class UnimplementedService : public unittest::TestService { - public: - UnimplementedService() {} - }; - - UnimplementedService unimplemented_service; - - // And a controller which expects to get a "not implemented" error. - class ExpectUnimplementedController : public MockController { - public: - ExpectUnimplementedController() : called_(false) {} - - void SetFailed(const string& reason) { - EXPECT_FALSE(called_); - called_ = true; - EXPECT_EQ("Method Foo() not implemented.", reason); - } - - bool called_; - }; - - ExpectUnimplementedController controller; - - // Call Foo. - unimplemented_service.Foo(&controller, &foo_request_, &foo_response_, - done_.get()); - - EXPECT_TRUE(controller.called_); -} - -} // namespace - -} // namespace cpp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc deleted file mode 100644 index 38b30863..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_enum.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/csharp/csharp_enum.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) - : descriptor_(descriptor) { - for (int i = 0; i < descriptor_->value_count(); i++) { - const EnumValueDescriptor* value = descriptor_->value(i); - const EnumValueDescriptor* canonical_value = - descriptor_->FindValueByNumber(value->number()); - - if (value == canonical_value) { - canonical_values_.push_back(value); - } else { - Alias alias; - alias.value = value; - alias.canonical_value = canonical_value; - aliases_.push_back(alias); - } - } -} - -EnumGenerator::~EnumGenerator() {} - -void EnumGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - descriptor_->file()->options().csharp_multiple_files(); - printer->Print( - "public enum $classname$ {\r\n", - "classname", descriptor_->name()); - printer->Indent(); - - for (int i = 0; i < canonical_values_.size(); i++) { - map<string, string> vars; - vars["name"] = canonical_values_[i]->name(); - vars["number"] = SimpleItoa(canonical_values_[i]->number()); - - // TODO(jonskeet): Change CONSTANT_CASE into PascalCase? (Would muck up text format) - printer->Print(vars, - "$name$ = $number$,\r\n"); - } - - for (int i = 0; i < aliases_.size(); i++) { - map<string, string> vars; - vars["name"] = aliases_[i].value->name(); - vars["canonical_number"] = SimpleItoa(aliases_[i].canonical_value->number()); - printer->Print(vars, - "$name$ = $canonical_number$,\r\n"); - } - - printer->Outdent(); - printer->Print("}\r\n\r\n"); - -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.h b/src/google/protobuf/compiler/csharp/csharp_enum.h deleted file mode 100644 index dec98918..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_enum.h +++ /dev/null @@ -1,71 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ - -#include <string> -#include <vector> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -class EnumGenerator { - public: - explicit EnumGenerator(const EnumDescriptor* descriptor); - ~EnumGenerator(); - - void Generate(io::Printer* printer); - - private: - const EnumDescriptor* descriptor_; - - // The proto language allows multiple enum constants to have the same numeric - // value. Java, however, does not allow multiple enum constants to be - // considered equivalent. We treat the first defined constant for any - // given numeric value as "canonical" and the rest as aliases of that - // canonical value. - vector<const EnumValueDescriptor*> canonical_values_; - - struct Alias { - const EnumValueDescriptor* value; - const EnumValueDescriptor* canonical_value; - }; - vector<Alias> aliases_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc deleted file mode 100644 index 00b69910..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc +++ /dev/null @@ -1,263 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/csharp/csharp_enum_field.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -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, - map<string, string>* variables) { - const EnumValueDescriptor* default_value; - default_value = descriptor->default_value_enum(); - - string type = ClassName(descriptor->enum_type()); - - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = type; - (*variables)["default"] = type + "." + default_value->name(); -} - -} // namespace - -// =================================================================== - -EnumFieldGenerator:: -EnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -EnumFieldGenerator::~EnumFieldGenerator() {} - -void EnumFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private bool has$capitalized_name$;\r\n" - "private $type$ $name$_ = $default$;\r\n" - "public bool Has$capitalized_name$ {\r\n" - " get { return has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {" - " get { return $name$_; }" - "}\r\n"); -} - -void EnumFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - printer->Print(variables_, - "public bool Has$capitalized_name$ {\r\n" - " get { return result.Has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {\r\n" - " get { return result.$capitalized_name$; }\r\n" - " set { Set$capitalized_name$(value); }\r\n" - "}\r\n" - "public Builder Set$capitalized_name$($type$ value) {\r\n" - " result.has$capitalized_name$ = true;\r\n" - " result.$name$_ = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.has$capitalized_name$ = false;\r\n" - " result.$name$_ = $default$;\r\n" - " return this;\r\n" - "}\r\n"); -} - -void EnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.Has$capitalized_name$) {\r\n" - " $capitalized_name$ = other.$capitalized_name$;\r\n" - "}\r\n"); -} - -void EnumFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for enum types. -} - -void EnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - // TODO(jonskeet): Make a more efficient way of doing this - "int rawValue = input.ReadEnum();\r\n" - "if (!global::System.Enum.IsDefined(typeof($type$), rawValue)) {\r\n" - " unknownFields.MergeVarintField($number$, (ulong) rawValue);\r\n" - "} else {\r\n" - " $capitalized_name$ = ($type$) rawValue;\r\n" - "}\r\n"); -} - -void EnumFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " output.WriteEnum($number$, (int) $capitalized_name$);\r\n" - "}\r\n"); -} - -void EnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " size += pb::CodedOutputStream\r\n" - " .ComputeEnumSize($number$, (int) $capitalized_name$);\r\n" - "}\r\n"); -} - -// =================================================================== - -RepeatedEnumFieldGenerator:: -RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} - -void RepeatedEnumFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private scg::IList<$type$> $name$_ = new scg::List<$type$> ();\r\n" - "public scg.IList<$type$> $capitalized_name$List {\r\n" - " get { return pbc::Lists.AsReadOnly($name$_); }\r\n" // note: unmodifiable list - "}\r\n" - - // Redundant API calls? - // TODO(jonskeet): Possibly. Include for portability to start with though. - "public int $capitalized_name$Count {\r\n" - " get { return $name$_.Count; }\r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return $name$_[index];\r\n" - "}\r\n" - ); -} - -void RepeatedEnumFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - 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 scg::IList<$type$> $capitalized_name$List {\r\n" - " get { return pbc::Lists.AsReadOnly(result.$name$_); }\r\n" - "}\r\n" - "public int $capitalized_name$Count {\r\n" - " get { return result.$capitalized_name$Count; } \r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return result.Get$capitalized_name$(index);\r\n" - "}\r\n" - "public Builder Set$capitalized_name$(int index, $type$ value) {\r\n" - " result.$name$_[index] = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Add$capitalized_name$($type$ value) {\r\n" - " if (result.$name$_.Count == 0) {\r\n" - " result.$name$_ = new scg::List<$type$>();\r\n" - " }\r\n" - " result.$name$_.Add(value);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n" - " if (result.$name$_.Count == 0) {\r\n" - " result.$name$_ = new scg::List<$type$>();\r\n" - " }\r\n" - " base.AddRange(values, result.$name$_);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.$name$_ = pbc::Lists<$type$>.Empty;\r\n" - " return this;\r\n" - "}\r\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.$name$_.Count != 0) {\r\n" - " if (result.$name$_.Count == 0) {\r\n" - " result.$name$_ = new scg::List<$type$>();\r\n" - " }\r\n" - " base.AddRange(other.$name$_, result.$name$_);\r\n" - "}\r\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "result.$name$_ = pbc::Lists.AsReadOnly(result.$name$_);\r\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "int rawValue = input.ReadEnum();\r\n" - "$type$ value = ($type$) rawValue;\r\n" - "if (!global::System.Enum.IsDefined(typeof($type$), value)) {\r\n" - " unknownFields.MergeVarintField($number$, (ulong) rawValue);\r\n" - "} else {\r\n" - " Add$capitalized_name$(value);\r\n" - "}\r\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " output.WriteEnum($number$, (int) element);\r\n" - "}\r\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " size += pb::CodedOutputStream\r\n" - " .ComputeEnumSize($number$, (int) element);\r\n" - "}\r\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h deleted file mode 100644 index 6bf07004..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.h +++ /dev/null @@ -1,83 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/csharp/csharp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -class EnumFieldGenerator : public FieldGenerator { - public: - explicit EnumFieldGenerator(const FieldDescriptor* descriptor); - ~EnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); -}; - -class RepeatedEnumFieldGenerator : public FieldGenerator { - public: - explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedEnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_extension.cc b/src/google/protobuf/compiler/csharp/csharp_extension.cc deleted file mode 100644 index a9103e97..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_extension.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/csharp/csharp_extension.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) {} - -ExtensionGenerator::~ExtensionGenerator() {} - -void ExtensionGenerator::Generate(io::Printer* printer) { - map<string, string> vars; - vars["name"] = UnderscoresToCapitalizedCamelCase(descriptor_); - vars["containing_type"] = ClassName(descriptor_->containing_type()); - vars["index"] = SimpleItoa(descriptor_->index()); - - MappedType mapped_type = GetMappedType(descriptor_); - string singular_type; - switch (mapped_type) { - case MAPPEDTYPE_MESSAGE: - vars["type"] = ClassName(descriptor_->message_type()); - break; - case MAPPEDTYPE_ENUM: - vars["type"] = ClassName(descriptor_->enum_type()); - break; - default: - vars["type"] = MappedTypeName(mapped_type); - break; - } - - if (descriptor_->is_repeated()) { - printer->Print(vars, - "public static readonly\r\n" - " pb::GeneratedExtensionBase<scg::IList<$type$>> $name$ =\r\n" - " pb::GeneratedRepeatExtension<$type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n"); - } else { - printer->Print(vars, - "public static readonly pb::GeneratedExtensionBase<$type$> $name$ =\r\n" - " pb::GeneratedSingleExtension<$type$>.CreateInstance(Descriptor.Extensions[$index$]);\r\n"); - } -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_extension.h b/src/google/protobuf/compiler/csharp/csharp_extension.h deleted file mode 100644 index 3f14762f..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_extension.h +++ /dev/null @@ -1,59 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ - -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - class FieldDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -// Generates code for an extension, which may be within the scope of some -// message or may be at file scope. This is much simpler than FieldGenerator -// since extensions are just simple identifiers with interesting types. -class ExtensionGenerator { - public: - explicit ExtensionGenerator(const FieldDescriptor* descriptor); - ~ExtensionGenerator(); - - void Generate(io::Printer* printer); - - private: - const FieldDescriptor* descriptor_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_field.cc b/src/google/protobuf/compiler/csharp/csharp_field.cc deleted file mode 100644 index 1bf01094..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_field.cc +++ /dev/null @@ -1,89 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/csharp/csharp_field.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> -#include <google/protobuf/compiler/csharp/csharp_enum_field.h> -#include <google/protobuf/compiler/csharp/csharp_message_field.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -FieldGenerator::~FieldGenerator() {} - -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) - : descriptor_(descriptor), - field_generators_( - new scoped_ptr<FieldGenerator>[descriptor->field_count()]), - extension_generators_( - new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { - - // Construct all the FieldGenerators. - for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i))); - } - for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset(MakeGenerator(descriptor->extension(i))); - } -} - -FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { - if (field->is_repeated()) { - switch (GetMappedType(field)) { - case MAPPEDTYPE_MESSAGE: - return new RepeatedMessageFieldGenerator(field); - case MAPPEDTYPE_ENUM: - return new RepeatedEnumFieldGenerator(field); - default: - return new RepeatedPrimitiveFieldGenerator(field); - } - } else { - switch (GetMappedType(field)) { - case MAPPEDTYPE_MESSAGE: - return new MessageFieldGenerator(field); - case MAPPEDTYPE_ENUM: - return new EnumFieldGenerator(field); - default: - return new PrimitiveFieldGenerator(field); - } - } -} - -FieldGeneratorMap::~FieldGeneratorMap() {} - -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); - return *field_generators_[field->index()]; -} - -const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { - return *extension_generators_[index]; -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_field.h b/src/google/protobuf/compiler/csharp/csharp_field.h deleted file mode 100644 index 5c1b9f87..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_field.h +++ /dev/null @@ -1,81 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -class FieldGenerator { - public: - FieldGenerator() {} - virtual ~FieldGenerator(); - - virtual void GenerateMembers(io::Printer* printer) const = 0; - virtual void GenerateBuilderMembers(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 GenerateSerializationCode(io::Printer* printer) const = 0; - virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); -}; - -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { - public: - explicit FieldGeneratorMap(const Descriptor* descriptor); - ~FieldGeneratorMap(); - - const FieldGenerator& get(const FieldDescriptor* field) const; - const FieldGenerator& get_extension(int index) const; - - private: - const Descriptor* descriptor_; - scoped_array<scoped_ptr<FieldGenerator> > field_generators_; - scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; - - static FieldGenerator* MakeGenerator(const FieldDescriptor* field); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_file.cc b/src/google/protobuf/compiler/csharp/csharp_file.cc deleted file mode 100644 index 4c0d7443..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_file.cc +++ /dev/null @@ -1,295 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/csharp/csharp_file.h> -#include <google/protobuf/compiler/csharp/csharp_enum.h> -#include <google/protobuf/compiler/csharp/csharp_service.h> -#include <google/protobuf/compiler/csharp/csharp_extension.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/compiler/csharp/csharp_message.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -FileGenerator::FileGenerator(const FileDescriptor* file) - : file_(file), - csharp_namespace_(FileCSharpNamespace(file)), - classname_(FileClassName(file)) {} - -FileGenerator::~FileGenerator() {} - -bool FileGenerator::Validate(string* error) { - // Check that no class name matches the file's class name. This is a common - // problem that leads to Java compile errors that can be hard to understand. - // It's especially bad when using the csharp_multiple_files, since we would - // end up overwriting the outer class with one of the inner ones. - - bool found_conflict = false; - for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) { - if (file_->enum_type(i)->name() == classname_) { - found_conflict = true; - } - } - for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) { - if (file_->message_type(i)->name() == classname_) { - found_conflict = true; - } - } - for (int i = 0; i < file_->service_count() && !found_conflict; i++) { - if (file_->service(i)->name() == classname_) { - found_conflict = true; - } - } - - if (found_conflict) { - error->assign(file_->name()); - error->append( - ": Cannot generate C# output because the file's top-level class name, \""); - error->append(classname_); - error->append( - "\", matches the name of one of the message, service or enum types. " - "Please either rename the type or use the csharp_file_classname " - "option to specify a different file-level class name for the .proto file."); - return false; - } - - return true; -} - -void FileGenerator::Generate(io::Printer* printer) { - // We don't import anything because we refer to all classes by their - // fully-qualified names in the generated source. - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\r\n" - "\r\n"); - - // Namespace aliases to avoid lines getting horribly long - printer->Print("using pb = global::Google.ProtocolBuffers;\r\n"); - printer->Print("using pbc = global::Google.ProtocolBuffers.Collections;\r\n"); - printer->Print("using pbd = global::Google.ProtocolBuffers.Descriptors;\r\n"); - printer->Print("using scg = global::System.Collections.Generic;\r\n"); - - if (!csharp_namespace_.empty()) { - printer->Print( - "namespace $namespace$ {\r\n", - "namespace", csharp_namespace_); - printer->Indent(); - } - printer->Print("\r\n"); - printer->Print( - "$access$ static partial class $classname$ {\r\n\r\n", - "classname", classname_, - "access", ClassAccessLevel(file_)); - printer->Indent(); - - // ----------------------------------------------------------------- - - printer->Print("#region Descriptor\r\n"); - // Embed the descriptor. We simply serialize the entire FileDescriptorProto - // and embed it as a byte array, which is parsed and built into real - // descriptors at initialization time. - FileDescriptorProto file_proto; - file_->CopyTo(&file_proto); - string file_data; - file_proto.SerializeToString(&file_data); - - printer->Print( - "public static pbd::FileDescriptor Descriptor {\r\n" - " get { return descriptor; }\r\n" - "}\r\n" - "private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom (\r\n" - " new byte[] {"); - printer->Indent(); - printer->Indent(); - printer->Indent(); - printer->Indent(); - - // Only write 20 bytes per line. - static const int kBytesPerLine = 20; - char buffer[3]; - for (int i = 0; i < file_data.size(); i++) { - if ((i % kBytesPerLine) == 0) { - printer->Print("\r\n"); - } - - // TODO(jonskeet): There must be a better way of doing this! - sprintf(buffer, "%02x", static_cast<uint8>(file_data[i])); - printer->Print("0x$val$, ", "val", buffer); - } - printer->Outdent(); - printer->Outdent(); - printer->Print("\r\n}, new pbd::FileDescriptor[] {\r\n"); - for (int i = 0; i < file_->dependency_count(); i++) { - printer->Print( - " $dependency$.Descriptor,\r\n", - "dependency", ClassName(file_->dependency(i))); - } - - printer->Print("});\r\n"); - - printer->Outdent(); - printer->Outdent(); - printer->Print("#endregion\r\n\r\n"); - - // ----------------------------------------------------------------- - - - - // Extensions must be generated in the outer class since they are values, - // not classes. - printer->Print("#region Extensions\r\n"); - for (int i = 0; i < file_->extension_count(); i++) { - ExtensionGenerator(file_->extension(i)).Generate(printer); - } - printer->Print("#endregion\r\n\r\n"); - - printer->Print("#region Static variables\r\n"); - // Static variables. - for (int i = 0; i < file_->message_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer); - } - printer->Print("#endregion\r\n\r\n"); - - // If we're not nesting classes, the class for the .proto file is done now - if (!file_->options().csharp_nest_classes()) { - printer->Outdent(); - printer->Print("}\r\n\r\n"); - } - - if (!file_->options().csharp_multiple_files()) { - printer->Print("#region Enums\r\n"); - for (int i = 0; i < file_->enum_type_count(); i++) { - EnumGenerator(file_->enum_type(i)).Generate(printer); - } - printer->Print("#endregion\r\n\r\n"); - printer->Print("#region Messages\r\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - MessageGenerator(file_->message_type(i)).Generate(printer); - } - printer->Print("#endregion\r\n\r\n"); - printer->Print("#region Services\r\n"); - for (int i = 0; i < file_->service_count(); i++) { - ServiceGenerator(file_->service(i)).Generate(printer); - } - printer->Print("#endregion\r\n"); - } - - // If we were nesting classes, we still need to finish the outer one at some point! - if (file_->options().csharp_nest_classes()) { - printer->Outdent(); - printer->Print("}\r\n\r\n"); - } - - if (!csharp_namespace_.empty()) { - printer->Outdent(); - printer->Print("}\r\n"); - } -} - -template<typename GeneratorClass, typename DescriptorClass> -static void GenerateSibling(const string& csharp_namespace, - const FileDescriptor* file, - const DescriptorClass* descriptor, - OutputDirectory* output_directory, - vector<string>* file_list) { - string filename = descriptor->name() + ".cs"; - file_list->push_back(filename); - - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename)); - io::Printer printer(output.get(), '$'); - - printer.Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\r\n" - "\r\n"); - - // Namespace aliases to avoid lines getting horribly long - printer.Print("using pb = global::Google.ProtocolBuffers;\r\n"); - printer.Print("using pbc = global::Google.ProtocolBuffers.Collections;\r\n"); - printer.Print("using pbd = global::Google.ProtocolBuffers.Descriptors;\r\n"); - printer.Print("using scg = global::System.Collections.Generic;\r\n"); - - if (!csharp_namespace.empty()) { - printer.Print( - "namespace $namespace$ {\r\n", - "namespace", csharp_namespace); - printer.Indent(); - } - printer.Print("\r\n"); - - - if (file->options().csharp_nest_classes()) { - printer.Print( - "$access$ static partial class $classname$ {\r\n\r\n", - "classname", FileClassName(file), - "access", ClassAccessLevel(file)); - printer.Indent(); - } - - GeneratorClass(descriptor).Generate(&printer); - - if (file->options().csharp_nest_classes()) { - printer.Outdent(); - printer.Print("}\r\n"); - } - - if (!csharp_namespace.empty()) { - printer.Outdent(); - printer.Print("}\r\n"); - } -} - -void FileGenerator::GenerateSiblings(OutputDirectory* output_directory, - vector<string>* file_list) { - if (file_->options().csharp_multiple_files()) { - for (int i = 0; i < file_->enum_type_count(); i++) { - GenerateSibling<EnumGenerator>(csharp_namespace_, - file_, - file_->enum_type(i), - output_directory, file_list); - } - for (int i = 0; i < file_->message_type_count(); i++) { - GenerateSibling<MessageGenerator>(csharp_namespace_, - file_, - file_->message_type(i), - output_directory, file_list); - } - for (int i = 0; i < file_->service_count(); i++) { - GenerateSibling<ServiceGenerator>(csharp_namespace_, - file_, - file_->service(i), - output_directory, file_list); - } - } -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_file.h b/src/google/protobuf/compiler/csharp/csharp_file.h deleted file mode 100644 index 3ca18a61..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_file.h +++ /dev/null @@ -1,78 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_FILE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FILE_H__ - -#include <string> -#include <vector> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - class FileDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } - namespace compiler { - class OutputDirectory; // code_generator.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -class FileGenerator { - public: - explicit FileGenerator(const FileDescriptor* file); - ~FileGenerator(); - - // Checks for problems that would otherwise lead to cryptic compile errors. - // Returns true if there are no problems, or writes an error description to - // the given string and returns false otherwise. - bool Validate(string* error); - - void Generate(io::Printer* printer); - - // If we aren't putting everything into one file, this will write all the - // files other than the outer file (i.e. one for each message, enum, and - // service type). - void GenerateSiblings(OutputDirectory* output_directory, - vector<string>* file_list); - - const string& csharp_namespace() { return csharp_namespace_; } - const string& classname() { return classname_; } - - private: - const FileDescriptor* file_; - string csharp_namespace_; - string classname_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FILE_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc deleted file mode 100644 index 7542ea09..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ /dev/null @@ -1,129 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/csharp/csharp_generator.h> -#include <google/protobuf/compiler/csharp/csharp_file.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -namespace { - -// Parses a set of comma-delimited name/value pairs, e.g.: -// "foo=bar,baz,qux=corge" -// parses to the pairs: -// ("foo", "bar"), ("baz", ""), ("qux", "corge") -void ParseOptions(const string& text, vector<pair<string, string> >* output) { - vector<string> parts; - SplitStringUsing(text, ",", &parts); - - for (int i = 0; i < parts.size(); i++) { - string::size_type equals_pos = parts[i].find_first_of('='); - pair<string, string> value; - if (equals_pos == string::npos) { - value.first = parts[i]; - value.second = ""; - } else { - value.first = parts[i].substr(0, equals_pos); - value.second = parts[i].substr(equals_pos + 1); - } - output->push_back(value); - } -} - -} // namespace - -CSharpGenerator::CSharpGenerator() {} -CSharpGenerator::~CSharpGenerator() {} - -bool CSharpGenerator::Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - vector<pair<string, string> > options; - ParseOptions(parameter, &options); - - // ----------------------------------------------------------------- - // parse generator options - - // Name a file where we will write a list of generated file names, one - // per line. - string output_list_file; - - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "output_list_file") { - output_list_file = options[i].second; - } else { - *error = "Unknown generator option: " + options[i].first; - return false; - } - } - - - // ----------------------------------------------------------------- - - - FileGenerator file_generator(file); - if (!file_generator.Validate(error)) { - return false; - } - - vector<string> all_files; - - string csharp_filename = file_generator.classname(); - csharp_filename += ".cs"; - all_files.push_back(csharp_filename); - - // Generate main C# file. - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(csharp_filename)); - io::Printer printer(output.get(), '$'); - file_generator.Generate(&printer); - - // Generate sibling files. - file_generator.GenerateSiblings(output_directory, &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 .csharp files being generated. - scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output( - output_directory->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$\r\n", "filename", all_files[i]); - } - } - - return true; -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h deleted file mode 100644 index 41f320a7..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_generator.h +++ /dev/null @@ -1,59 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Generates Java code for a given .proto file. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ - -#include <string> -#include <google/protobuf/compiler/code_generator.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -// CodeGenerator implementation which generates Java code. If you create your -// own protocol compiler binary and you want it to support Java output, you -// can do so by registering an instance of this CodeGenerator with the -// CommandLineInterface in your main() function. -class LIBPROTOC_EXPORT CSharpGenerator : public CodeGenerator { - public: - CSharpGenerator(); - ~CSharpGenerator(); - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CSharpGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc deleted file mode 100644 index 5747e5be..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ /dev/null @@ -1,246 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> - -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -const char kThickSeparator[] = - "// ===================================================================\r\n"; -const char kThinSeparator[] = - "// -------------------------------------------------------------------\r\n"; - -namespace { - -const char* kDefaultPackage = ""; - -const string& FieldName(const FieldDescriptor* field) { - // Groups are hacky: The name of the field is just the lower-cased name - // of the group type. In Java, though, we would like to retain the original - // capitalization of the type name. - if (field->type() == FieldDescriptor::TYPE_GROUP) { - return field->message_type()->name(); - } else { - return field->name(); - } -} - -string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { - string result; - // Note: I distrust ctype.h due to locales. - for (int i = 0; i < input.size(); i++) { - if ('a' <= input[i] && input[i] <= 'z') { - if (cap_next_letter) { - result += input[i] + ('A' - 'a'); - } else { - result += input[i]; - } - cap_next_letter = false; - } else if ('A' <= input[i] && input[i] <= 'Z') { - if (i == 0 && !cap_next_letter) { - // Force first letter to lower-case unless explicitly told to - // capitalize it. - result += input[i] + ('a' - 'A'); - } else { - // Capital letters after the first are left as-is. - result += input[i]; - } - cap_next_letter = false; - } else if ('0' <= input[i] && input[i] <= '9') { - result += input[i]; - cap_next_letter = true; - } else { - cap_next_letter = true; - } - } - return result; -} - -} // namespace - -string UnderscoresToCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), false); -} - -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), true); -} - -string UnderscoresToCapitalizedCamelCase(const MethodDescriptor* method) { - return UnderscoresToCamelCaseImpl(method->name(), true); -} - -string UnderscoresToCamelCase(const MethodDescriptor* method) { - return UnderscoresToCamelCaseImpl(method->name(), false); -} - -string StripProto(const string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - -string FileClassName(const FileDescriptor* file) { - if (file->options().has_csharp_file_classname()) { - return file->options().csharp_file_classname(); - } else { - string basename; - string::size_type last_slash = file->name().find_last_of('/'); - if (last_slash == string::npos) { - basename = file->name(); - } else { - basename = file->name().substr(last_slash + 1); - } - return UnderscoresToCamelCaseImpl(StripProto(basename), true); - } -} - -string FileCSharpNamespace(const FileDescriptor* file) { - if (file->options().has_csharp_namespace()) { - return file->options().csharp_namespace(); - } else { - string result = kDefaultPackage; - if (!file->package().empty()) { - if (!result.empty()) result += '.'; - result += file->package(); - } - return result; - } -} - -string ToCSharpName(const string& full_name, const FileDescriptor* file) { - string result; - if (!file->options().csharp_nest_classes()) { - result = FileCSharpNamespace(file); - } else { - result = ClassName(file); - } - if (!result.empty()) { - result += '.'; - } - string classname; - if (file->package().empty()) { - classname = full_name; - } else { - // Strip the proto package from full_name since we've replaced it with - // the C# namespace. - classname = full_name.substr(file->package().size() + 1); - } - result += StringReplace(classname, ".", ".Types.", true); - return "global::" + result; -} - -string ClassName(const FileDescriptor* descriptor) { - string result = FileCSharpNamespace(descriptor); - if (!result.empty()) result += '.'; - result += FileClassName(descriptor); - return "global::" + result; -} - -MappedType GetMappedType(FieldDescriptor::Type field_type) { - switch (field_type) { - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_SFIXED32: - return MAPPEDTYPE_INT; - - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SFIXED64: - return MAPPEDTYPE_LONG; - - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_FIXED32: - return MAPPEDTYPE_UINT; - - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_FIXED64: - return MAPPEDTYPE_ULONG; - - case FieldDescriptor::TYPE_FLOAT: - return MAPPEDTYPE_FLOAT; - - case FieldDescriptor::TYPE_DOUBLE: - return MAPPEDTYPE_DOUBLE; - - case FieldDescriptor::TYPE_BOOL: - return MAPPEDTYPE_BOOLEAN; - - case FieldDescriptor::TYPE_STRING: - return MAPPEDTYPE_STRING; - - case FieldDescriptor::TYPE_BYTES: - return MAPPEDTYPE_BYTES; - - case FieldDescriptor::TYPE_ENUM: - return MAPPEDTYPE_ENUM; - - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - return MAPPEDTYPE_MESSAGE; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return MAPPEDTYPE_INT; -} - -const char* MappedTypeName(MappedType type) { - switch (type) { - case MAPPEDTYPE_INT : return "int"; - case MAPPEDTYPE_LONG : return "long"; - case MAPPEDTYPE_UINT : return "uint"; - case MAPPEDTYPE_ULONG : return "ulong"; - case MAPPEDTYPE_FLOAT : return "float"; - case MAPPEDTYPE_DOUBLE : return "double"; - case MAPPEDTYPE_BOOLEAN: return "bool"; - case MAPPEDTYPE_STRING : return "string"; - case MAPPEDTYPE_BYTES : return "pb::ByteString"; - case MAPPEDTYPE_ENUM : return NULL; - case MAPPEDTYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // MappedTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -const char* ClassAccessLevel(const FileDescriptor* file) { - return file->options().csharp_public_classes() ? "public" : "internal"; -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h deleted file mode 100644 index 3f1becf2..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ /dev/null @@ -1,108 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ - -#include <string> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -// Commonly-used separator comments. Thick is a line of '=', thin is a line -// of '-'. -extern const char kThickSeparator[]; -extern const char kThinSeparator[]; - -// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes -// "fooBarBaz" or "FooBarBaz", respectively. -string UnderscoresToCamelCase(const FieldDescriptor* field); -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); - -// Similar, but for method names. (Typically, this merely has the effect -// of lower-casing the first letter of the name.) -string UnderscoresToCamelCase(const MethodDescriptor* method); -string UnderscoresToCapitalizedCamelCase(const MethodDescriptor* method); - -// Strips ".proto" or ".protodevel" from the end of a filename. -string StripProto(const string& filename); - -// Gets the unqualified class name for the file. Each .proto file becomes a -// single C# class, with extra (possibly nested) classes for messages, enums and services. -string FileClassName(const FileDescriptor* file); - -// Returns the file's C# namespace. -string FileCSharpNamespace(const FileDescriptor* file); - -// Converts the given fully-qualified name in the proto namespace to its -// fully-qualified name in the C# namespace, given that it is in the given -// file. -string ToCSharpName(const string& full_name, const FileDescriptor* file); - -// These return the fully-qualified class name corresponding to the given -// descriptor. -inline string ClassName(const Descriptor* descriptor) { - return ToCSharpName(descriptor->full_name(), descriptor->file()); -} -inline string ClassName(const EnumDescriptor* descriptor) { - return ToCSharpName(descriptor->full_name(), descriptor->file()); -} -inline string ClassName(const ServiceDescriptor* descriptor) { - return ToCSharpName(descriptor->full_name(), descriptor->file()); -} -string ClassName(const FileDescriptor* descriptor); - -enum MappedType { - MAPPEDTYPE_INT, - MAPPEDTYPE_LONG, - MAPPEDTYPE_UINT, - MAPPEDTYPE_ULONG, - MAPPEDTYPE_FLOAT, - MAPPEDTYPE_DOUBLE, - MAPPEDTYPE_BOOLEAN, - MAPPEDTYPE_STRING, - MAPPEDTYPE_BYTES, - MAPPEDTYPE_ENUM, - MAPPEDTYPE_MESSAGE -}; - -MappedType GetMappedType(FieldDescriptor::Type field_type); - -inline MappedType GetMappedType(const FieldDescriptor* field) { - return GetMappedType(field->type()); -} - -// Get the access level for generated classes: public or internal -const char* ClassAccessLevel(const FileDescriptor* file); - -// Get the class name for a built-in type (including ByteString). -// Returns NULL for enum and message types. -const char* MappedTypeName(MappedType type); - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc deleted file mode 100644 index 94ca2c4e..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ /dev/null @@ -1,709 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/csharp/csharp_message.h> -#include <google/protobuf/compiler/csharp/csharp_enum.h> -#include <google/protobuf/compiler/csharp/csharp_extension.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -using internal::WireFormat; - -namespace { - -void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { - // Print the field's proto-syntax definition as a comment. We don't want to - // print group bodies so we cut off after the first line. - string def = field->DebugString(); - printer->Print("// $def$\r\n", - "def", def.substr(0, def.find_first_of('\n'))); -} - -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -struct ExtensionRangeOrdering { - bool operator()(const Descriptor::ExtensionRange* a, - const Descriptor::ExtensionRange* b) const { - return a->start < b->start; - } -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor*[descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); - return fields; -} - -// Get an identifier that uniquely identifies this type within the file. -// This is used to declare static variables related to this type at the -// outermost file scope. -string UniqueFileScopeIdentifier(const Descriptor* descriptor) { - return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); -} - -// Returns true if the message type has any required fields. If it doesn't, -// we can optimize out calls to its isInitialized() method. -// -// already_seen is used to avoid checking the same type multiple times -// (and also to protect against recursion). -static bool HasRequiredFields( - const Descriptor* type, - hash_set<const Descriptor*>* already_seen) { - if (already_seen->count(type) > 0) { - // The type is already in cache. This means that either: - // a. The type has no required fields. - // b. We are in the midst of checking if the type has required fields, - // somewhere up the stack. In this case, we know that if the type - // has any required fields, they'll be found when we return to it, - // and the whole call to HasRequiredFields() will return true. - // Therefore, we don't have to check if this type has required fields - // here. - return false; - } - already_seen->insert(type); - - // If the type has extensions, an extension with message type could contain - // required fields, so we have to be conservative and assume such an - // extension exists. - if (type->extension_range_count() > 0) return true; - - for (int i = 0; i < type->field_count(); i++) { - const FieldDescriptor* field = type->field(i); - if (field->is_required()) { - return true; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (HasRequiredFields(field->message_type(), already_seen)) { - return true; - } - } - } - - return false; -} - -static bool HasRequiredFields(const Descriptor* type) { - hash_set<const Descriptor*> already_seen; - return HasRequiredFields(type, &already_seen); -} - -} // namespace - -// =================================================================== - -MessageGenerator::MessageGenerator(const Descriptor* descriptor) - : descriptor_(descriptor), - field_generators_(descriptor) { -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { - // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is - // used in the construction of descriptors, we have a tricky bootstrapping - // problem. To help control static initialization order, we make sure all - // descriptors and other static data that depends on them are members of - // the proto-descriptor class. This way, they will be initialized in - // a deterministic order. - - map<string, string> vars; - vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); - vars["index"] = SimpleItoa(descriptor_->index()); - vars["classname"] = ClassName(descriptor_); - if (descriptor_->containing_type() != NULL) { - vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type()); - } - if (!descriptor_->file()->options().csharp_nest_classes()) { - // We can only make these assembly-private since the classes that use them - // aren't nested. - vars["private"] = "internal "; - } else { - vars["private"] = "private "; - } - - // The descriptor for this type. - if (descriptor_->containing_type() == NULL) { - printer->Print(vars, - "$private$static readonly pbd::MessageDescriptor internal__$identifier$__Descriptor \r\n" - " = Descriptor.MessageTypes[$index$];\r\n"); - } else { - printer->Print(vars, - "$private$static readonly pbd::MessageDescriptor internal__$identifier$__Descriptor \r\n" - " = internal__$parent$__Descriptor.NestedTypes[$index$];\r\n"); - } - - // And the FieldAccessorTable. - printer->Print(vars, - "$private$static pb::FieldAccess.FieldAccessorTable<$classname$, $classname$.Builder> internal__$identifier$__FieldAccessorTable\r\n" - " = new pb::FieldAccess.FieldAccessorTable<$classname$, $classname$.Builder>(internal__$identifier$__Descriptor,\r\n" - " new string[] { "); - for (int i = 0; i < descriptor_->field_count(); i++) { - printer->Print( - "\"$field_name$\", ", - "field_name", - UnderscoresToCapitalizedCamelCase(descriptor_->field(i))); - } - printer->Print("});\r\n"); - - // Generate static members for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(descriptor_->nested_type(i)) - .GenerateStaticVariables(printer); - } -} - -void MessageGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - descriptor_->file()->options().csharp_multiple_files(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "$access$ sealed partial class $classname$ : pb::ExtendableMessage<$classname$, $classname$.Builder> {\r\n", - "classname", descriptor_->name(), - "access", ClassAccessLevel(descriptor_->file())); - } else { - printer->Print( - "$access$ sealed partial class $classname$ : pb::GeneratedMessage<$classname$, $classname$.Builder> {\r\n", - "classname", descriptor_->name(), - "access", ClassAccessLevel(descriptor_->file())); - } - printer->Indent(); - printer->Print( - // Must call Build() to make sure all lists are made read-only - "private static readonly $classname$ defaultInstance = new Builder().BuildPartial();\r\n" - "public static $classname$ DefaultInstance {\r\n" - " get { return defaultInstance; }\r\n" - "}\r\n" - "\r\n" - "public override $classname$ DefaultInstanceForType {\r\n" - " get { return defaultInstance; }\r\n" - "}\r\n" - "\r\n", - "classname", descriptor_->name()); - - printer->Print( - "protected override $classname$ ThisMessage {\r\n" - " get { return this; }\r\n" - "}\r\n\r\n", - "classname", descriptor_->name()); - - map<string, string> vars; - vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); - vars["fileclass"] = ClassName(descriptor_->file()); - vars["classname"] = descriptor_->name(); - printer->Print(vars, - "public static pbd::MessageDescriptor Descriptor {\r\n" - " get { return $fileclass$.internal__$identifier$__Descriptor; }\r\n" - "}\r\n" - "\r\n" - "protected override pb::FieldAccess.FieldAccessorTable<$classname$, $classname$.Builder> InternalFieldAccessors {\r\n" - " get { return $fileclass$.internal__$identifier$__FieldAccessorTable; }\r\n" - "}\r\n" - "\r\n"); - - // Extensions don't need to go in an extra nested type - for (int i = 0; i < descriptor_->extension_count(); i++) { - ExtensionGenerator(descriptor_->extension(i)).Generate(printer); - } - - if (descriptor_->enum_type_count() - + descriptor_->nested_type_count() - + descriptor_->extension_count() > 0) { - printer->Print("#region Nested types\r\n"); - printer->Print("public static class Types {\r\n"); - printer->Indent(); - // Nested types and extensions - 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); - } - - printer->Outdent(); - printer->Print("}\r\n"); - printer->Print("#endregion\r\n\r\n"); - } - - // Fields - for (int i = 0; i < descriptor_->field_count(); i++) { - PrintFieldComment(printer, descriptor_->field(i)); - field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); - printer->Print("\r\n"); - } - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - GenerateIsInitialized(printer); - GenerateMessageSerializationMethods(printer); - } - - GenerateParseFromMethods(printer); - GenerateBuilder(printer); -} - -// =================================================================== - -void MessageGenerator:: -GenerateMessageSerializationMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - vector<const Descriptor::ExtensionRange*> sorted_extensions; - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { - sorted_extensions.push_back(descriptor_->extension_range(i)); - } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeOrdering()); - - printer->Print("public override void WriteTo(pb::CodedOutputStream output) {\r\n"); - printer->Indent(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "pb::ExtendableMessage<$classname$, $classname$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);\r\n", - "classname", descriptor_->name()); - } - - // Merge the fields and the extension ranges, both sorted by field number. - for (int i = 0, j = 0; - i < descriptor_->field_count() || j < sorted_extensions.size(); - ) { - if (i == descriptor_->field_count()) { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } else if (j == sorted_extensions.size()) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } - } - - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "UnknownFields.WriteAsMessageSetTo(output);\r\n"); - } else { - printer->Print( - "UnknownFields.WriteTo(output);\r\n"); - } - - printer->Outdent(); - printer->Print( - "}\r\n" - "\r\n" - "private int memoizedSerializedSize = -1;\r\n" - "public override int SerializedSize {\r\n"); - printer->Indent(); - printer->Print("get {\r\n"); - printer->Indent(); - printer->Print( - "int size = memoizedSerializedSize;\r\n" - "if (size != -1) return size;\r\n" - "\r\n" - "size = 0;\r\n"); - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "size += ExtensionsSerializedSize;\r\n"); - } - - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += UnknownFields.SerializedSizeAsMessageSet;\r\n"); - } else { - printer->Print( - "size += UnknownFields.SerializedSize;\r\n"); - } - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " memoizedSerializedSize = size;\r\n" - " return size;\r\n" - " }\r\n" - "}\r\n" - "\r\n"); -} - -void MessageGenerator:: -GenerateParseFromMethods(io::Printer* printer) { - // Note: These are separate from GenerateMessageSerializationMethods() - // because they need to be generated even for messages that are optimized - // for code size. - printer->Print( - "public static $classname$ ParseFrom(pb::ByteString data) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(pb::ByteString data,\r\n" - " pb::ExtensionRegistry extensionRegistry) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry))\r\n" - " .BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(byte[] data) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(byte[] data,\r\n" - " pb::ExtensionRegistry extensionRegistry) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry))\r\n" - " .BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(global::System.IO.Stream input) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(\r\n" - " global::System.IO.Stream input,\r\n" - " pb::ExtensionRegistry extensionRegistry) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry))\r\n" - " .BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(pb::CodedInputStream input) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\r\n" - "}\r\n" - "public static $classname$ ParseFrom(pb::CodedInputStream input,\r\n" - " pb::ExtensionRegistry extensionRegistry) {\r\n" - " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry))\r\n" - " .BuildParsed();\r\n" - "}\r\n" - "\r\n", - "classname", ClassName(descriptor_)); -} - -void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field) { - field_generators_.get(field).GenerateSerializationCode(printer); -} - -void MessageGenerator::GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range) { - printer->Print( - "extensionWriter.WriteUntil($end$, output);\r\n", - "end", SimpleItoa(range->end)); -} - -// =================================================================== - -void MessageGenerator::GenerateBuilder(io::Printer* printer) { - printer->Print( - "public static Builder CreateBuilder() { return new Builder(); }\r\n" - "public override Builder CreateBuilderForType() { return new Builder(); }\r\n" - "public static Builder CreateBuilder($classname$ prototype) {\r\n" - " return (Builder) new Builder().MergeFrom(prototype);\r\n" - "}\r\n" - "\r\n", - "classname", ClassName(descriptor_)); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "$access$ sealed partial class Builder : pb::ExtendableBuilder<$classname$, $classname$.Builder> {\r\n", - "classname", ClassName(descriptor_), - "access", ClassAccessLevel(descriptor_->file())); - } else { - printer->Print( - "$access$ sealed partial class Builder : pb::GeneratedBuilder<$classname$, Builder> {\r\n", - "classname", ClassName(descriptor_), - "access", ClassAccessLevel(descriptor_->file())); - } - - printer->Indent(); - - printer->Print( - "protected override Builder ThisBuilder {\r\n" - " get { return this; }\r\n" - "}\r\n\r\n"); - - GenerateCommonBuilderMethods(printer); - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - GenerateBuilderParsingMethods(printer); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - printer->Print("\r\n"); - PrintFieldComment(printer, descriptor_->field(i)); - field_generators_.get(descriptor_->field(i)) - .GenerateBuilderMembers(printer); - } - - printer->Outdent(); - printer->Print("}\r\n"); - printer->Outdent(); - printer->Print("}\r\n\r\n"); -} - -// =================================================================== - -void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { - printer->Print( - "// Construct using $classname$.CreateBuilder()\r\n" - "$access$ Builder() {}\r\n" - "\r\n" - "$classname$ result = new $classname$();\r\n" - "\r\n" - "protected override $classname$ MessageBeingBuilt {\r\n" - " get { return result; }\r\n" - "}\r\n" - "\r\n" - "public override Builder Clear() {\r\n" - " result = new $classname$();\r\n" - " return this;\r\n" - "}\r\n" - "\r\n" - "public override Builder Clone() {\r\n" - " return new Builder().MergeFrom(result);\r\n" - "}\r\n" - "\r\n" - "public override pbd::MessageDescriptor DescriptorForType {\r\n" - " get { return $classname$.Descriptor; }\r\n" - "}\r\n" - "\r\n" - "public override $classname$ DefaultInstanceForType {\r\n" - " get { return $classname$.DefaultInstance; }\r\n" - "}\r\n" - "\r\n", - "classname", ClassName(descriptor_), - "access", ClassAccessLevel(descriptor_->file())); - - // ----------------------------------------------------------------- - - printer->Print( - "public override $classname$ BuildPartial() {\r\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); - } - - printer->Outdent(); - printer->Print( - " $classname$ returnMe = result;\r\n" - " result = null;\r\n" - " return returnMe;\r\n" - "}\r\n" - "\r\n", - "classname", ClassName(descriptor_)); - - // ----------------------------------------------------------------- - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - printer->Print( - /* - "protected override Builder MergeFrom(CodedInputStream data, ExtensionRegistry extensionRegistry) {\r\n" - " return MergeFrom(data, extensionRegistry);\r\n" - "}\r\n" - "\r\n"*/ - "public override Builder MergeFrom(pb::IMessage other) {\r\n" - " if (other is $classname$) {\r\n" - " return MergeFrom(($classname$) other);\r\n" - " } else {\r\n" - " base.MergeFrom(other);\r\n" - " return this;\r\n" - " }\r\n" - "}\r\n" - "\r\n" - "public override Builder MergeFrom($classname$ other) {\r\n" - // Optimization: If other is the default instance, we know none of its - // fields are set so we can skip the merge. - " if (other == $classname$.DefaultInstance) return this;\r\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer); - } - - printer->Outdent(); - printer->Print( - " this.MergeUnknownFields(other.UnknownFields);\r\n" - " return this;\r\n" - "}\r\n" - "\r\n"); - } -} - -// =================================================================== - -void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print( - "public override Builder MergeFrom(pb::CodedInputStream input) {\r\n" - " return MergeFrom(input, pb::ExtensionRegistry.Empty);\r\n" - "}\r\n" - "\r\n" - "public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\r\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - printer->Print( - "pb::UnknownFieldSet.Builder unknownFields =\r\n" - " pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\r\n" - "while (true) {\r\n"); - printer->Indent(); - - printer->Print( - "uint tag = input.ReadTag();\r\n" - "switch (tag) {\r\n"); - printer->Indent(); - - printer->Print( - "case 0:\r\n" // zero signals EOF / limit reached - " this.UnknownFields = unknownFields.Build();\r\n" - " return this;\r\n" - "default: {\r\n" - " if (!ParseUnknownField(input, unknownFields,\r\n" - " extensionRegistry, tag)) {\r\n" - " this.UnknownFields = unknownFields.Build();\r\n" - " return this;\r\n" // it's an endgroup tag - " }\r\n" - " break;\r\n" - "}\r\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32 tag = WireFormat::MakeTag(field->number(), - WireFormat::WireTypeForFieldType(field->type())); - - printer->Print( - "case $tag$: {\r\n", - "tag", SimpleItoa(tag)); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCode(printer); - - printer->Outdent(); - printer->Print( - " break;\r\n" - "}\r\n"); - } - - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\r\n" // switch (tag) - " }\r\n" // while (true) - "}\r\n" - "\r\n"); -} - -// =================================================================== - -void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { - printer->Print("public override bool IsInitialized {\r\n"); - printer->Indent(); - printer->Print("get {\r\n"); - printer->Indent(); - - // 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. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_required()) { - printer->Print( - "if (!has$name$) return false;\r\n", - "name", UnderscoresToCapitalizedCamelCase(field)); - } - } - - // Now check that all embedded messages are initialized. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - HasRequiredFields(field->message_type())) { - switch (field->label()) { - case FieldDescriptor::LABEL_REQUIRED: - printer->Print( - "if (!$name$.IsInitialized) return false;\r\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_OPTIONAL: - printer->Print( - "if (Has$name$) {\r\n" - " if (!$name$.IsInitialized) return false;\r\n" - "}\r\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_REPEATED: - printer->Print( - "foreach ($type$ element in $name$List) {\r\n" - " if (!element.IsInitialized) return false;\r\n" - "}\r\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - } - } - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "if (!ExtensionsAreInitialized) return false;\r\n"); - } - - printer->Outdent(); - printer->Print( - " return true;\r\n" - "}\r\n"); - printer->Outdent(); - printer->Print( - "}\r\n" - "\r\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h deleted file mode 100644 index aff3e6f2..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ /dev/null @@ -1,77 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/csharp/csharp_field.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -class MessageGenerator { - public: - explicit MessageGenerator(const Descriptor* descriptor); - ~MessageGenerator(); - - // All static variables have to be declared at the top-level of the file - // so that we can control initialization order, which is important for - // DescriptorProto bootstrapping to work. - void GenerateStaticVariables(io::Printer* printer); - - // Generate the class itself. - void Generate(io::Printer* printer); - - private: - void GenerateMessageSerializationMethods(io::Printer* printer); - void GenerateParseFromMethods(io::Printer* printer); - void GenerateSerializeOneField(io::Printer* printer, - const FieldDescriptor* field); - void GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range); - - void GenerateBuilder(io::Printer* printer); - void GenerateCommonBuilderMethods(io::Printer* printer); - void GenerateBuilderParsingMethods(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer); - - const Descriptor* descriptor_; - FieldGeneratorMap field_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc deleted file mode 100644 index 3981becb..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/csharp/csharp_message_field.h> -#include <google/protobuf/compiler/csharp/csharp_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 csharp { - -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, - map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = ClassName(descriptor->message_type()); - (*variables)["group_or_message"] = - (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? - "Group" : "Message"; -} - -} // namespace - -// =================================================================== - -MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -MessageFieldGenerator::~MessageFieldGenerator() {} - -void MessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private bool has$capitalized_name$;\r\n" - "private $type$ $name$_ = $type$.DefaultInstance;\r\n" - "public bool Has$capitalized_name$ {\r\n" - " get { return has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {\r\n" - " get { return $name$_; }\r\n" - "}\r\n"); -} - -void MessageFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - printer->Print(variables_, - "public bool Has$capitalized_name$ {\r\n" - " get { return result.Has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {\r\n" - " get { return result.$capitalized_name$; }\r\n" - " set { Set$capitalized_name$(value); }\r\n" - "}\r\n" - "public Builder Set$capitalized_name$($type$ value) {\r\n" - " result.has$capitalized_name$ = true;\r\n" - " result.$name$_ = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Set$capitalized_name$($type$.Builder builderForValue) {\r\n" - " result.has$capitalized_name$ = true;\r\n" - " result.$name$_ = builderForValue.Build();\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Merge$capitalized_name$($type$ value) {\r\n" - " if (result.Has$capitalized_name$ &&\r\n" - " result.$name$_ != $type$.DefaultInstance) {\r\n" - " result.$name$_ =\r\n" - " $type$.CreateBuilder(result.$name$_).MergeFrom(value).BuildPartial();\r\n" - " } else {\r\n" - " result.$name$_ = value;\r\n" - " }\r\n" - " result.has$capitalized_name$ = true;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.has$capitalized_name$ = false;\r\n" - " result.$name$_ = $type$.DefaultInstance;\r\n" - " return this;\r\n" - "}\r\n"); -} - -void MessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.Has$capitalized_name$) {\r\n" - " Merge$capitalized_name$(other.$capitalized_name$);\r\n" - "}\r\n"); -} - -void MessageFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do for singular fields. -} - -void MessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = $type$.CreateBuilder();\r\n" - "if (Has$capitalized_name$) {\r\n" - " subBuilder.MergeFrom($capitalized_name$);\r\n" - "}\r\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.ReadGroup($number$, subBuilder, extensionRegistry);\r\n"); - } else { - printer->Print(variables_, - "input.ReadMessage(subBuilder, extensionRegistry);\r\n"); - } - - printer->Print(variables_, - "$capitalized_name$ = subBuilder.BuildPartial();\r\n"); -} - -void MessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " output.Write$group_or_message$($number$, $capitalized_name$);\r\n" - "}\r\n"); -} - -void MessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " size += pb::CodedOutputStream.Compute$group_or_message$Size($number$, $capitalized_name$);\r\n" - "}\r\n"); -} - -// =================================================================== - -RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} - -void RepeatedMessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private pbc::PopsicleList<$type$> $name$_ = new pbc::PopsicleList<$type$>();\r\n" - "public scg::IList<$type$> $capitalized_name$List {\r\n" - " get { return $name$_; } \r\n" // Will be unmodifiable by the time it's exposed - "}\r\n" - "public int $capitalized_name$Count\r\n" - " { get { return $name$_.Count; }\r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return $name$_ [index];\r\n" - "}\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - printer->Print(variables_, - // Note: We can return the original list here, because we - // make it read-only when we build. - "public scg::IList<$type$> $capitalized_name$List {\r\n" - " get { return result.$name$_; }\r\n" - "}\r\n" - "public int $capitalized_name$Count {\r\n" - " get { return result.$capitalized_name$Count; }\r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return result.Get$capitalized_name$(index);\r\n" - "}\r\n" - "public Builder Set$capitalized_name$(int index, $type$ value) {\r\n" - " result.$name$_[index] = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Set$capitalized_name$(int index, $type$.Builder builderForValue) {\r\n" - " result.$name$_[index] = builderForValue.Build();\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Add$capitalized_name$($type$ value) {\r\n" - " result.$name$_.Add(value);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Add$capitalized_name$($type$.Builder builderForValue) {\r\n" - " result.$name$_.Add(builderForValue.Build());\r\n" - " return this;\r\n" - "}\r\n" - "public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n" - " base.AddRange(values, result.$name$_);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.$name$_.Clear();\r\n" - " return this;\r\n" - "}\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.$name$_.Count != 0) {\r\n" - " base.AddRange(other.$name$_, result.$name$_);\r\n" - "}\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "result.$name$_.MakeReadOnly();\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = $type$.CreateBuilder();\r\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.ReadGroup($number$, subBuilder, extensionRegistry);\r\n"); - } else { - printer->Print(variables_, - "input.ReadMessage(subBuilder, extensionRegistry);\r\n"); - } - - printer->Print(variables_, - "Add$capitalized_name$(subBuilder.BuildPartial());\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " output.Write$group_or_message$($number$, element);\r\n" - "}\r\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " size += pb::CodedOutputStream.Compute$group_or_message$Size($number$, element);\r\n" - "}\r\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h deleted file mode 100644 index 30b1d76b..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ /dev/null @@ -1,83 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/csharp/csharp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -class MessageFieldGenerator : public FieldGenerator { - public: - explicit MessageFieldGenerator(const FieldDescriptor* descriptor); - ~MessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); -}; - -class RepeatedMessageFieldGenerator : public FieldGenerator { - public: - explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedMessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc deleted file mode 100644 index 64b2bb52..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ /dev/null @@ -1,327 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -namespace { - -const char* GetCapitalizedType(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32 : return "Int32" ; - case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; - case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; - case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; - case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; - case FieldDescriptor::TYPE_INT64 : return "Int64" ; - case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; - case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; - case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; - case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; - case FieldDescriptor::TYPE_FLOAT : return "Float" ; - case FieldDescriptor::TYPE_DOUBLE : return "Double" ; - case FieldDescriptor::TYPE_BOOL : return "Bool" ; - case FieldDescriptor::TYPE_STRING : return "String" ; - case FieldDescriptor::TYPE_BYTES : return "Bytes" ; - case FieldDescriptor::TYPE_ENUM : return "Enum" ; - case FieldDescriptor::TYPE_GROUP : return "Group" ; - case FieldDescriptor::TYPE_MESSAGE : return "Message" ; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -bool AllPrintableAscii(const string& text) { - // Cannot use isprint() because it's locale-specific. :( - for (int i = 0; i < text.size(); i++) { - if ((text[i] < 0x20) || text[i] >= 0x7F) { - return false; - } - } - return true; -} - -string DefaultValue(const FieldDescriptor* field) { - // Switch on cpp_type since we need to know which default_value_* method - // of FieldDescriptor to call. - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return SimpleItoa(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - return SimpleItoa(field->default_value_uint32()); - case FieldDescriptor::CPPTYPE_INT64: - return SimpleItoa(field->default_value_int64()) + "L"; - case FieldDescriptor::CPPTYPE_UINT64: - return SimpleItoa(field->default_value_uint64()) + - "UL"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()) + "D"; - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field->default_value_float()) + "F"; - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_STRING: { - bool isBytes = field->type() == FieldDescriptor::TYPE_BYTES; - - if (!isBytes && AllPrintableAscii(field->default_value_string())) { - // All chars are ASCII and printable. In this case CEscape() works - // fine (it will only escape quotes and backslashes). - // Note: If this "optimization" is removed, DescriptorProtos will - // no longer be able to initialize itself due to bootstrapping - // problems. - return "\"" + CEscape(field->default_value_string()) + "\""; - } - - if (isBytes && !field->has_default_value()) { - return "pb::ByteString.Empty"; - } - - // Escaping strings correctly for Java and generating efficient - // initializers for ByteStrings are both tricky. We can sidestep the - // whole problem by just grabbing the default value from the descriptor. - return strings::Substitute( - "(($0) $1.Descriptor.Fields[$2].DefaultValue)", - isBytes ? "pb::ByteString" : "string", - ClassName(field->containing_type()), field->index()); - } - - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; -} - -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = MappedTypeName(GetMappedType(descriptor)); - (*variables)["default"] = DefaultValue(descriptor); - (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); -} - -} // namespace - -// =================================================================== - -PrimitiveFieldGenerator:: -PrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} - -void PrimitiveFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private bool has$capitalized_name$;\r\n" - "private $type$ $name$_ = $default$;\r\n" - "public bool Has$capitalized_name$ {\r\n" - " get { return has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {\r\n" - " get { return $name$_; }\r\n" - "}\r\n"); -} - -void PrimitiveFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - printer->Print(variables_, - "public bool Has$capitalized_name$ {\r\n" - " get { return result.Has$capitalized_name$; }\r\n" - "}\r\n" - "public $type$ $capitalized_name$ {\r\n" - " get { return result.$capitalized_name$; }\r\n" - " set { Set$capitalized_name$(value); }\r\n" - "}\r\n" - "public Builder Set$capitalized_name$($type$ value) {\r\n" - " result.has$capitalized_name$ = true;\r\n" - " result.$name$_ = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.has$capitalized_name$ = false;\r\n" - " result.$name$_ = $default$;\r\n" - " return this;\r\n" - "}\r\n"); -} - -void PrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.Has$capitalized_name$) {\r\n" - " $capitalized_name$ = other.$capitalized_name$;\r\n" - "}\r\n"); -} - -void PrimitiveFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for primitive types. -} - -void PrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$capitalized_name$ = input.Read$capitalized_type$();\r\n"); -} - -void PrimitiveFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " output.Write$capitalized_type$($number$, $capitalized_name$);\r\n" - "}\r\n"); -} - -void PrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (Has$capitalized_name$) {\r\n" - " size += pb::CodedOutputStream.Compute$capitalized_type$Size($number$, $capitalized_name$);\r\n" - "}\r\n"); -} - -// =================================================================== - -RepeatedPrimitiveFieldGenerator:: -RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private pbc::PopsicleList<$type$> $name$_ = new pbc::PopsicleList<$type$>();\r\n" - "public scg::IList<$type$> $capitalized_name$List {\r\n" - " get { return $name$_; } \r\n" // Will be unmodifiable by the time it's exposed - "}\r\n" - "public int $capitalized_name$Count {\r\n" - " get { return $name$_.Count; }\r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return $name$_[index];\r\n" - "}\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - printer->Print(variables_, - // Note: We can return the original list here, because we - // make it read-only when we build. - "public scg::IList<$type$> $capitalized_name$List {\r\n" - " get { return result.$name$_; }\r\n" - "}\r\n" - "public int $capitalized_name$Count {\r\n" - " get { return result.$capitalized_name$Count; }\r\n" - "}\r\n" - "public $type$ Get$capitalized_name$(int index) {\r\n" - " return result.Get$capitalized_name$(index);\r\n" - "}\r\n" - "public Builder Set$capitalized_name$(int index, $type$ value) {\r\n" - " result.$name$_[index] = value;\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Add$capitalized_name$($type$ value) {\r\n" - " result.$name$_.Add(value);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder AddRange$capitalized_name$(scg::IEnumerable<$type$> values) {\r\n" - " base.AddRange(values, result.$name$_);\r\n" - " return this;\r\n" - "}\r\n" - "public Builder Clear$capitalized_name$() {\r\n" - " result.$name$_.Clear();\r\n" - " return this;\r\n" - "}\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.$name$_.Count != 0) {\r\n" - " base.AddRange(other.$name$_, result.$name$_);\r\n" - "}\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "result.$name$_.MakeReadOnly();\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "Add$capitalized_name$(input.Read$capitalized_type$());\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " output.Write$capitalized_type$($number$, element);\r\n" - "}\r\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "foreach ($type$ element in $capitalized_name$List) {\r\n" - " size += pb::CodedOutputStream\r\n" - " .Compute$capitalized_type$Size($number$, element);\r\n" - "}\r\n"); -} - - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h deleted file mode 100644 index feef810b..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h +++ /dev/null @@ -1,81 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/csharp/csharp_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -class PrimitiveFieldGenerator : public FieldGenerator { - public: - explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~PrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); -}; - -class RepeatedPrimitiveFieldGenerator : public FieldGenerator { - public: - explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedPrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_service.cc b/src/google/protobuf/compiler/csharp/csharp_service.cc deleted file mode 100644 index 60c38f3c..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_service.cc +++ /dev/null @@ -1,213 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/csharp/csharp_service.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor) - : descriptor_(descriptor) {} - -ServiceGenerator::~ServiceGenerator() {} - -void ServiceGenerator::Generate(io::Printer* printer) { - printer->Print( - "public abstract class $classname$ : pb::IService {\r\n", - "classname", descriptor_->name()); - printer->Indent(); - - // Generate abstract method declarations. - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["name"] = UnderscoresToCapitalizedCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "public abstract void $name$(\r\n" - " pb::IRpcController controller,\r\n" - " $input$ request,\r\n" - " global::System.Action<$output$> done);\r\n"); - } - - // Generate Descriptor and DescriptorForType. - printer->Print( - "\r\n" - "public static pbd::ServiceDescriptor Descriptor {\r\n" - " get { return $file$.Descriptor.Services[$index$]; }\r\n" - "}\r\n" - "public pbd::ServiceDescriptor DescriptorForType {\r\n" - " get { return Descriptor; }\r\n" - "}\r\n", - "file", ClassName(descriptor_->file()), - "index", SimpleItoa(descriptor_->index())); - - // Generate more stuff. - GenerateCallMethod(printer); - GenerateGetPrototype(REQUEST, printer); - GenerateGetPrototype(RESPONSE, printer); - GenerateStub(printer); - - printer->Outdent(); - printer->Print("}\r\n\r\n"); -} - -void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { - printer->Print( - "\r\n" - "public void CallMethod(\r\n" - " pbd::MethodDescriptor method,\r\n" - " pb::IRpcController controller,\r\n" - " pb::IMessage request,\r\n" - " global::System.Action<pb::IMessage> done) {\r\n" - " if (method.Service != Descriptor) {\r\n" - " throw new global::System.ArgumentException(\r\n" - " \"Service.CallMethod() given method descriptor for wrong \" +\r\n" - " \"service type.\");\r\n" - " }\r\n" - " switch(method.Index) {\r\n"); - printer->Indent(); - printer->Indent(); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["method"] = UnderscoresToCapitalizedCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "case $index$:\r\n" - " this.$method$(controller, ($input$)request,\r\n" - " pb::RpcUtil.SpecializeCallback<$output$>(\r\n" - " done));\r\n" - " return;\r\n"); - } - - printer->Print( - "default:\r\n" - " throw new global::System.InvalidOperationException(\"Can't get here.\");\r\n"); - - printer->Outdent(); - printer->Outdent(); - - printer->Print( - " }\r\n" - "}\r\n" - "\r\n"); -} - -void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, - io::Printer* printer) { - printer->Print( - "public pb::IMessage Get$request_or_response$Prototype(pbd::MethodDescriptor method) {\r\n" - " if (method.Service != Descriptor) {\r\n" - " throw new global::System.ArgumentException(\r\n" - " \"Service.Get$request_or_response$Prototype() given method \" +\r\n" - " \"descriptor for wrong service type.\");\r\n" - " }\r\n" - " switch(method.Index) {\r\n", - "request_or_response", (which == REQUEST) ? "Request" : "Response"); - printer->Indent(); - printer->Indent(); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["type"] = ClassName( - (which == REQUEST) ? method->input_type() : method->output_type()); - printer->Print(vars, - "case $index$:\r\n" - " return $type$.DefaultInstance;\r\n"); - } - - printer->Print( - "default:\r\n" - " throw new global::System.ArgumentException(\"Can't get here.\");\r\n"); - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\r\n" - "}\r\n" - "\r\n"); -} - -void ServiceGenerator::GenerateStub(io::Printer* printer) { - printer->Print( - "public static Stub CreateStub(\r\n" - " pb::IRpcChannel channel) {\r\n" - " return new Stub(channel);\r\n" - "}\r\n" - "\r\n" - "public class Stub : $classname$ {\r\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - printer->Print( - "internal Stub(pb::IRpcChannel channel) {\r\n" - " this.channel = channel;\r\n" - "}\r\n" - "\r\n" - "private readonly pb::IRpcChannel channel;\r\n" - "\r\n" - "public pb::IRpcChannel Channel {\r\n" - " get { return channel; }\r\n" - "}\r\n"); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["method"] = UnderscoresToCapitalizedCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "\r\n" - "public override void $method$(\r\n" - " pb::IRpcController controller,\r\n" - " $input$ request,\r\n" - " global::System.Action<$output$> done) {\r\n" - " channel.CallMethod(\r\n" - " Descriptor.Methods[$index$],\r\n" - " controller,\r\n" - " request,\r\n" - " $output$.DefaultInstance,\r\n" - " pb::RpcUtil.GeneralizeCallback<$output$, $output$.Builder>(done, $output$.DefaultInstance));\r\n" - "}\r\n"); - } - - printer->Outdent(); - printer->Print("}\r\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_service.h b/src/google/protobuf/compiler/csharp/csharp_service.h deleted file mode 100644 index 524c4801..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_service.h +++ /dev/null @@ -1,67 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jonskeet@google.com (Jon Skeet) -// Following the Java generator by kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_SERVICE_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_SERVICE_H__ - -#include <map> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace csharp { - -class ServiceGenerator { - public: - explicit ServiceGenerator(const ServiceDescriptor* descriptor); - ~ServiceGenerator(); - - void Generate(io::Printer* printer); - - private: - // Generate the implementation of Service.callMethod(). - void GenerateCallMethod(io::Printer* printer); - - // Generate the implementations of Service.get{Request,Response}Prototype(). - enum RequestOrResponse { REQUEST, RESPONSE }; - void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); - - // Generate a stub implementation of the service. - void GenerateStub(io::Printer* printer); - - const ServiceDescriptor* descriptor_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf - -#endif // NET_PROTO2_COMPILER_CSHARP_SERVICE_H__ -} // namespace google diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc deleted file mode 100644 index 62089cdc..00000000 --- a/src/google/protobuf/compiler/importer.cc +++ /dev/null @@ -1,406 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifdef _MSC_VER -#include <io.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> - -#include <algorithm> - -#include <google/protobuf/compiler/importer.h> - -#include <google/protobuf/compiler/parser.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { - -#ifdef _WIN32 -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#endif - -MultiFileErrorCollector::~MultiFileErrorCollector() {} - -// This class serves two purposes: -// - It implements the ErrorCollector interface (used by Tokenizer and Parser) -// in terms of MultiFileErrorCollector, using a particular filename. -// - It lets us check if any errors have occurred. -class SourceTreeDescriptorDatabase::SingleFileErrorCollector - : public io::ErrorCollector { - public: - SingleFileErrorCollector(const string& filename, - MultiFileErrorCollector* multi_file_error_collector) - : filename_(filename), - multi_file_error_collector_(multi_file_error_collector), - had_errors_(false) {} - ~SingleFileErrorCollector() {} - - bool had_errors() { return had_errors_; } - - // implements ErrorCollector --------------------------------------- - void AddError(int line, int column, const string& message) { - if (multi_file_error_collector_ != NULL) { - multi_file_error_collector_->AddError(filename_, line, column, message); - } - had_errors_ = true; - } - - private: - string filename_; - MultiFileErrorCollector* multi_file_error_collector_; - bool had_errors_; -}; - -// =================================================================== - -SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase( - SourceTree* source_tree) - : source_tree_(source_tree), - error_collector_(NULL), - using_validation_error_collector_(false), - validation_error_collector_(this) {} - -SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} - -bool SourceTreeDescriptorDatabase::FindFileByName( - const string& filename, FileDescriptorProto* output) { - scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename)); - if (input == NULL) { - if (error_collector_ != NULL) { - error_collector_->AddError(filename, -1, 0, "File not found."); - } - return false; - } - - // Set up the tokenizer and parser. - SingleFileErrorCollector file_error_collector(filename, error_collector_); - io::Tokenizer tokenizer(input.get(), &file_error_collector); - - Parser parser; - if (error_collector_ != NULL) { - parser.RecordErrorsTo(&file_error_collector); - } - if (using_validation_error_collector_) { - parser.RecordSourceLocationsTo(&source_locations_); - } - - // Parse it. - output->set_name(filename); - return parser.Parse(&tokenizer, output) && - !file_error_collector.had_errors(); -} - -bool SourceTreeDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, FileDescriptorProto* output) { - return false; -} - -bool SourceTreeDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, int field_number, - FileDescriptorProto* output) { - return false; -} - -// ------------------------------------------------------------------- - -SourceTreeDescriptorDatabase::ValidationErrorCollector:: -ValidationErrorCollector(SourceTreeDescriptorDatabase* owner) - : owner_(owner) {} - -SourceTreeDescriptorDatabase::ValidationErrorCollector:: -~ValidationErrorCollector() {} - -void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError( - const string& filename, - const string& element_name, - const Message* descriptor, - ErrorLocation location, - const string& message) { - if (owner_->error_collector_ == NULL) return; - - int line, column; - owner_->source_locations_.Find(descriptor, location, &line, &column); - owner_->error_collector_->AddError(filename, line, column, message); -} - -// =================================================================== - -Importer::Importer(SourceTree* source_tree, - MultiFileErrorCollector* error_collector) - : database_(source_tree), - pool_(&database_, database_.GetValidationErrorCollector()) { - database_.RecordErrorsTo(error_collector); -} - -Importer::~Importer() {} - -const FileDescriptor* Importer::Import(const string& filename) { - return pool_.FindFileByName(filename); -} - -// =================================================================== - -SourceTree::~SourceTree() {} - -DiskSourceTree::DiskSourceTree() {} - -DiskSourceTree::~DiskSourceTree() {} - -static inline char LastChar(const string& str) { - return str[str.size() - 1]; -} - -// Given a path, returns an equivalent path with these changes: -// - On Windows, any backslashes are replaced with forward slashes. -// - Any instances of the directory "." are removed. -// - Any consecutive '/'s are collapsed into a single slash. -// Note that the resulting string may be empty. -// -// TODO(kenton): It would be nice to handle "..", e.g. so that we can figure -// out that "foo/bar.proto" is inside "baz/../foo". However, if baz is a -// symlink or doesn't exist, then things get complicated, and we can't -// actually determine this without investigating the filesystem, probably -// in non-portable ways. So, we punt. -// -// TODO(kenton): It would be nice to use realpath() here except that it -// resolves symbolic links. This could cause problems if people place -// symbolic links in their source tree. For example, if you executed: -// protoc --proto_path=foo foo/bar/baz.proto -// then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize -// to a path which does not appear to be under foo, and thus the compiler -// will complain that baz.proto is not inside the --proto_path. -static string CanonicalizePath(string path) { -#ifdef _WIN32 - // The Win32 API accepts forward slashes as a path delimiter even though - // backslashes are standard. Let's avoid confusion and use only forward - // slashes. - path = StringReplace(path, "\\", "/", true); -#endif - - vector<string> parts; - vector<string> canonical_parts; - SplitStringUsing(path, "/", &parts); // Note: Removes empty parts. - for (int i = 0; i < parts.size(); i++) { - if (parts[i] == ".") { - // Ignore. - } else { - canonical_parts.push_back(parts[i]); - } - } - string result = JoinStrings(canonical_parts, "/"); - if (!path.empty() && path[0] == '/') { - // Restore leading slash. - result = '/' + result; - } - if (!path.empty() && LastChar(path) == '/' && - !result.empty() && LastChar(result) != '/') { - // Restore trailing slash. - result += '/'; - } - return result; -} - -static inline bool ContainsParentReference(const string& path) { - return path == ".." || - HasPrefixString(path, "../") || - HasSuffixString(path, "/..") || - path.find("/../") != string::npos; -} - -// Maps a file from an old location to a new one. Typically, old_prefix is -// a virtual path and new_prefix is its corresponding disk path. Returns -// false if the filename did not start with old_prefix, otherwise replaces -// old_prefix with new_prefix and stores the result in *result. Examples: -// string result; -// assert(ApplyMapping("foo/bar", "", "baz", &result)); -// assert(result == "baz/foo/bar"); -// -// assert(ApplyMapping("foo/bar", "foo", "baz", &result)); -// assert(result == "baz/bar"); -// -// assert(ApplyMapping("foo", "foo", "bar", &result)); -// assert(result == "bar"); -// -// assert(!ApplyMapping("foo/bar", "baz", "qux", &result)); -// assert(!ApplyMapping("foo/bar", "baz", "qux", &result)); -// assert(!ApplyMapping("foobar", "foo", "baz", &result)); -static bool ApplyMapping(const string& filename, - const string& old_prefix, - const string& new_prefix, - string* result) { - if (old_prefix.empty()) { - // old_prefix matches any relative path. - if (ContainsParentReference(filename)) { - // We do not allow the file name to use "..". - return false; - } - if (HasPrefixString(filename, "/")) { - // This is an absolute path, so it isn't matched by the empty string. - return false; - } - result->assign(new_prefix); - if (!result->empty()) result->push_back('/'); - result->append(filename); - return true; - } else if (HasPrefixString(filename, old_prefix)) { - // old_prefix is a prefix of the filename. Is it the whole filename? - if (filename.size() == old_prefix.size()) { - // Yep, it's an exact match. - *result = new_prefix; - return true; - } else { - // Not an exact match. Is the next character a '/'? Otherwise, - // this isn't actually a match at all. E.g. the prefix "foo/bar" - // does not match the filename "foo/barbaz". - int after_prefix_start = -1; - if (filename[old_prefix.size()] == '/') { - after_prefix_start = old_prefix.size() + 1; - } else if (filename[old_prefix.size() - 1] == '/') { - // old_prefix is never empty, and canonicalized paths never have - // consecutive '/' characters. - after_prefix_start = old_prefix.size(); - } - if (after_prefix_start != -1) { - // Yep. So the prefixes are directories and the filename is a file - // inside them. - string after_prefix = filename.substr(after_prefix_start); - if (ContainsParentReference(after_prefix)) { - // We do not allow the file name to use "..". - return false; - } - result->assign(new_prefix); - if (!result->empty()) result->push_back('/'); - result->append(after_prefix); - return true; - } - } - } - - return false; -} - -void DiskSourceTree::MapPath(const string& virtual_path, - const string& disk_path) { - mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path))); -} - -DiskSourceTree::DiskFileToVirtualFileResult -DiskSourceTree::DiskFileToVirtualFile( - const string& disk_file, - string* virtual_file, - string* shadowing_disk_file) { - int mapping_index = -1; - string canonical_disk_file = CanonicalizePath(disk_file); - - for (int i = 0; i < mappings_.size(); i++) { - // Apply the mapping in reverse. - if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path, - mappings_[i].virtual_path, virtual_file)) { - // Success. - mapping_index = i; - break; - } - } - - if (mapping_index == -1) { - return NO_MAPPING; - } - - // Iterate through all mappings with higher precedence and verify that none - // of them map this file to some other existing file. - for (int i = 0; i < mapping_index; i++) { - if (ApplyMapping(*virtual_file, mappings_[i].virtual_path, - mappings_[i].disk_path, shadowing_disk_file)) { - if (access(shadowing_disk_file->c_str(), F_OK) >= 0) { - // File exists. - return SHADOWED; - } - } - } - shadowing_disk_file->clear(); - - // Verify that we can open the file. Note that this also has the side-effect - // of verifying that we are not canonicalizing away any non-existent - // directories. - scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file)); - if (stream == NULL) { - return CANNOT_OPEN; - } - - return SUCCESS; -} - -io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) { - if (filename != CanonicalizePath(filename) || - ContainsParentReference(filename)) { - // We do not allow importing of paths containing things like ".." or - // consecutive slashes since the compiler expects files to be uniquely - // identified by file name. - return NULL; - } - - for (int i = 0; i < mappings_.size(); i++) { - string disk_file; - if (ApplyMapping(filename, mappings_[i].virtual_path, - mappings_[i].disk_path, &disk_file)) { - io::ZeroCopyInputStream* stream = OpenDiskFile(disk_file); - if (stream != NULL) return stream; - - if (errno == EACCES) { - // The file exists but is not readable. - // TODO(kenton): Find a way to report this more nicely. - GOOGLE_LOG(WARNING) << "Read access is denied for file: " << disk_file; - return NULL; - } - } - } - - return NULL; -} - -io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( - const string& filename) { - int file_descriptor; - do { - file_descriptor = open(filename.c_str(), O_RDONLY); - } while (file_descriptor < 0 && errno == EINTR); - if (file_descriptor >= 0) { - io::FileInputStream* result = new io::FileInputStream(file_descriptor); - result->SetCloseOnDelete(true); - return result; - } else { - return NULL; - } -} - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h deleted file mode 100644 index 2e3d0df4..00000000 --- a/src/google/protobuf/compiler/importer.h +++ /dev/null @@ -1,279 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file is the public interface to the .proto file parser. - -#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ -#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ - -#include <string> -#include <vector> -#include <set> -#include <utility> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/compiler/parser.h> - -namespace google { -namespace protobuf { - -namespace io { class ZeroCopyInputStream; } - -namespace compiler { - -// Defined in this file. -class Importer; -class MultiFileErrorCollector; -class SourceTree; -class DiskSourceTree; - -// TODO(kenton): Move all SourceTree stuff to a separate file? - -// An implementation of DescriptorDatabase which loads files from a SourceTree -// and parses them. -// -// Note: This class is not thread-safe since it maintains a table of source -// code locations for error reporting. However, when a DescriptorPool wraps -// a DescriptorDatabase, it uses mutex locking to make sure only one method -// of the database is called at a time, even if the DescriptorPool is used -// from multiple threads. Therefore, there is only a problem if you create -// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase -// and use them from multiple threads. -// -// Note: This class does not implement FindFileContainingSymbol() or -// FindFileContainingExtension(); these will always return false. -class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase { - public: - SourceTreeDescriptorDatabase(SourceTree* source_tree); - ~SourceTreeDescriptorDatabase(); - - // Instructs the SourceTreeDescriptorDatabase to report any parse errors - // to the given MultiFileErrorCollector. This should be called before - // parsing. error_collector must remain valid until either this method - // is called again or the SourceTreeDescriptorDatabase is destroyed. - void RecordErrorsTo(MultiFileErrorCollector* error_collector) { - error_collector_ = error_collector; - } - - // Gets a DescriptorPool::ErrorCollector which records errors to the - // MultiFileErrorCollector specified with RecordErrorsTo(). This collector - // has the ability to determine exact line and column numbers of errors - // from the information given to it by the DescriptorPool. - DescriptorPool::ErrorCollector* GetValidationErrorCollector() { - using_validation_error_collector_ = true; - return &validation_error_collector_; - } - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - - private: - class SingleFileErrorCollector; - - SourceTree* source_tree_; - MultiFileErrorCollector* error_collector_; - - class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector { - public: - ValidationErrorCollector(SourceTreeDescriptorDatabase* owner); - ~ValidationErrorCollector(); - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, - const string& element_name, - const Message* descriptor, - ErrorLocation location, - const string& message); - - private: - SourceTreeDescriptorDatabase* owner_; - }; - friend class ValidationErrorCollector; - - bool using_validation_error_collector_; - SourceLocationTable source_locations_; - ValidationErrorCollector validation_error_collector_; -}; - -// Simple interface for parsing .proto files. This wraps the process -// of opening the file, parsing it with a Parser, recursively parsing all its -// imports, and then cross-linking the results to produce a FileDescriptor. -// -// This is really just a thin wrapper around SourceTreeDescriptorDatabase. -// You may find that SourceTreeDescriptorDatabase is more flexible. -// -// TODO(kenton): I feel like this class is not well-named. -class LIBPROTOBUF_EXPORT Importer { - public: - Importer(SourceTree* source_tree, - MultiFileErrorCollector* error_collector); - ~Importer(); - - // Import the given file and build a FileDescriptor representing it. If - // the file is already in the DescriptorPool, the existing FileDescriptor - // will be returned. The FileDescriptor is property of the DescriptorPool, - // and will remain valid until it is destroyed. If any errors occur, they - // will be reported using the error collector and Import() will return NULL. - // - // A particular Importer object will only report errors for a particular - // file once. All future attempts to import the same file will return NULL - // without reporting any errors. The idea is that you might want to import - // a lot of files without seeing the same errors over and over again. If - // you want to see errors for the same files repeatedly, you can use a - // separate Importer object to import each one (but use the same - // DescriptorPool so that they can be cross-linked). - const FileDescriptor* Import(const string& filename); - - // The DescriptorPool in which all imported FileDescriptors and their - // contents are stored. - inline const DescriptorPool* pool() const { - return &pool_; - } - - private: - SourceTreeDescriptorDatabase database_; - DescriptorPool pool_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer); -}; - -// If the importer encounters problems while trying to import the proto files, -// it reports them to a MultiFileErrorCollector. -class LIBPROTOBUF_EXPORT MultiFileErrorCollector { - public: - inline MultiFileErrorCollector() {} - virtual ~MultiFileErrorCollector(); - - // Line and column numbers are zero-based. A line number of -1 indicates - // an error with the entire file (e.g. "not found"). - virtual void AddError(const string& filename, int line, int column, - const string& message) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector); -}; - -// Abstract interface which represents a directory tree containing proto files. -// Used by the default implementation of Importer to resolve import statements -// Most users will probably want to use the DiskSourceTree implementation, -// below. -class LIBPROTOBUF_EXPORT SourceTree { - public: - inline SourceTree() {} - virtual ~SourceTree(); - - // Open the given file and return a stream that reads it, or NULL if not - // found. The caller takes ownership of the returned object. The filename - // must be a path relative to the root of the source tree and must not - // contain "." or ".." components. - virtual io::ZeroCopyInputStream* Open(const string& filename) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree); -}; - -// An implementation of SourceTree which loads files from locations on disk. -// Multiple mappings can be set up to map locations in the DiskSourceTree to -// locations in the physical filesystem. -class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree { - public: - DiskSourceTree(); - ~DiskSourceTree(); - - // Map a path on disk to a location in the SourceTree. The path may be - // either a file or a directory. If it is a directory, the entire tree - // under it will be mapped to the given virtual location. To map a directory - // to the root of the source tree, pass an empty string for virtual_path. - // - // If multiple mapped paths apply when opening a file, they will be searched - // in order. For example, if you do: - // MapPath("bar", "foo/bar"); - // MapPath("", "baz"); - // and then you do: - // Open("bar/qux"); - // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux, - // returning the first one that opens successfuly. - // - // disk_path may be an absolute path or relative to the current directory, - // just like a path you'd pass to open(). - void MapPath(const string& virtual_path, const string& disk_path); - - // Return type for DiskFileToVirtualFile(). - enum DiskFileToVirtualFileResult { - SUCCESS, - SHADOWED, - CANNOT_OPEN, - NO_MAPPING - }; - - // Given a path to a file on disk, find a virtual path mapping to that - // file. The first mapping created with MapPath() whose disk_path contains - // the filename is used. However, that virtual path may not actually be - // usable to open the given file. Possible return values are: - // * SUCCESS: The mapping was found. *virtual_file is filled in so that - // calling Open(*virtual_file) will open the file named by disk_file. - // * SHADOWED: A mapping was found, but using Open() to open this virtual - // path will end up returning some different file. This is because some - // other mapping with a higher precedence also matches this virtual path - // and maps it to a different file that exists on disk. *virtual_file - // is filled in as it would be in the SUCCESS case. *shadowing_disk_file - // is filled in with the disk path of the file which would be opened if - // you were to call Open(*virtual_file). - // * CANNOT_OPEN: The mapping was found and was not shadowed, but the - // file specified cannot be opened. When this value is returned, - // errno will indicate the reason the file cannot be opened. *virtual_file - // will be set to the virtual path as in the SUCCESS case, even though - // it is not useful. - // * NO_MAPPING: Indicates that no mapping was found which contains this - // file. - DiskFileToVirtualFileResult - DiskFileToVirtualFile(const string& disk_file, - string* virtual_file, - string* shadowing_disk_file); - - // implements SourceTree ------------------------------------------- - io::ZeroCopyInputStream* Open(const string& filename); - - private: - struct Mapping { - string virtual_path; - string disk_path; - - inline Mapping(const string& virtual_path, const string& disk_path) - : virtual_path(virtual_path), disk_path(disk_path) {} - }; - vector<Mapping> mappings_; - - // Like Open() but given the actual on-disk path. - io::ZeroCopyInputStream* OpenDiskFile(const string& filename); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree); -}; - -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__ diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc deleted file mode 100644 index 55c52e47..00000000 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ /dev/null @@ -1,546 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/stubs/hash.h> - -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> - -#include <google/protobuf/stubs/map-util.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/file.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace compiler { - -namespace { - -#define EXPECT_SUBSTRING(needle, haystack) \ - EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack)) - -class MockErrorCollector : public MultiFileErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", - filename, line, column, message); - } -}; - -// ------------------------------------------------------------------- - -// A dummy implementation of SourceTree backed by a simple map. -class MockSourceTree : public SourceTree { - public: - MockSourceTree() {} - ~MockSourceTree() {} - - void AddFile(const string& name, const char* contents) { - files_[name] = contents; - } - - // implements SourceTree ------------------------------------------- - io::ZeroCopyInputStream* Open(const string& filename) { - const char* contents = FindPtrOrNull(files_, filename); - if (contents == NULL) { - return NULL; - } else { - return new io::ArrayInputStream(contents, strlen(contents)); - } - } - - private: - hash_map<string, const char*> files_; -}; - -// =================================================================== - -class ImporterTest : public testing::Test { - protected: - ImporterTest() - : importer_(&source_tree_, &error_collector_) {} - - void AddFile(const string& filename, const char* text) { - source_tree_.AddFile(filename, text); - } - - // Return the collected error text - string error() const { return error_collector_.text_; } - - MockErrorCollector error_collector_; - MockSourceTree source_tree_; - Importer importer_; -}; - -TEST_F(ImporterTest, Import) { - // Test normal importing. - AddFile("foo.proto", - "syntax = \"proto2\";\n" - "message Foo {}\n"); - - const FileDescriptor* file = importer_.Import("foo.proto"); - EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->message_type_count()); - EXPECT_EQ("Foo", file->message_type(0)->name()); - - // Importing again should return same object. - EXPECT_EQ(file, importer_.Import("foo.proto")); -} - -TEST_F(ImporterTest, ImportNested) { - // Test that importing a file which imports another file works. - AddFile("foo.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n" - "message Foo {\n" - " optional Bar bar = 1;\n" - "}\n"); - AddFile("bar.proto", - "syntax = \"proto2\";\n" - "message Bar {}\n"); - - // Note that both files are actually parsed by the first call to Import() - // here, since foo.proto imports bar.proto. The second call just returns - // the same ProtoFile for bar.proto which was constructed while importing - // foo.proto. We test that this is the case below by checking that bar - // is among foo's dependencies (by pointer). - const FileDescriptor* foo = importer_.Import("foo.proto"); - const FileDescriptor* bar = importer_.Import("bar.proto"); - EXPECT_EQ("", error_collector_.text_); - ASSERT_TRUE(foo != NULL); - ASSERT_TRUE(bar != NULL); - - // Check that foo's dependency is the same object as bar. - ASSERT_EQ(1, foo->dependency_count()); - EXPECT_EQ(bar, foo->dependency(0)); - - // Check that foo properly cross-links bar. - ASSERT_EQ(1, foo->message_type_count()); - ASSERT_EQ(1, bar->message_type_count()); - ASSERT_EQ(1, foo->message_type(0)->field_count()); - ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, - foo->message_type(0)->field(0)->type()); - EXPECT_EQ(bar->message_type(0), - foo->message_type(0)->field(0)->message_type()); -} - -TEST_F(ImporterTest, FileNotFound) { - // Error: Parsing a file that doesn't exist. - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); - EXPECT_EQ( - "foo.proto:-1:0: File not found.\n", - error_collector_.text_); -} - -TEST_F(ImporterTest, ImportNotFound) { - // Error: Importing a file that doesn't exist. - AddFile("foo.proto", - "syntax = \"proto2\";\n" - "import \"bar.proto\";\n"); - - EXPECT_TRUE(importer_.Import("foo.proto") == NULL); - EXPECT_EQ( - "bar.proto:-1:0: File not found.\n" - "foo.proto:-1:0: Import \"bar.proto\" was not found or had errors.\n", - error_collector_.text_); -} - -TEST_F(ImporterTest, RecursiveImport) { - // Error: Recursive import. - AddFile("recursive1.proto", - "syntax = \"proto2\";\n" - "import \"recursive2.proto\";\n"); - AddFile("recursive2.proto", - "syntax = \"proto2\";\n" - "import \"recursive1.proto\";\n"); - - EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL); - EXPECT_EQ( - "recursive1.proto:-1:0: File recursively imports itself: recursive1.proto " - "-> recursive2.proto -> recursive1.proto\n" - "recursive2.proto:-1:0: Import \"recursive1.proto\" was not found " - "or had errors.\n" - "recursive1.proto:-1:0: Import \"recursive2.proto\" was not found " - "or had errors.\n", - error_collector_.text_); -} - -// TODO(sanjay): The MapField tests below more properly belong in -// descriptor_unittest, but are more convenient to test here. -TEST_F(ImporterTest, MapFieldValid) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Item {\n" - " required string key = 1;\n" - "}\n" - "message Map {\n" - " repeated Item items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - const FileDescriptor* file = importer_.Import("map.proto"); - ASSERT_TRUE(file != NULL) << error_collector_.text_; - EXPECT_EQ("", error_collector_.text_); - - // Check that Map::items points to Item::key - const Descriptor* item_type = file->FindMessageTypeByName("Item"); - ASSERT_TRUE(item_type != NULL); - const Descriptor* map_type = file->FindMessageTypeByName("Map"); - ASSERT_TRUE(map_type != NULL); - const FieldDescriptor* key_field = item_type->FindFieldByName("key"); - ASSERT_TRUE(key_field != NULL); - const FieldDescriptor* items_field = map_type->FindFieldByName("items"); - ASSERT_TRUE(items_field != NULL); - EXPECT_EQ(items_field->experimental_map_key(), key_field); -} - -TEST_F(ImporterTest, MapFieldNotRepeated) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Item {\n" - " required string key = 1;\n" - "}\n" - "message Map {\n" - " required Item items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("only allowed for repeated fields", error()); -} - -TEST_F(ImporterTest, MapFieldNotMessageType) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Map {\n" - " repeated int32 items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("only allowed for fields with a message type", error()); -} - -TEST_F(ImporterTest, MapFieldTypeNotFound) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Map {\n" - " repeated Unknown items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("not defined", error()); -} - -TEST_F(ImporterTest, MapFieldKeyNotFound) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Item {\n" - " required string key = 1;\n" - "}\n" - "message Map {\n" - " repeated Item items = 1 [experimental_map_key = \"badkey\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("Could not find field", error()); -} - -TEST_F(ImporterTest, MapFieldKeyRepeated) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message Item {\n" - " repeated string key = 1;\n" - "}\n" - "message Map {\n" - " repeated Item items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("must not name a repeated field", error()); -} - -TEST_F(ImporterTest, MapFieldKeyNotScalar) { - AddFile( - "map.proto", - "syntax = \"proto2\";\n" - "message ItemKey { }\n" - "message Item {\n" - " required ItemKey key = 1;\n" - "}\n" - "message Map {\n" - " repeated Item items = 1 [experimental_map_key = \"key\"];\n" - "}\n" - ); - EXPECT_TRUE(importer_.Import("map.proto") == NULL); - EXPECT_SUBSTRING("must name a scalar or string", error()); -} - -// =================================================================== - -class DiskSourceTreeTest : public testing::Test { - protected: - virtual void SetUp() { - dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1"); - dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); - - for (int i = 0; i < dirnames_.size(); i++) { - if (File::Exists(dirnames_[i])) { - File::DeleteRecursively(dirnames_[i], NULL, NULL); - } - GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE)); - } - } - - virtual void TearDown() { - for (int i = 0; i < dirnames_.size(); i++) { - File::DeleteRecursively(dirnames_[i], NULL, NULL); - } - } - - void AddFile(const string& filename, const char* contents) { - File::WriteStringToFileOrDie(contents, filename); - } - - void AddSubdir(const string& dirname) { - GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE)); - } - - void ExpectFileContents(const string& filename, - const char* expected_contents) { - scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); - - ASSERT_FALSE(input == NULL); - - // Read all the data from the file. - string file_contents; - const void* data; - int size; - while (input->Next(&data, &size)) { - file_contents.append(reinterpret_cast<const char*>(data), size); - } - - EXPECT_EQ(expected_contents, file_contents); - } - - void ExpectFileNotFound(const string& filename) { - scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); - EXPECT_TRUE(input == NULL); - } - - DiskSourceTree source_tree_; - - // Paths of two on-disk directories to use during the test. - vector<string> dirnames_; -}; - -TEST_F(DiskSourceTreeTest, MapRoot) { - // Test opening a file in a directory that is mapped to the root of the - // source tree. - AddFile(dirnames_[0] + "/foo", "Hello World!"); - source_tree_.MapPath("", dirnames_[0]); - - ExpectFileContents("foo", "Hello World!"); - ExpectFileNotFound("bar"); -} - -TEST_F(DiskSourceTreeTest, MapDirectory) { - // Test opening a file in a directory that is mapped to somewhere other - // than the root of the source tree. - - AddFile(dirnames_[0] + "/foo", "Hello World!"); - source_tree_.MapPath("baz", dirnames_[0]); - - ExpectFileContents("baz/foo", "Hello World!"); - ExpectFileNotFound("baz/bar"); - ExpectFileNotFound("foo"); - ExpectFileNotFound("bar"); - - // Non-canonical file names should not work. - ExpectFileNotFound("baz//foo"); - ExpectFileNotFound("baz/../baz/foo"); - ExpectFileNotFound("baz/./foo"); - ExpectFileNotFound("baz/foo/"); -} - -TEST_F(DiskSourceTreeTest, NoParent) { - // Test that we cannot open files in a parent of a mapped directory. - - AddFile(dirnames_[0] + "/foo", "Hello World!"); - AddSubdir(dirnames_[0] + "/bar"); - AddFile(dirnames_[0] + "/bar/baz", "Blah."); - source_tree_.MapPath("", dirnames_[0] + "/bar"); - - ExpectFileContents("baz", "Blah."); - ExpectFileNotFound("../foo"); - ExpectFileNotFound("../bar/baz"); -} - -TEST_F(DiskSourceTreeTest, MapFile) { - // Test opening a file that is mapped directly into the source tree. - - AddFile(dirnames_[0] + "/foo", "Hello World!"); - source_tree_.MapPath("foo", dirnames_[0] + "/foo"); - - ExpectFileContents("foo", "Hello World!"); - ExpectFileNotFound("bar"); -} - -TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { - // Test mapping and searching multiple directories. - - AddFile(dirnames_[0] + "/foo", "Hello World!"); - AddFile(dirnames_[1] + "/foo", "This file should be hidden."); - AddFile(dirnames_[1] + "/bar", "Goodbye World!"); - source_tree_.MapPath("", dirnames_[0]); - source_tree_.MapPath("", dirnames_[1]); - - ExpectFileContents("foo", "Hello World!"); - ExpectFileContents("bar", "Goodbye World!"); - ExpectFileNotFound("baz"); -} - -TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { - // Test that directories are always searched in order, even when a latter - // directory is more-specific than a former one. - - // Create the "bar" directory so we can put a file in it. - ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(), - DEFAULT_FILE_MODE)); - - // Add files and map paths. - AddFile(dirnames_[0] + "/bar/foo", "Hello World!"); - AddFile(dirnames_[1] + "/foo", "This file should be hidden."); - source_tree_.MapPath("", dirnames_[0]); - source_tree_.MapPath("bar", dirnames_[1]); - - // Check. - ExpectFileContents("bar/foo", "Hello World!"); -} - -TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) { - // Test DiskFileToVirtualFile. - - AddFile(dirnames_[0] + "/foo", "Hello World!"); - AddFile(dirnames_[1] + "/foo", "This file should be hidden."); - source_tree_.MapPath("bar", dirnames_[0]); - source_tree_.MapPath("bar", dirnames_[1]); - - string virtual_file; - string shadowing_disk_file; - - EXPECT_EQ(DiskSourceTree::NO_MAPPING, - source_tree_.DiskFileToVirtualFile( - "/foo", &virtual_file, &shadowing_disk_file)); - - EXPECT_EQ(DiskSourceTree::SHADOWED, - source_tree_.DiskFileToVirtualFile( - dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("bar/foo", virtual_file); - EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file); - - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("bar/baz", virtual_file); - - EXPECT_EQ(DiskSourceTree::SUCCESS, - source_tree_.DiskFileToVirtualFile( - dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("bar/foo", virtual_file); -} - -TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) { - // Test handling of "..", ".", etc. in DiskFileToVirtualFile(). - - source_tree_.MapPath("dir1", ".."); - source_tree_.MapPath("dir2", "../../foo"); - source_tree_.MapPath("dir3", "./foo/bar/."); - source_tree_.MapPath("dir4", "."); - source_tree_.MapPath("", "/qux"); - source_tree_.MapPath("dir5", "/quux/"); - - string virtual_file; - string shadowing_disk_file; - - // "../.." should not be considered to be under "..". - EXPECT_EQ(DiskSourceTree::NO_MAPPING, - source_tree_.DiskFileToVirtualFile( - "../../baz", &virtual_file, &shadowing_disk_file)); - - // But "../baz" should be. - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "../baz", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("dir1/baz", virtual_file); - - // "../../foo/baz" is under "../../foo". - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "../../foo/baz", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("dir2/baz", virtual_file); - - // "foo/./bar/baz" is under "./foo/bar/.". - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "foo/bar/baz", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("dir3/baz", virtual_file); - - // "bar" is under ".". - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "bar", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("dir4/bar", virtual_file); - - // "/qux/baz" is under "/qux". - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "/qux/baz", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("baz", virtual_file); - - // "/quux/bar" is under "/quux". - EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, - source_tree_.DiskFileToVirtualFile( - "/quux/bar", &virtual_file, &shadowing_disk_file)); - EXPECT_EQ("dir5/bar", virtual_file); -} - -} // namespace - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc deleted file mode 100644 index aa15a468..00000000 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ /dev/null @@ -1,189 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/java/java_enum.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) - : descriptor_(descriptor) { - for (int i = 0; i < descriptor_->value_count(); i++) { - const EnumValueDescriptor* value = descriptor_->value(i); - const EnumValueDescriptor* canonical_value = - descriptor_->FindValueByNumber(value->number()); - - if (value == canonical_value) { - canonical_values_.push_back(value); - } else { - Alias alias; - alias.value = value; - alias.canonical_value = canonical_value; - aliases_.push_back(alias); - } - } -} - -EnumGenerator::~EnumGenerator() {} - -void EnumGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - descriptor_->file()->options().java_multiple_files(); - printer->Print( - "public $static$ enum $classname$ {\n", - "static", is_own_file ? "" : "static", - "classname", descriptor_->name()); - printer->Indent(); - - for (int i = 0; i < canonical_values_.size(); i++) { - map<string, string> vars; - vars["name"] = canonical_values_[i]->name(); - vars["index"] = SimpleItoa(canonical_values_[i]->index()); - vars["number"] = SimpleItoa(canonical_values_[i]->number()); - printer->Print(vars, - "$name$($index$, $number$),\n"); - } - - printer->Print( - ";\n" - "\n"); - - // ----------------------------------------------------------------- - - for (int i = 0; i < aliases_.size(); i++) { - map<string, string> vars; - vars["classname"] = descriptor_->name(); - vars["name"] = aliases_[i].value->name(); - vars["canonical_name"] = aliases_[i].canonical_value->name(); - printer->Print(vars, - "public static final $classname$ $name$ = $canonical_name$;\n"); - } - - // ----------------------------------------------------------------- - - printer->Print( - "\n" - "public final int getNumber() { return value; }\n" - "\n" - "public static $classname$ valueOf(int value) {\n" - " switch (value) {\n", - "classname", descriptor_->name()); - printer->Indent(); - printer->Indent(); - - for (int i = 0; i < canonical_values_.size(); i++) { - printer->Print( - "case $number$: return $name$;\n", - "name", canonical_values_[i]->name(), - "number", SimpleItoa(canonical_values_[i]->number())); - } - - printer->Outdent(); - printer->Outdent(); - printer->Print( - " default: return null;\n" - " }\n" - "}\n" - "\n"); - - // ----------------------------------------------------------------- - // Reflection - - printer->Print( - "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n" - " getValueDescriptor() {\n" - " return getDescriptor().getValues().get(index);\n" - "}\n" - "public final com.google.protobuf.Descriptors.EnumDescriptor\n" - " getDescriptorForType() {\n" - " return getDescriptor();\n" - "}\n" - "public static final com.google.protobuf.Descriptors.EnumDescriptor\n" - " getDescriptor() {\n"); - - // TODO(kenton): Cache statically? Note that we can't access descriptors - // at module init time because it wouldn't work with descriptor.proto, but - // we can cache the value the first time getDescriptor() is called. - if (descriptor_->containing_type() == NULL) { - printer->Print( - " return $file$.getDescriptor().getEnumTypes().get($index$);\n", - "file", ClassName(descriptor_->file()), - "index", SimpleItoa(descriptor_->index())); - } else { - printer->Print( - " return $parent$.getDescriptor().getEnumTypes().get($index$);\n", - "parent", ClassName(descriptor_->containing_type()), - "index", SimpleItoa(descriptor_->index())); - } - - printer->Print( - "}\n" - "\n" - "private static final $classname$[] VALUES = {\n" - " ", - "classname", descriptor_->name()); - - for (int i = 0; i < descriptor_->value_count(); i++) { - printer->Print("$name$, ", - "name", descriptor_->value(i)->name()); - } - - printer->Print( - "\n" - "};\n" - "public static $classname$ valueOf(\n" - " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n" - " if (desc.getType() != getDescriptor()) {\n" - " throw new java.lang.IllegalArgumentException(\n" - " \"EnumValueDescriptor is not for this type.\");\n" - " }\n" - " return VALUES[desc.getIndex()];\n" - "}\n", - "classname", descriptor_->name()); - - // ----------------------------------------------------------------- - - printer->Print( - "private final int index;\n" - "private final int value;\n" - "private $classname$(int index, int value) {\n" - " this.index = index;\n" - " this.value = value;\n" - "}\n", - "classname", descriptor_->name()); - - printer->Outdent(); - printer->Print("}\n\n"); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h deleted file mode 100644 index f0a16036..00000000 --- a/src/google/protobuf/compiler/java/java_enum.h +++ /dev/null @@ -1,70 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ - -#include <string> -#include <vector> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class EnumGenerator { - public: - explicit EnumGenerator(const EnumDescriptor* descriptor); - ~EnumGenerator(); - - void Generate(io::Printer* printer); - - private: - const EnumDescriptor* descriptor_; - - // The proto language allows multiple enum constants to have the same numeric - // value. Java, however, does not allow multiple enum constants to be - // considered equivalent. We treat the first defined constant for any - // given numeric value as "canonical" and the rest as aliases of that - // canonical value. - vector<const EnumValueDescriptor*> canonical_values_; - - struct Alias { - const EnumValueDescriptor* value; - const EnumValueDescriptor* canonical_value; - }; - vector<Alias> aliases_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc deleted file mode 100644 index cb80c4b8..00000000 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ /dev/null @@ -1,264 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/java/java_enum_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/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -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, - map<string, string>* variables) { - const EnumValueDescriptor* default_value; - default_value = descriptor->default_value_enum(); - - string type = ClassName(descriptor->enum_type()); - - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = type; - (*variables)["default"] = type + "." + default_value->name(); -} - -} // namespace - -// =================================================================== - -EnumFieldGenerator:: -EnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -EnumFieldGenerator::~EnumFieldGenerator() {} - -void EnumFieldGenerator:: -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"); -} - -void EnumFieldGenerator:: -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" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = value;\n" - " return this;\n" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n" - " result.$name$_ = $default$;\n" - " return this;\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " set$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for enum types. -} - -void EnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "int rawValue = input.readEnum();\n" - "$type$ value = $type$.valueOf(rawValue);\n" - "if (value == null) {\n" - " unknownFields.mergeVarintField($number$, rawValue);\n" - "} else {\n" - " set$capitalized_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" - "}\n"); -} - -void EnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeEnumSize($number$, get$capitalized_name$().getNumber());\n" - "}\n"); -} - -string EnumFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->enum_type()); -} - -// =================================================================== - -RepeatedEnumFieldGenerator:: -RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); -} - -RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} - -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" - " 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" - " return $name$_.get(index);\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - 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" - " result.$name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.add(value);\n" - " return this;\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" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.addAll(other.$name$_);\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -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"); -} - -void RepeatedEnumFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "int rawValue = input.readEnum();\n" - "$type$ value = $type$.valueOf(rawValue);\n" - "if (value == null) {\n" - " unknownFields.mergeVarintField($number$, rawValue);\n" - "} else {\n" - " add$capitalized_name$(value);\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.writeEnum($number$, element.getNumber());\n" - "}\n"); -} - -void RepeatedEnumFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeEnumSize($number$, element.getNumber());\n" - "}\n"); -} - -string RepeatedEnumFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->enum_type()); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h deleted file mode 100644 index 473ba617..00000000 --- a/src/google/protobuf/compiler/java/java_enum_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/java/java_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -class EnumFieldGenerator : public FieldGenerator { - public: - explicit EnumFieldGenerator(const FieldDescriptor* descriptor); - ~EnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); -}; - -class RepeatedEnumFieldGenerator : public FieldGenerator { - public: - explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedEnumFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc deleted file mode 100644 index 1b637fab..00000000 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ /dev/null @@ -1,82 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_extension.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) - : descriptor_(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["index"] = SimpleItoa(descriptor_->index()); - - JavaType java_type = GetJavaType(descriptor_); - string singular_type; - switch (java_type) { - case JAVATYPE_MESSAGE: - vars["type"] = ClassName(descriptor_->message_type()); - break; - case JAVATYPE_ENUM: - vars["type"] = ClassName(descriptor_->enum_type()); - break; - default: - vars["type"] = BoxedPrimitiveTypeName(java_type); - break; - } - - if (descriptor_->is_repeated()) { - printer->Print(vars, - "public static final\n" - " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" - " $containing_type$,\n" - " java.util.List<$type$>> $name$ =\n" - " com.google.protobuf.GeneratedMessage\n" - " .newRepeatedGeneratedExtension(\n" - " getDescriptor().getExtensions().get($index$),\n" - " $type$.class);\n"); - } else { - printer->Print(vars, - "public static final\n" - " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" - " $containing_type$,\n" - " $type$> $name$ =\n" - " com.google.protobuf.GeneratedMessage.newGeneratedExtension(\n" - " getDescriptor().getExtensions().get($index$),\n" - " $type$.class);\n"); - } -} - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h deleted file mode 100644 index 9088fecd..00000000 --- a/src/google/protobuf/compiler/java/java_extension.h +++ /dev/null @@ -1,58 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ - -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - class FieldDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -// Generates code for an extension, which may be within the scope of some -// message or may be at file scope. This is much simpler than FieldGenerator -// since extensions are just simple identifiers with interesting types. -class ExtensionGenerator { - public: - explicit ExtensionGenerator(const FieldDescriptor* descriptor); - ~ExtensionGenerator(); - - void Generate(io::Printer* printer); - - private: - const FieldDescriptor* descriptor_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc deleted file mode 100644 index b7197cac..00000000 --- a/src/google/protobuf/compiler/java/java_field.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_field.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#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/stubs/common.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -FieldGenerator::~FieldGenerator() {} - -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) - : descriptor_(descriptor), - field_generators_( - new scoped_ptr<FieldGenerator>[descriptor->field_count()]), - extension_generators_( - new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { - - // Construct all the FieldGenerators. - for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i))); - } - for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset(MakeGenerator(descriptor->extension(i))); - } -} - -FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { - if (field->is_repeated()) { - switch (GetJavaType(field)) { - case JAVATYPE_MESSAGE: - return new RepeatedMessageFieldGenerator(field); - case JAVATYPE_ENUM: - return new RepeatedEnumFieldGenerator(field); - default: - return new RepeatedPrimitiveFieldGenerator(field); - } - } else { - switch (GetJavaType(field)) { - case JAVATYPE_MESSAGE: - return new MessageFieldGenerator(field); - case JAVATYPE_ENUM: - return new EnumFieldGenerator(field); - default: - return new PrimitiveFieldGenerator(field); - } - } -} - -FieldGeneratorMap::~FieldGeneratorMap() {} - -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); - return *field_generators_[field->index()]; -} - -const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { - return *extension_generators_[index]; -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h deleted file mode 100644 index ef47c735..00000000 --- a/src/google/protobuf/compiler/java/java_field.h +++ /dev/null @@ -1,82 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class FieldGenerator { - public: - FieldGenerator() {} - virtual ~FieldGenerator(); - - virtual void GenerateMembers(io::Printer* printer) const = 0; - virtual void GenerateBuilderMembers(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 GenerateSerializationCode(io::Printer* printer) const = 0; - virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; - - virtual string GetBoxedType() const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); -}; - -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { - public: - explicit FieldGeneratorMap(const Descriptor* descriptor); - ~FieldGeneratorMap(); - - const FieldGenerator& get(const FieldDescriptor* field) const; - const FieldGenerator& get_extension(int index) const; - - private: - const Descriptor* descriptor_; - scoped_array<scoped_ptr<FieldGenerator> > field_generators_; - scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; - - static FieldGenerator* MakeGenerator(const FieldDescriptor* field); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc deleted file mode 100644 index e7e8618d..00000000 --- a/src/google/protobuf/compiler/java/java_file.cc +++ /dev/null @@ -1,249 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_file.h> -#include <google/protobuf/compiler/java/java_enum.h> -#include <google/protobuf/compiler/java/java_service.h> -#include <google/protobuf/compiler/java/java_extension.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_message.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -FileGenerator::FileGenerator(const FileDescriptor* file) - : file_(file), - java_package_(FileJavaPackage(file)), - classname_(FileClassName(file)) {} - -FileGenerator::~FileGenerator() {} - -bool FileGenerator::Validate(string* error) { - // Check that no class name matches the file's class name. This is a common - // problem that leads to Java compile errors that can be hard to understand. - // It's especially bad when using the java_multiple_files, since we would - // end up overwriting the outer class with one of the inner ones. - - bool found_conflict = false; - for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) { - if (file_->enum_type(i)->name() == classname_) { - found_conflict = true; - } - } - for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) { - if (file_->message_type(i)->name() == classname_) { - found_conflict = true; - } - } - for (int i = 0; i < file_->service_count() && !found_conflict; i++) { - if (file_->service(i)->name() == classname_) { - found_conflict = true; - } - } - - if (found_conflict) { - error->assign(file_->name()); - error->append( - ": Cannot generate Java output because the file's outer class name, \""); - error->append(classname_); - error->append( - "\", matches the name of one of the types declared inside it. " - "Please either rename the type or use the java_outer_classname " - "option to specify a different outer class name for the .proto file."); - return false; - } - - return true; -} - -void FileGenerator::Generate(io::Printer* printer) { - // We don't import anything because we refer to all classes by their - // fully-qualified names in the generated source. - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n"); - if (!java_package_.empty()) { - printer->Print( - "package $package$;\n" - "\n", - "package", java_package_); - } - printer->Print( - "public final class $classname$ {\n" - " private $classname$() {}\n", - "classname", classname_); - printer->Indent(); - - // ----------------------------------------------------------------- - - // Embed the descriptor. We simply serialize the entire FileDescriptorProto - // and embed it as a string literal, which is parsed and built into real - // descriptors at initialization time. We unfortunately have to put it in - // a string literal, not a byte array, because apparently using a literal - // byte array causes the Java compiler to generate *instructions* to - // initialize each and every byte of the array, e.g. as if you typed: - // b[0] = 123; b[1] = 456; b[2] = 789; - // This makes huge bytecode files and can easily hit the compiler's internal - // code size limits (error "code to large"). String literals are apparently - // embedded raw, which is what we want. - FileDescriptorProto file_proto; - file_->CopyTo(&file_proto); - string file_data; - file_proto.SerializeToString(&file_data); - - printer->Print( - "public static com.google.protobuf.Descriptors.FileDescriptor\n" - " getDescriptor() {\n" - " return descriptor;\n" - "}\n" - "private static final com.google.protobuf.Descriptors.FileDescriptor\n" - " descriptor = buildDescriptor();\n" - "private static\n" - " com.google.protobuf.Descriptors.FileDescriptor\n" - " buildDescriptor() {\n" - " java.lang.String descriptorData =\n"); - printer->Indent(); - printer->Indent(); - - // Only write 40 bytes per line. - static const int kBytesPerLine = 40; - for (int i = 0; i < file_data.size(); i += kBytesPerLine) { - if (i > 0) printer->Print(" +\n"); - printer->Print("\"$data$\"", - "data", CEscape(file_data.substr(i, kBytesPerLine))); - } - printer->Print(";\n"); - - printer->Outdent(); - printer->Print( - "try {\n" - " return com.google.protobuf.Descriptors.FileDescriptor\n" - " .internalBuildGeneratedFileFrom(descriptorData,\n" - " new com.google.protobuf.Descriptors.FileDescriptor[] {\n"); - - for (int i = 0; i < file_->dependency_count(); i++) { - printer->Print( - " $dependency$.getDescriptor(),\n", - "dependency", ClassName(file_->dependency(i))); - } - - printer->Print( - " });\n" - "} catch (Exception e) {\n" - " throw new RuntimeException(\n" - " \"Failed to parse protocol buffer descriptor for \" +\n" - " \"\\\"$filename$\\\".\", e);\n" - "}\n", - "filename", file_->name()); - - printer->Outdent(); - printer->Print( - "}\n" - "\n"); - - // ----------------------------------------------------------------- - - if (!file_->options().java_multiple_files()) { - for (int i = 0; i < file_->enum_type_count(); i++) { - EnumGenerator(file_->enum_type(i)).Generate(printer); - } - for (int i = 0; i < file_->message_type_count(); i++) { - MessageGenerator(file_->message_type(i)).Generate(printer); - } - for (int i = 0; i < file_->service_count(); i++) { - ServiceGenerator(file_->service(i)).Generate(printer); - } - } - - // Extensions must be generated in the outer class since they are values, - // not classes. - for (int i = 0; i < file_->extension_count(); i++) { - ExtensionGenerator(file_->extension(i)).Generate(printer); - } - - // Static variables. - for (int i = 0; i < file_->message_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer); - } - - printer->Outdent(); - printer->Print("}\n"); -} - -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"; - file_list->push_back(filename); - - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename)); - io::Printer printer(output.get(), '$'); - - printer.Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n"); - if (!java_package.empty()) { - printer.Print( - "package $package$;\n" - "\n", - "package", java_package); - } - - GeneratorClass(descriptor).Generate(&printer); -} - -void FileGenerator::GenerateSiblings(const string& package_dir, - OutputDirectory* output_directory, - 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); - } - for (int i = 0; i < file_->message_type_count(); i++) { - GenerateSibling<MessageGenerator>(package_dir, java_package_, - file_->message_type(i), - output_directory, file_list); - } - for (int i = 0; i < file_->service_count(); i++) { - GenerateSibling<ServiceGenerator>(package_dir, java_package_, - file_->service(i), - output_directory, file_list); - } - } -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h deleted file mode 100644 index 9eeec253..00000000 --- a/src/google/protobuf/compiler/java/java_file.h +++ /dev/null @@ -1,78 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ - -#include <string> -#include <vector> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - class FileDescriptor; // descriptor.h - namespace io { - class Printer; // printer.h - } - namespace compiler { - class OutputDirectory; // code_generator.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class FileGenerator { - public: - explicit FileGenerator(const FileDescriptor* file); - ~FileGenerator(); - - // Checks for problems that would otherwise lead to cryptic compile errors. - // Returns true if there are no problems, or writes an error description to - // the given string and returns false otherwise. - bool Validate(string* error); - - void Generate(io::Printer* printer); - - // If we aren't putting everything into one file, this will write all the - // 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, - vector<string>* file_list); - - const string& java_package() { return java_package_; } - const string& classname() { return classname_; } - - private: - const FileDescriptor* file_; - string java_package_; - string classname_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc deleted file mode 100644 index 89a32da4..00000000 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ /dev/null @@ -1,133 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_generator.h> -#include <google/protobuf/compiler/java/java_file.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -namespace { - -// Parses a set of comma-delimited name/value pairs, e.g.: -// "foo=bar,baz,qux=corge" -// parses to the pairs: -// ("foo", "bar"), ("baz", ""), ("qux", "corge") -void ParseOptions(const string& text, vector<pair<string, string> >* output) { - vector<string> parts; - SplitStringUsing(text, ",", &parts); - - for (int i = 0; i < parts.size(); i++) { - string::size_type equals_pos = parts[i].find_first_of('='); - pair<string, string> value; - if (equals_pos == string::npos) { - value.first = parts[i]; - value.second = ""; - } else { - value.first = parts[i].substr(0, equals_pos); - value.second = parts[i].substr(equals_pos + 1); - } - output->push_back(value); - } -} - -} // namespace - -JavaGenerator::JavaGenerator() {} -JavaGenerator::~JavaGenerator() {} - -bool JavaGenerator::Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - vector<pair<string, string> > options; - ParseOptions(parameter, &options); - - // ----------------------------------------------------------------- - // parse generator options - - // Name a file where we will write a list of generated file names, one - // per line. - string output_list_file; - - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "output_list_file") { - output_list_file = options[i].second; - } else { - *error = "Unknown generator option: " + options[i].first; - 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 += "/"; - - vector<string> all_files; - - string java_filename = package_dir; - java_filename += file_generator.classname(); - java_filename += ".java"; - all_files.push_back(java_filename); - - // Generate main java file. - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(java_filename)); - io::Printer printer(output.get(), '$'); - file_generator.Generate(&printer); - - // Generate sibling files. - file_generator.GenerateSiblings(package_dir, output_directory, &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)); - 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]); - } - } - - return true; -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h deleted file mode 100644 index 11886aa0..00000000 --- a/src/google/protobuf/compiler/java/java_generator.h +++ /dev/null @@ -1,58 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Generates Java code for a given .proto file. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ - -#include <string> -#include <google/protobuf/compiler/code_generator.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -// CodeGenerator implementation which generates Java code. If you create your -// own protocol compiler binary and you want it to support Java output, you -// can do so by registering an instance of this CodeGenerator with the -// CommandLineInterface in your main() function. -class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator { - public: - JavaGenerator(); - ~JavaGenerator(); - - // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc deleted file mode 100644 index 4ba82c2a..00000000 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ /dev/null @@ -1,229 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> - -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -const char kThickSeparator[] = - "// ===================================================================\n"; -const char kThinSeparator[] = - "// -------------------------------------------------------------------\n"; - -namespace { - -const char* kDefaultPackage = ""; - -const string& FieldName(const FieldDescriptor* field) { - // Groups are hacky: The name of the field is just the lower-cased name - // of the group type. In Java, though, we would like to retain the original - // capitalization of the type name. - if (field->type() == FieldDescriptor::TYPE_GROUP) { - return field->message_type()->name(); - } else { - return field->name(); - } -} - -string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) { - string result; - // Note: I distrust ctype.h due to locales. - for (int i = 0; i < input.size(); i++) { - if ('a' <= input[i] && input[i] <= 'z') { - if (cap_next_letter) { - result += input[i] + ('A' - 'a'); - } else { - result += input[i]; - } - cap_next_letter = false; - } else if ('A' <= input[i] && input[i] <= 'Z') { - if (i == 0 && !cap_next_letter) { - // Force first letter to lower-case unless explicitly told to - // capitalize it. - result += input[i] + ('a' - 'A'); - } else { - // Capital letters after the first are left as-is. - result += input[i]; - } - cap_next_letter = false; - } else if ('0' <= input[i] && input[i] <= '9') { - result += input[i]; - cap_next_letter = true; - } else { - cap_next_letter = true; - } - } - return result; -} - -} // namespace - -string UnderscoresToCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), false); -} - -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { - return UnderscoresToCamelCaseImpl(FieldName(field), true); -} - -string UnderscoresToCamelCase(const MethodDescriptor* method) { - return UnderscoresToCamelCaseImpl(method->name(), false); -} - -string StripProto(const string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - -string FileClassName(const FileDescriptor* file) { - if (file->options().has_java_outer_classname()) { - return file->options().java_outer_classname(); - } else { - string basename; - string::size_type last_slash = file->name().find_last_of('/'); - if (last_slash == string::npos) { - basename = file->name(); - } else { - basename = file->name().substr(last_slash + 1); - } - return UnderscoresToCamelCaseImpl(StripProto(basename), true); - } -} - -string FileJavaPackage(const FileDescriptor* file) { - if (file->options().has_java_package()) { - return file->options().java_package(); - } else { - string result = kDefaultPackage; - if (!file->package().empty()) { - if (!result.empty()) result += '.'; - result += file->package(); - } - return result; - } -} - -string ToJavaName(const string& full_name, const FileDescriptor* file) { - string result; - if (file->options().java_multiple_files()) { - result = FileJavaPackage(file); - } else { - result = ClassName(file); - } - if (!result.empty()) { - result += '.'; - } - if (file->package().empty()) { - result += full_name; - } else { - // Strip the proto package from full_name since we've replaced it with - // the Java package. - result += full_name.substr(file->package().size() + 1); - } - return result; -} - -string ClassName(const FileDescriptor* descriptor) { - string result = FileJavaPackage(descriptor); - if (!result.empty()) result += '.'; - result += FileClassName(descriptor); - return result; -} - -JavaType GetJavaType(FieldDescriptor::Type field_type) { - switch (field_type) { - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_SFIXED32: - return JAVATYPE_INT; - - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_SFIXED64: - return JAVATYPE_LONG; - - case FieldDescriptor::TYPE_FLOAT: - return JAVATYPE_FLOAT; - - case FieldDescriptor::TYPE_DOUBLE: - return JAVATYPE_DOUBLE; - - case FieldDescriptor::TYPE_BOOL: - return JAVATYPE_BOOLEAN; - - case FieldDescriptor::TYPE_STRING: - return JAVATYPE_STRING; - - case FieldDescriptor::TYPE_BYTES: - return JAVATYPE_BYTES; - - case FieldDescriptor::TYPE_ENUM: - return JAVATYPE_ENUM; - - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - return JAVATYPE_MESSAGE; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return JAVATYPE_INT; -} - -const char* BoxedPrimitiveTypeName(JavaType type) { - switch (type) { - case JAVATYPE_INT : return "java.lang.Integer"; - case JAVATYPE_LONG : return "java.lang.Long"; - case JAVATYPE_FLOAT : return "java.lang.Float"; - case JAVATYPE_DOUBLE : return "java.lang.Double"; - case JAVATYPE_BOOLEAN: return "java.lang.Boolean"; - case JAVATYPE_STRING : return "java.lang.String"; - case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; - case JAVATYPE_ENUM : return NULL; - case JAVATYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h deleted file mode 100644 index 74376330..00000000 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ /dev/null @@ -1,102 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ - -#include <string> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -// Commonly-used separator comments. Thick is a line of '=', thin is a line -// of '-'. -extern const char kThickSeparator[]; -extern const char kThinSeparator[]; - -// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes -// "fooBarBaz" or "FooBarBaz", respectively. -string UnderscoresToCamelCase(const FieldDescriptor* field); -string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); - -// Similar, but for method names. (Typically, this merely has the effect -// of lower-casing the first letter of the name.) -string UnderscoresToCamelCase(const MethodDescriptor* method); - -// Strips ".proto" or ".protodevel" from the end of a filename. -string StripProto(const string& filename); - -// Gets the unqualified class name for the file. Each .proto file becomes a -// single Java class, with all its contents nested in that class. -string FileClassName(const FileDescriptor* file); - -// Returns the file's Java package name. -string FileJavaPackage(const FileDescriptor* file); - -// 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. -string ToJavaName(const string& full_name, const FileDescriptor* file); - -// These return the fully-qualified class name corresponding to the given -// descriptor. -inline string ClassName(const Descriptor* descriptor) { - return ToJavaName(descriptor->full_name(), descriptor->file()); -} -inline string ClassName(const EnumDescriptor* descriptor) { - return ToJavaName(descriptor->full_name(), descriptor->file()); -} -inline string ClassName(const ServiceDescriptor* descriptor) { - return ToJavaName(descriptor->full_name(), descriptor->file()); -} -string ClassName(const FileDescriptor* descriptor); - -enum JavaType { - JAVATYPE_INT, - JAVATYPE_LONG, - JAVATYPE_FLOAT, - JAVATYPE_DOUBLE, - JAVATYPE_BOOLEAN, - JAVATYPE_STRING, - JAVATYPE_BYTES, - JAVATYPE_ENUM, - JAVATYPE_MESSAGE -}; - -JavaType GetJavaType(FieldDescriptor::Type field_type); - -inline JavaType GetJavaType(const FieldDescriptor* field) { - return GetJavaType(field->type()); -} - -// Get the fully-qualified class name for a boxed primitive type, e.g. -// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message -// types. -const char* BoxedPrimitiveTypeName(JavaType type); - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc deleted file mode 100644 index ebba1f7b..00000000 --- a/src/google/protobuf/compiler/java/java_message.cc +++ /dev/null @@ -1,722 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/java/java_message.h> -#include <google/protobuf/compiler/java/java_enum.h> -#include <google/protobuf/compiler/java/java_extension.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -using internal::WireFormat; - -namespace { - -void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { - // Print the field's proto-syntax definition as a comment. We don't want to - // print group bodies so we cut off after the first line. - string def = field->DebugString(); - printer->Print("// $def$\n", - "def", def.substr(0, def.find_first_of('\n'))); -} - -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -struct ExtensionRangeOrdering { - bool operator()(const Descriptor::ExtensionRange* a, - const Descriptor::ExtensionRange* b) const { - return a->start < b->start; - } -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor*[descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); - return fields; -} - -// Get an identifier that uniquely identifies this type within the file. -// This is used to declare static variables related to this type at the -// outermost file scope. -string UniqueFileScopeIdentifier(const Descriptor* descriptor) { - return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); -} - -// Returns true if the message type has any required fields. If it doesn't, -// we can optimize out calls to its isInitialized() method. -// -// already_seen is used to avoid checking the same type multiple times -// (and also to protect against recursion). -static bool HasRequiredFields( - const Descriptor* type, - hash_set<const Descriptor*>* already_seen) { - if (already_seen->count(type) > 0) { - // The type is already in cache. This means that either: - // a. The type has no required fields. - // b. We are in the midst of checking if the type has required fields, - // somewhere up the stack. In this case, we know that if the type - // has any required fields, they'll be found when we return to it, - // and the whole call to HasRequiredFields() will return true. - // Therefore, we don't have to check if this type has required fields - // here. - return false; - } - already_seen->insert(type); - - // If the type has extensions, an extension with message type could contain - // required fields, so we have to be conservative and assume such an - // extension exists. - if (type->extension_range_count() > 0) return true; - - for (int i = 0; i < type->field_count(); i++) { - const FieldDescriptor* field = type->field(i); - if (field->is_required()) { - return true; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (HasRequiredFields(field->message_type(), already_seen)) { - return true; - } - } - } - - return false; -} - -static bool HasRequiredFields(const Descriptor* type) { - hash_set<const Descriptor*> already_seen; - return HasRequiredFields(type, &already_seen); -} - -} // namespace - -// =================================================================== - -MessageGenerator::MessageGenerator(const Descriptor* descriptor) - : descriptor_(descriptor), - field_generators_(descriptor) { -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator::GenerateStaticVariables(io::Printer* printer) { - // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is - // used in the construction of descriptors, we have a tricky bootstrapping - // problem. To help control static initialization order, we make sure all - // descriptors and other static data that depends on them are members of - // the outermost class in the file. This way, they will be initialized in - // a deterministic order. - - map<string, string> vars; - vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); - vars["index"] = SimpleItoa(descriptor_->index()); - vars["classname"] = ClassName(descriptor_); - if (descriptor_->containing_type() != NULL) { - vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type()); - } - if (descriptor_->file()->options().java_multiple_files()) { - // We can only make these package-private since the classes that use them - // are in separate files. - vars["private"] = ""; - } else { - vars["private"] = "private "; - } - - // The descriptor for this type. - if (descriptor_->containing_type() == NULL) { - printer->Print(vars, - "$private$static final com.google.protobuf.Descriptors.Descriptor\n" - " internal_$identifier$_descriptor =\n" - " getDescriptor().getMessageTypes().get($index$);\n"); - } else { - printer->Print(vars, - "$private$static final com.google.protobuf.Descriptors.Descriptor\n" - " internal_$identifier$_descriptor =\n" - " internal_$parent$_descriptor.getNestedTypes().get($index$);\n"); - } - - // And the FieldAccessorTable. - printer->Print(vars, - "$private$static\n" - " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" - " internal_$identifier$_fieldAccessorTable = new\n" - " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n" - " internal_$identifier$_descriptor,\n" - " new java.lang.String[] { "); - for (int i = 0; i < descriptor_->field_count(); i++) { - printer->Print( - "\"$field_name$\", ", - "field_name", - UnderscoresToCapitalizedCamelCase(descriptor_->field(i))); - } - printer->Print("},\n" - " $classname$.class,\n" - " $classname$.Builder.class);\n", - "classname", ClassName(descriptor_)); - - // Generate static members for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO(kenton): Reuse MessageGenerator objects? - MessageGenerator(descriptor_->nested_type(i)) - .GenerateStaticVariables(printer); - } -} - -void MessageGenerator::Generate(io::Printer* printer) { - bool is_own_file = - descriptor_->containing_type() == NULL && - descriptor_->file()->options().java_multiple_files(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "public $static$ final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" - " $classname$> {\n", - "static", is_own_file ? "" : "static", - "classname", descriptor_->name()); - } else { - printer->Print( - "public $static$ final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage {\n", - "static", is_own_file ? "" : "static", - "classname", descriptor_->name()); - } - printer->Indent(); - printer->Print( - "// Use $classname$.newBuilder() to construct.\n" - "private $classname$() {}\n" - "\n" - "private static final $classname$ defaultInstance = new $classname$();\n" - "public static $classname$ getDefaultInstance() {\n" - " return defaultInstance;\n" - "}\n" - "\n" - "public $classname$ getDefaultInstanceForType() {\n" - " return defaultInstance;\n" - "}\n" - "\n", - "classname", descriptor_->name()); - 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_)); - - // Nested types and extensions - 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); - } - - for (int i = 0; i < descriptor_->extension_count(); i++) { - ExtensionGenerator(descriptor_->extension(i)).Generate(printer); - } - - // Fields - for (int i = 0; i < descriptor_->field_count(); i++) { - PrintFieldComment(printer, descriptor_->field(i)); - field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); - printer->Print("\n"); - } - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - GenerateIsInitialized(printer); - GenerateMessageSerializationMethods(printer); - } - - GenerateParseFromMethods(printer); - GenerateBuilder(printer); -} - -// =================================================================== - -void MessageGenerator:: -GenerateMessageSerializationMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - vector<const Descriptor::ExtensionRange*> sorted_extensions; - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { - sorted_extensions.push_back(descriptor_->extension_range(i)); - } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeOrdering()); - - printer->Print( - "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" - " throws java.io.IOException {\n"); - printer->Indent(); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "com.google.protobuf.GeneratedMessage.ExtendableMessage\n" - " .ExtensionWriter extensionWriter = newExtensionWriter();\n"); - } - - // Merge the fields and the extension ranges, both sorted by field number. - for (int i = 0, j = 0; - i < descriptor_->field_count() || j < sorted_extensions.size(); - ) { - if (i == descriptor_->field_count()) { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } else if (j == sorted_extensions.size()) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } - } - - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "getUnknownFields().writeAsMessageSetTo(output);\n"); - } else { - printer->Print( - "getUnknownFields().writeTo(output);\n"); - } - - printer->Outdent(); - printer->Print( - "}\n" - "\n" - "private int memoizedSerializedSize = -1;\n" - "public int getSerializedSize() {\n" - " int size = memoizedSerializedSize;\n" - " if (size != -1) return size;\n" - "\n" - " size = 0;\n"); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "size += extensionsSerializedSize();\n"); - } - - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += getUnknownFields().getSerializedSizeAsMessageSet();\n"); - } else { - printer->Print( - "size += getUnknownFields().getSerializedSize();\n"); - } - - printer->Outdent(); - printer->Print( - " memoizedSerializedSize = size;\n" - " return size;\n" - "}\n" - "\n"); -} - -void MessageGenerator:: -GenerateParseFromMethods(io::Printer* printer) { - // Note: These are separate from GenerateMessageSerializationMethods() - // because they need to be generated even for messages that are optimized - // for code size. - printer->Print( - "public static $classname$ parseFrom(\n" - " com.google.protobuf.ByteString data)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " return newBuilder().mergeFrom(data).buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(\n" - " com.google.protobuf.ByteString data,\n" - " com.google.protobuf.ExtensionRegistry extensionRegistry)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " return newBuilder().mergeFrom(data, extensionRegistry)\n" - " .buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(byte[] data)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " return newBuilder().mergeFrom(data).buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(\n" - " byte[] data,\n" - " com.google.protobuf.ExtensionRegistry extensionRegistry)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " return newBuilder().mergeFrom(data, extensionRegistry)\n" - " .buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(java.io.InputStream input)\n" - " throws java.io.IOException {\n" - " return newBuilder().mergeFrom(input).buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(\n" - " java.io.InputStream input,\n" - " com.google.protobuf.ExtensionRegistry extensionRegistry)\n" - " throws java.io.IOException {\n" - " return newBuilder().mergeFrom(input, extensionRegistry)\n" - " .buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(\n" - " com.google.protobuf.CodedInputStream input)\n" - " throws java.io.IOException {\n" - " return newBuilder().mergeFrom(input).buildParsed();\n" - "}\n" - "public static $classname$ parseFrom(\n" - " com.google.protobuf.CodedInputStream input,\n" - " com.google.protobuf.ExtensionRegistry extensionRegistry)\n" - " throws java.io.IOException {\n" - " return newBuilder().mergeFrom(input, extensionRegistry)\n" - " .buildParsed();\n" - "}\n" - "\n", - "classname", ClassName(descriptor_)); -} - -void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field) { - field_generators_.get(field).GenerateSerializationCode(printer); -} - -void MessageGenerator::GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range) { - printer->Print( - "extensionWriter.writeUntil($end$, output);\n", - "end", SimpleItoa(range->end)); -} - -// =================================================================== - -void MessageGenerator::GenerateBuilder(io::Printer* printer) { - printer->Print( - "public static Builder newBuilder() { return new Builder(); }\n" - "public Builder newBuilderForType() { return new Builder(); }\n" - "public static Builder newBuilder($classname$ prototype) {\n" - " return new Builder().mergeFrom(prototype);\n" - "}\n" - "\n", - "classname", ClassName(descriptor_)); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" - " $classname$, Builder> {\n", - "classname", ClassName(descriptor_)); - } else { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n", - "classname", ClassName(descriptor_)); - } - printer->Indent(); - - GenerateCommonBuilderMethods(printer); - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - GenerateBuilderParsingMethods(printer); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - printer->Print("\n"); - PrintFieldComment(printer, descriptor_->field(i)); - field_generators_.get(descriptor_->field(i)) - .GenerateBuilderMembers(printer); - } - - printer->Outdent(); - printer->Print("}\n"); - printer->Outdent(); - printer->Print("}\n\n"); -} - -// =================================================================== - -void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { - printer->Print( - "// Construct using $classname$.newBuilder()\n" - "private Builder() {}\n" - "\n" - "$classname$ result = new $classname$();\n" - "\n" - "protected $classname$ internalGetResult() {\n" - " return result;\n" - "}\n" - "\n" - "public Builder clear() {\n" - " result = new $classname$();\n" - " return this;\n" - "}\n" - "\n" - "public Builder clone() {\n" - " return new Builder().mergeFrom(result);\n" - "}\n" - "\n" - "public com.google.protobuf.Descriptors.Descriptor\n" - " getDescriptorForType() {\n" - " return $classname$.getDescriptor();\n" - "}\n" - "\n" - "public $classname$ getDefaultInstanceForType() {\n" - " return $classname$.getDefaultInstance();\n" - "}\n" - "\n", - "classname", ClassName(descriptor_)); - - // ----------------------------------------------------------------- - - printer->Print( - "public $classname$ build() {\n" - " if (!isInitialized()) {\n" - " throw new com.google.protobuf.UninitializedMessageException(\n" - " result);\n" - " }\n" - " return buildPartial();\n" - "}\n" - "\n" - "private $classname$ buildParsed()\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " if (!isInitialized()) {\n" - " throw new com.google.protobuf.UninitializedMessageException(\n" - " result).asInvalidProtocolBufferException();\n" - " }\n" - " return buildPartial();\n" - "}\n" - "\n" - "public $classname$ buildPartial() {\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); - } - - printer->Outdent(); - printer->Print( - " $classname$ returnMe = result;\n" - " result = null;\n" - " return returnMe;\n" - "}\n" - "\n", - "classname", ClassName(descriptor_)); - - // ----------------------------------------------------------------- - - if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) { - printer->Print( - "public Builder mergeFrom(com.google.protobuf.Message other) {\n" - " if (other instanceof $classname$) {\n" - " return mergeFrom(($classname$)other);\n" - " } else {\n" - " super.mergeFrom(other);\n" - " return this;\n" - " }\n" - "}\n" - "\n" - "public Builder mergeFrom($classname$ other) {\n" - // Optimization: If other is the default instance, we know none of its - // fields are set so we can skip the merge. - " if (other == $classname$.getDefaultInstance()) return this;\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer); - } - - printer->Outdent(); - printer->Print( - " this.mergeUnknownFields(other.getUnknownFields());\n" - " return this;\n" - "}\n" - "\n"); - } -} - -// =================================================================== - -void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { - scoped_array<const FieldDescriptor*> sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print( - "public Builder mergeFrom(\n" - " com.google.protobuf.CodedInputStream input)\n" - " throws java.io.IOException {\n" - " return mergeFrom(input,\n" - " com.google.protobuf.ExtensionRegistry.getEmptyRegistry());\n" - "}\n" - "\n" - "public Builder mergeFrom(\n" - " com.google.protobuf.CodedInputStream input,\n" - " com.google.protobuf.ExtensionRegistry extensionRegistry)\n" - " throws java.io.IOException {\n"); - printer->Indent(); - - printer->Print( - "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" - " com.google.protobuf.UnknownFieldSet.newBuilder(\n" - " this.getUnknownFields());\n" - "while (true) {\n"); - printer->Indent(); - - printer->Print( - "int tag = input.readTag();\n" - "switch (tag) {\n"); - printer->Indent(); - - printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " this.setUnknownFields(unknownFields.build());\n" - " return this;\n" - "default: {\n" - " if (!parseUnknownField(input, unknownFields,\n" - " extensionRegistry, tag)) {\n" - " this.setUnknownFields(unknownFields.build());\n" - " return this;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32 tag = WireFormat::MakeTag(field->number(), - WireFormat::WireTypeForFieldType(field->type())); - - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(tag)); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCode(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - } - - printer->Outdent(); - printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // switch (tag) - " }\n" // while (true) - "}\n" - "\n"); -} - -// =================================================================== - -void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { - printer->Print( - "public final boolean isInitialized() {\n"); - printer->Indent(); - - // 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. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->is_required()) { - printer->Print( - "if (!has$name$) return false;\n", - "name", UnderscoresToCapitalizedCamelCase(field)); - } - } - - // Now check that all embedded messages are initialized. - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - HasRequiredFields(field->message_type())) { - switch (field->label()) { - case FieldDescriptor::LABEL_REQUIRED: - printer->Print( - "if (!get$name$().isInitialized()) return false;\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_OPTIONAL: - printer->Print( - "if (has$name$()) {\n" - " if (!get$name$().isInitialized()) return false;\n" - "}\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - case FieldDescriptor::LABEL_REPEATED: - printer->Print( - "for ($type$ element : get$name$List()) {\n" - " if (!element.isInitialized()) return false;\n" - "}\n", - "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); - break; - } - } - } - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "if (!extensionsAreInitialized()) return false;\n"); - } - - printer->Outdent(); - printer->Print( - " return true;\n" - "}\n" - "\n"); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h deleted file mode 100644 index d9f8798e..00000000 --- a/src/google/protobuf/compiler/java/java_message.h +++ /dev/null @@ -1,76 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/compiler/java/java_field.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class MessageGenerator { - public: - explicit MessageGenerator(const Descriptor* descriptor); - ~MessageGenerator(); - - // All static variables have to be declared at the top-level of the file - // so that we can control initialization order, which is important for - // DescriptorProto bootstrapping to work. - void GenerateStaticVariables(io::Printer* printer); - - // Generate the class itself. - void Generate(io::Printer* printer); - - private: - void GenerateMessageSerializationMethods(io::Printer* printer); - void GenerateParseFromMethods(io::Printer* printer); - void GenerateSerializeOneField(io::Printer* printer, - const FieldDescriptor* field); - void GenerateSerializeOneExtensionRange( - io::Printer* printer, const Descriptor::ExtensionRange* range); - - void GenerateBuilder(io::Printer* printer); - void GenerateCommonBuilderMethods(io::Printer* printer); - void GenerateBuilderParsingMethods(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer); - - const Descriptor* descriptor_; - FieldGeneratorMap field_generators_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc deleted file mode 100644 index 16ddb0d6..00000000 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ /dev/null @@ -1,302 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/java/java_message_field.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 { - -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, - map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = ClassName(descriptor->message_type()); - (*variables)["group_or_message"] = - (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? - "Group" : "Message"; -} - -} // namespace - -// =================================================================== - -MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -MessageFieldGenerator::~MessageFieldGenerator() {} - -void MessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private boolean has$capitalized_name$;\n" - "private $type$ $name$_ = $type$.getDefaultInstance();\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public $type$ get$capitalized_name$() { return $name$_; }\n"); -} - -void MessageFieldGenerator:: -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" - " 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" - "}\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" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n" - " result.$name$_ = $type$.getDefaultInstance();\n" - " return this;\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " merge$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do for singular fields. -} - -void MessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = $type$.newBuilder();\n" - "if (has$capitalized_name$()) {\n" - " subBuilder.mergeFrom(get$capitalized_name$());\n" - "}\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.readGroup($number$, subBuilder, extensionRegistry);\n"); - } else { - printer->Print(variables_, - "input.readMessage(subBuilder, extensionRegistry);\n"); - } - - printer->Print(variables_, - "set$capitalized_name$(subBuilder.buildPartial());\n"); -} - -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" - "}\n"); -} - -void MessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" - "}\n"); -} - -string MessageFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->message_type()); -} - -// =================================================================== - -RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); -} - -RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} - -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" - " 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" - " return $name$_.get(index);\n" - "}\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - 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" - " 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" - "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.add(value);\n" - " return this;\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" - "}\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" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\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"); -} - -void RepeatedMessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$type$.Builder subBuilder = $type$.newBuilder();\n"); - - if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.readGroup($number$, subBuilder, extensionRegistry);\n"); - } else { - printer->Print(variables_, - "input.readMessage(subBuilder, extensionRegistry);\n"); - } - - printer->Print(variables_, - "add$capitalized_name$(subBuilder.buildPartial());\n"); -} - -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" - "}\n"); -} - -void RepeatedMessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .compute$group_or_message$Size($number$, element);\n" - "}\n"); -} - -string RepeatedMessageFieldGenerator::GetBoxedType() const { - return ClassName(descriptor_->message_type()); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h deleted file mode 100644 index 52cf7d15..00000000 --- a/src/google/protobuf/compiler/java/java_message_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/java/java_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -class MessageFieldGenerator : public FieldGenerator { - public: - explicit MessageFieldGenerator(const FieldDescriptor* descriptor); - ~MessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); -}; - -class RepeatedMessageFieldGenerator : public FieldGenerator { - public: - explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedMessageFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc deleted file mode 100644 index 9138f2c9..00000000 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ /dev/null @@ -1,365 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <map> -#include <string> - -#include <google/protobuf/compiler/java/java_primitive_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/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -namespace { - -const char* PrimitiveTypeName(JavaType type) { - switch (type) { - case JAVATYPE_INT : return "int"; - case JAVATYPE_LONG : return "long"; - case JAVATYPE_FLOAT : return "float"; - case JAVATYPE_DOUBLE : return "double"; - case JAVATYPE_BOOLEAN: return "boolean"; - case JAVATYPE_STRING : return "java.lang.String"; - case JAVATYPE_BYTES : return "com.google.protobuf.ByteString"; - case JAVATYPE_ENUM : return NULL; - case JAVATYPE_MESSAGE: return NULL; - - // No default because we want the compiler to complain if any new - // JavaTypes are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -const char* GetCapitalizedType(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32 : return "Int32" ; - case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; - case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; - case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; - case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; - case FieldDescriptor::TYPE_INT64 : return "Int64" ; - case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; - case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; - case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; - case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; - case FieldDescriptor::TYPE_FLOAT : return "Float" ; - case FieldDescriptor::TYPE_DOUBLE : return "Double" ; - case FieldDescriptor::TYPE_BOOL : return "Bool" ; - case FieldDescriptor::TYPE_STRING : return "String" ; - case FieldDescriptor::TYPE_BYTES : return "Bytes" ; - case FieldDescriptor::TYPE_ENUM : return "Enum" ; - case FieldDescriptor::TYPE_GROUP : return "Group" ; - case FieldDescriptor::TYPE_MESSAGE : return "Message" ; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -bool AllPrintableAscii(const string& text) { - // Cannot use isprint() because it's locale-specific. :( - for (int i = 0; i < text.size(); i++) { - if ((text[i] < 0x20) || text[i] >= 0x7F) { - return false; - } - } - return true; -} - -string DefaultValue(const FieldDescriptor* field) { - // Switch on cpp_type since we need to know which default_value_* method - // of FieldDescriptor to call. - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return SimpleItoa(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - // Need to print as a signed int since Java has no unsigned. - return SimpleItoa(static_cast<int32>(field->default_value_uint32())); - case FieldDescriptor::CPPTYPE_INT64: - return SimpleItoa(field->default_value_int64()) + "L"; - case FieldDescriptor::CPPTYPE_UINT64: - return SimpleItoa(static_cast<int64>(field->default_value_uint64())) + - "L"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field->default_value_double()) + "D"; - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field->default_value_float()) + "F"; - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_STRING: { - bool isBytes = field->type() == FieldDescriptor::TYPE_BYTES; - - if (!isBytes && AllPrintableAscii(field->default_value_string())) { - // All chars are ASCII and printable. In this case CEscape() works - // fine (it will only escape quotes and backslashes). - // Note: If this "optimization" is removed, DescriptorProtos will - // no longer be able to initialize itself due to bootstrapping - // problems. - return "\"" + CEscape(field->default_value_string()) + "\""; - } - - if (isBytes && !field->has_default_value()) { - return "com.google.protobuf.ByteString.EMPTY"; - } - - // Escaping strings correctly for Java and generating efficient - // initializers for ByteStrings are both tricky. We can sidestep the - // whole problem by just grabbing the default value from the descriptor. - return strings::Substitute( - "(($0) $1.getDescriptor().getFields().get($2).getDefaultValue())", - isBytes ? "com.google.protobuf.ByteString" : "java.lang.String", - ClassName(field->containing_type()), field->index()); - } - - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; - - // No default because we want the compiler to complain if any new - // types are added. - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return ""; -} - -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { - (*variables)["name"] = - UnderscoresToCamelCase(descriptor); - (*variables)["capitalized_name"] = - UnderscoresToCapitalizedCamelCase(descriptor); - (*variables)["number"] = SimpleItoa(descriptor->number()); - (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); - (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); - (*variables)["default"] = DefaultValue(descriptor); - (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); -} - -} // namespace - -// =================================================================== - -PrimitiveFieldGenerator:: -PrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} - -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"); -} - -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" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = value;\n" - " return this;\n" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n" - " result.$name$_ = $default$;\n" - " return this;\n" - "}\n"); -} - -void PrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " set$capitalized_name$(other.get$capitalized_name$());\n" - "}\n"); -} - -void PrimitiveFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for primitive types. -} - -void PrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "set$capitalized_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" - "}\n"); -} - -void PrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n" - "}\n"); -} - -string PrimitiveFieldGenerator::GetBoxedType() const { - return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); -} - -// =================================================================== - -RepeatedPrimitiveFieldGenerator:: -RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); -} - -RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} - -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" - " 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" - " return $name$_.get(index);\n" - "}\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - 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<$boxed_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" - " result.$name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n" - " }\n" - " result.$name$_.add(value);\n" - " return this;\n" - "}\n" - "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" - " return this;\n" - "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n" - " }\n" - " result.$name$_.addAll(other.$name$_);\n" - "}\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -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"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "add$capitalized_name$(input.read$capitalized_type$());\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$capitalized_type$($number$, element);\n" - "}\n"); -} - -void RepeatedPrimitiveFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$Size($number$, element);\n" - "}\n"); -} - -string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { - return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h deleted file mode 100644 index 6fe9177a..00000000 --- a/src/google/protobuf/compiler/java/java_primitive_field.h +++ /dev/null @@ -1,84 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/java/java_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -class PrimitiveFieldGenerator : public FieldGenerator { - public: - explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~PrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); -}; - -class RepeatedPrimitiveFieldGenerator : public FieldGenerator { - public: - explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); - ~RepeatedPrimitiveFieldGenerator(); - - // implements FieldGenerator --------------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(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; - - string GetBoxedType() const; - - private: - const FieldDescriptor* descriptor_; - map<string, string> variables_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc deleted file mode 100644 index 8cb06270..00000000 --- a/src/google/protobuf/compiler/java/java_service.cc +++ /dev/null @@ -1,225 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_service.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor) - : descriptor_(descriptor) {} - -ServiceGenerator::~ServiceGenerator() {} - -void ServiceGenerator::Generate(io::Printer* printer) { - bool is_own_file = descriptor_->file()->options().java_multiple_files(); - printer->Print( - "public $static$ abstract class $classname$\n" - " implements com.google.protobuf.Service {\n", - "static", is_own_file ? "" : "static", - "classname", descriptor_->name()); - printer->Indent(); - - // Generate abstract method declarations. - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["name"] = UnderscoresToCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "public abstract void $name$(\n" - " com.google.protobuf.RpcController controller,\n" - " $input$ request,\n" - " com.google.protobuf.RpcCallback<$output$> done);\n"); - } - - // Generate getDescriptor() and getDescriptorForType(). - printer->Print( - "\n" - "public static final\n" - " com.google.protobuf.Descriptors.ServiceDescriptor\n" - " getDescriptor() {\n" - " return $file$.getDescriptor().getServices().get($index$);\n" - "}\n" - "public final com.google.protobuf.Descriptors.ServiceDescriptor\n" - " getDescriptorForType() {\n" - " return getDescriptor();\n" - "}\n", - "file", ClassName(descriptor_->file()), - "index", SimpleItoa(descriptor_->index())); - - // Generate more stuff. - GenerateCallMethod(printer); - GenerateGetPrototype(REQUEST, printer); - GenerateGetPrototype(RESPONSE, printer); - GenerateStub(printer); - - printer->Outdent(); - printer->Print("}\n\n"); -} - -void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { - printer->Print( - "\n" - "public final void callMethod(\n" - " com.google.protobuf.Descriptors.MethodDescriptor method,\n" - " com.google.protobuf.RpcController controller,\n" - " com.google.protobuf.Message request,\n" - " com.google.protobuf.RpcCallback<\n" - " com.google.protobuf.Message> done) {\n" - " if (method.getService() != getDescriptor()) {\n" - " throw new java.lang.IllegalArgumentException(\n" - " \"Service.callMethod() given method descriptor for wrong \" +\n" - " \"service type.\");\n" - " }\n" - " switch(method.getIndex()) {\n"); - printer->Indent(); - printer->Indent(); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["method"] = UnderscoresToCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "case $index$:\n" - " this.$method$(controller, ($input$)request,\n" - " com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n" - " done));\n" - " return;\n"); - } - - printer->Print( - "default:\n" - " throw new java.lang.RuntimeException(\"Can't get here.\");\n"); - - printer->Outdent(); - printer->Outdent(); - - printer->Print( - " }\n" - "}\n" - "\n"); -} - -void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, - io::Printer* printer) { - printer->Print( - "public final com.google.protobuf.Message\n" - " get$request_or_response$Prototype(\n" - " com.google.protobuf.Descriptors.MethodDescriptor method) {\n" - " if (method.getService() != getDescriptor()) {\n" - " throw new java.lang.IllegalArgumentException(\n" - " \"Service.get$request_or_response$Prototype() given method \" +\n" - " \"descriptor for wrong service type.\");\n" - " }\n" - " switch(method.getIndex()) {\n", - "request_or_response", (which == REQUEST) ? "Request" : "Response"); - printer->Indent(); - printer->Indent(); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["type"] = ClassName( - (which == REQUEST) ? method->input_type() : method->output_type()); - printer->Print(vars, - "case $index$:\n" - " return $type$.getDefaultInstance();\n"); - } - - printer->Print( - "default:\n" - " throw new java.lang.RuntimeException(\"Can't get here.\");\n"); - - printer->Outdent(); - printer->Outdent(); - - printer->Print( - " }\n" - "}\n" - "\n"); -} - -void ServiceGenerator::GenerateStub(io::Printer* printer) { - printer->Print( - "public static Stub newStub(\n" - " com.google.protobuf.RpcChannel channel) {\n" - " return new Stub(channel);\n" - "}\n" - "\n" - "public static final class Stub extends $classname$ {\n", - "classname", ClassName(descriptor_)); - printer->Indent(); - - printer->Print( - "private Stub(com.google.protobuf.RpcChannel channel) {\n" - " this.channel = channel;\n" - "}\n" - "\n" - "private final com.google.protobuf.RpcChannel channel;\n" - "\n" - "public com.google.protobuf.RpcChannel getChannel() {\n" - " return channel;\n" - "}\n"); - - for (int i = 0; i < descriptor_->method_count(); i++) { - const MethodDescriptor* method = descriptor_->method(i); - map<string, string> vars; - vars["index"] = SimpleItoa(i); - vars["method"] = UnderscoresToCamelCase(method); - vars["input"] = ClassName(method->input_type()); - vars["output"] = ClassName(method->output_type()); - printer->Print(vars, - "\n" - "public void $method$(\n" - " com.google.protobuf.RpcController controller,\n" - " $input$ request,\n" - " com.google.protobuf.RpcCallback<$output$> done) {\n" - " channel.callMethod(\n" - " getDescriptor().getMethods().get($index$),\n" - " controller,\n" - " request,\n" - " $output$.getDefaultInstance(),\n" - " com.google.protobuf.RpcUtil.generalizeCallback(\n" - " done,\n" - " $output$.class,\n" - " $output$.getDefaultInstance()));\n" - "}\n"); - } - - printer->Outdent(); - printer->Print("}\n"); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h deleted file mode 100644 index adf3dfd4..00000000 --- a/src/google/protobuf/compiler/java/java_service.h +++ /dev/null @@ -1,66 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ - -#include <map> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - namespace io { - class Printer; // printer.h - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class ServiceGenerator { - public: - explicit ServiceGenerator(const ServiceDescriptor* descriptor); - ~ServiceGenerator(); - - void Generate(io::Printer* printer); - - private: - // Generate the implementation of Service.callMethod(). - void GenerateCallMethod(io::Printer* printer); - - // Generate the implementations of Service.get{Request,Response}Prototype(). - enum RequestOrResponse { REQUEST, RESPONSE }; - void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); - - // Generate a stub implementation of the service. - void GenerateStub(io::Printer* printer); - - const ServiceDescriptor* descriptor_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -#endif // NET_PROTO2_COMPILER_JAVA_SERVICE_H__ -} // namespace google diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc deleted file mode 100644 index 84b58a35..00000000 --- a/src/google/protobuf/compiler/main.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <google/protobuf/compiler/command_line_interface.h> -#include <google/protobuf/compiler/cpp/cpp_generator.h> -#include <google/protobuf/compiler/python/python_generator.h> -#include <google/protobuf/compiler/java/java_generator.h> -#include <google/protobuf/compiler/csharp/csharp_generator.h> - -int main(int argc, char* argv[]) { - - google::protobuf::compiler::CommandLineInterface cli; - - // Proto2 C++ - google::protobuf::compiler::cpp::CppGenerator cpp_generator; - cli.RegisterGenerator("--cpp_out", &cpp_generator, - "Generate C++ header and source."); - - // Proto2 Java - google::protobuf::compiler::java::JavaGenerator java_generator; - cli.RegisterGenerator("--java_out", &java_generator, - "Generate Java source file."); - - // Proto2 Python - google::protobuf::compiler::python::Generator py_generator; - cli.RegisterGenerator("--python_out", &py_generator, - "Generate Python source file."); - - // Proto2 C# - google::protobuf::compiler::csharp::CSharpGenerator csharp_generator; - cli.RegisterGenerator("--csharp_out", &csharp_generator, - "Generate C# source file."); - - return cli.Run(argc, argv); -} diff --git a/src/google/protobuf/compiler/package_info.h b/src/google/protobuf/compiler/package_info.h deleted file mode 100644 index aa0c2823..00000000 --- a/src/google/protobuf/compiler/package_info.h +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file exists solely to document the google::protobuf::compiler namespace. -// It is not compiled into anything, but it may be read by an automated -// documentation generator. - -namespace google { - -namespace protobuf { - -// Implementation of the Protocol Buffer compiler. -// -// This package contains code for parsing .proto files and generating code -// based on them. There are two reasons you might be interested in this -// package: -// - You want to parse .proto files at runtime. In this case, you should -// look at importer.h. Since this functionality is widely useful, it is -// included in the libprotobuf base library; you do not have to link against -// libprotoc. -// - You want to write a custom protocol compiler which generates different -// kinds of code, e.g. code in a different language which is not supported -// by the official compiler. For this purpose, command_line_interface.h -// provides you with a complete compiler front-end, so all you need to do -// is write a custom implementation of CodeGenerator and a trivial main() -// function. You can even make your compiler support the official languages -// in addition to your own. Since this functionality is only useful to those -// writing custom compilers, it is in a separate library called "libprotoc" -// which you will have to link against. -namespace compiler {} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc deleted file mode 100644 index 7a148c5a..00000000 --- a/src/google/protobuf/compiler/parser.cc +++ /dev/null @@ -1,1108 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Recursive descent FTW. - -#include <google/protobuf/stubs/hash.h> -#include <float.h> - - -#include <google/protobuf/compiler/parser.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/map-util.h> - -namespace google { -namespace protobuf { -namespace compiler { - -using internal::WireFormat; - -namespace { - -typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap; - -TypeNameMap MakeTypeNameTable() { - TypeNameMap result; - - result["double" ] = FieldDescriptorProto::TYPE_DOUBLE; - result["float" ] = FieldDescriptorProto::TYPE_FLOAT; - result["uint64" ] = FieldDescriptorProto::TYPE_UINT64; - result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64; - result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32; - result["bool" ] = FieldDescriptorProto::TYPE_BOOL; - result["string" ] = FieldDescriptorProto::TYPE_STRING; - result["group" ] = FieldDescriptorProto::TYPE_GROUP; - - result["bytes" ] = FieldDescriptorProto::TYPE_BYTES; - result["uint32" ] = FieldDescriptorProto::TYPE_UINT32; - result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32; - result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64; - result["int32" ] = FieldDescriptorProto::TYPE_INT32; - result["int64" ] = FieldDescriptorProto::TYPE_INT64; - result["sint32" ] = FieldDescriptorProto::TYPE_SINT32; - result["sint64" ] = FieldDescriptorProto::TYPE_SINT64; - - return result; -} - -const TypeNameMap kTypeNames = MakeTypeNameTable(); - -} // anonymous namespace - -// Makes code slightly more readable. The meaning of "DO(foo)" is -// "Execute foo and fail if it fails.", where failure is indicated by -// returning false. -#define DO(STATEMENT) if (STATEMENT) {} else return false - -// =================================================================== - -Parser::Parser() - : input_(NULL), - error_collector_(NULL), - source_location_table_(NULL), - had_errors_(false), - require_syntax_identifier_(false) { -} - -Parser::~Parser() { -} - -// =================================================================== - -inline bool Parser::LookingAt(const char* text) { - return input_->current().text == text; -} - -inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) { - return input_->current().type == token_type; -} - -inline bool Parser::AtEnd() { - return LookingAtType(io::Tokenizer::TYPE_END); -} - -bool Parser::TryConsume(const char* text) { - if (LookingAt(text)) { - input_->Next(); - return true; - } else { - return false; - } -} - -bool Parser::Consume(const char* text, const char* error) { - if (TryConsume(text)) { - return true; - } else { - AddError(error); - return false; - } -} - -bool Parser::Consume(const char* text) { - if (TryConsume(text)) { - return true; - } else { - AddError("Expected \"" + string(text) + "\"."); - return false; - } -} - -bool Parser::ConsumeIdentifier(string* output, const char* error) { - if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - *output = input_->current().text; - input_->Next(); - return true; - } else { - AddError(error); - return false; - } -} - -bool Parser::ConsumeInteger(int* output, const char* error) { - if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - uint64 value = 0; - if (!io::Tokenizer::ParseInteger(input_->current().text, - kint32max, &value)) { - AddError("Integer out of range."); - // We still return true because we did, in fact, parse an integer. - } - *output = value; - input_->Next(); - return true; - } else { - AddError(error); - return false; - } -} - -bool Parser::ConsumeInteger64(uint64 max_value, uint64* output, - const char* error) { - if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - if (!io::Tokenizer::ParseInteger(input_->current().text, max_value, - output)) { - AddError("Integer out of range."); - // We still return true because we did, in fact, parse an integer. - *output = 0; - } - input_->Next(); - return true; - } else { - AddError(error); - return false; - } -} - -bool Parser::ConsumeNumber(double* output, const char* error) { - if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { - *output = io::Tokenizer::ParseFloat(input_->current().text); - input_->Next(); - return true; - } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - // Also accept integers. - uint64 value = 0; - if (!io::Tokenizer::ParseInteger(input_->current().text, - kuint64max, &value)) { - AddError("Integer out of range."); - // We still return true because we did, in fact, parse a number. - } - *output = value; - input_->Next(); - return true; - } else { - AddError(error); - return false; - } -} - -bool Parser::ConsumeString(string* output, const char* error) { - if (LookingAtType(io::Tokenizer::TYPE_STRING)) { - io::Tokenizer::ParseString(input_->current().text, output); - input_->Next(); - return true; - } else { - AddError(error); - return false; - } -} - -// ------------------------------------------------------------------- - -void Parser::AddError(int line, int column, const string& error) { - if (error_collector_ != NULL) { - error_collector_->AddError(line, column, error); - } - had_errors_ = true; -} - -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); - } -} - -void Parser::RecordLocation( - const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location) { - RecordLocation(descriptor, location, - input_->current().line, input_->current().column); -} - -// ------------------------------------------------------------------- - -void Parser::SkipStatement() { - while (true) { - if (AtEnd()) { - return; - } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsume(";")) { - return; - } else if (TryConsume("{")) { - SkipRestOfBlock(); - return; - } else if (LookingAt("}")) { - return; - } - } - input_->Next(); - } -} - -void Parser::SkipRestOfBlock() { - while (true) { - if (AtEnd()) { - return; - } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) { - if (TryConsume("}")) { - return; - } else if (TryConsume("{")) { - SkipRestOfBlock(); - } - } - input_->Next(); - } -} - -// =================================================================== - -bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { - input_ = input; - had_errors_ = false; - syntax_identifier_.clear(); - - 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; - } - } else { - syntax_identifier_ = "proto2"; - } - - // Repeatedly parse statemetns 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(); - - if (LookingAt("}")) { - AddError("Unmatched \"}\"."); - input_->Next(); - } - } - } - - input_ = NULL; - return !had_errors_; -} - -bool Parser::ParseSyntaxIdentifier() { - DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'.")); - DO(Consume("=")); - io::Tokenizer::Token syntax_token = input_->current(); - string syntax; - DO(ConsumeString(&syntax, "Expected syntax identifier.")); - DO(Consume(";")); - - syntax_identifier_ = syntax; - - if (syntax != "proto2") { - AddError(syntax_token.line, syntax_token.column, - "Unrecognized syntax identifier \"" + syntax + "\". This parser " - "only recognizes \"proto2\"."); - return false; - } - - return true; -} - -bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) { - if (TryConsume(";")) { - // empty statement; ignore - return true; - } else if (LookingAt("message")) { - return ParseMessageDefinition(file->add_message_type()); - } else if (LookingAt("enum")) { - return ParseEnumDefinition(file->add_enum_type()); - } else if (LookingAt("service")) { - return ParseServiceDefinition(file->add_service()); - } else if (LookingAt("extend")) { - return ParseExtend(file->mutable_extension(), - file->mutable_message_type()); - } else if (LookingAt("import")) { - return ParseImport(file->add_dependency()); - } else if (LookingAt("package")) { - return ParsePackage(file); - } else if (LookingAt("option")) { - return ParseOption(file->mutable_options()); - } else { - AddError("Expected top-level statement (e.g. \"message\")."); - return false; - } -} - -// ------------------------------------------------------------------- -// Messages - -bool Parser::ParseMessageDefinition(DescriptorProto* message) { - DO(Consume("message")); - RecordLocation(message, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); - DO(ParseMessageBlock(message)); - return true; -} - -bool Parser::ParseMessageBlock(DescriptorProto* message) { - DO(Consume("{")); - - while (!TryConsume("}")) { - if (AtEnd()) { - AddError("Reached end of input in message definition (missing '}')."); - return false; - } - - if (!ParseMessageStatement(message)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); - } - } - - return true; -} - -bool Parser::ParseMessageStatement(DescriptorProto* message) { - if (TryConsume(";")) { - // empty statement; ignore - return true; - } else if (LookingAt("message")) { - return ParseMessageDefinition(message->add_nested_type()); - } else if (LookingAt("enum")) { - return ParseEnumDefinition(message->add_enum_type()); - } else if (LookingAt("extensions")) { - return ParseExtensions(message); - } else if (LookingAt("extend")) { - return ParseExtend(message->mutable_extension(), - message->mutable_nested_type()); - } else if (LookingAt("option")) { - return ParseOption(message->mutable_options()); - } else { - return ParseMessageField(message->add_field(), - message->mutable_nested_type()); - } -} - -bool Parser::ParseMessageField(FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages) { - // 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); - } - - // Parse name and '='. - RecordLocation(field, DescriptorPool::ErrorCollector::NAME); - io::Tokenizer::Token name_token = input_->current(); - 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); - - // Parse options. - DO(ParseFieldOptions(field)); - - // Deal with groups. - if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) { - 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); - - // 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 - // not use groups; it should use nested messages. - if (group->name()[0] < 'A' || 'Z' < group->name()[0]) { - AddError(name_token.line, name_token.column, - "Group names must start with a capital letter."); - } - LowerString(field->mutable_name()); - - field->set_type_name(group->name()); - if (LookingAt("{")) { - DO(ParseMessageBlock(group)); - } else { - AddError("Missing group body."); - return false; - } - } else { - DO(Consume(";")); - } - - return true; -} - -bool Parser::ParseFieldOptions(FieldDescriptorProto* field) { - if (!TryConsume("[")) return true; - - // Parse field options. - do { - if (LookingAt("default")) { - DO(ParseDefaultAssignment(field)); - } else { - DO(ParseOptionAssignment(field->mutable_options())); - } - } while (TryConsume(",")); - - DO(Consume("]")); - return true; -} - -bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) { - if (field->has_default_value()) { - AddError("Already set option \"default\"."); - field->clear_default_value(); - } - - DO(Consume("default")); - DO(Consume("=")); - - RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); - string* default_value = field->mutable_default_value(); - - if (!field->has_type()) { - // The field has a type name, but we don't know if it is a message or an - // enum yet. Assume an enum for now. - DO(ConsumeIdentifier(default_value, "Expected identifier.")); - return true; - } - - switch (field->type()) { - case FieldDescriptorProto::TYPE_INT32: - case FieldDescriptorProto::TYPE_INT64: - case FieldDescriptorProto::TYPE_SINT32: - case FieldDescriptorProto::TYPE_SINT64: - case FieldDescriptorProto::TYPE_SFIXED32: - case FieldDescriptorProto::TYPE_SFIXED64: { - uint64 max_value = kint64max; - if (field->type() == FieldDescriptorProto::TYPE_INT32 || - field->type() == FieldDescriptorProto::TYPE_SINT32 || - field->type() == FieldDescriptorProto::TYPE_SFIXED32) { - max_value = kint32max; - } - - // These types can be negative. - if (TryConsume("-")) { - default_value->append("-"); - // Two's complement always has one more negative value than positive. - ++max_value; - } - // Parse the integer to verify that it is not out-of-range. - uint64 value; - DO(ConsumeInteger64(max_value, &value, "Expected integer.")); - // And stringify it again. - default_value->append(SimpleItoa(value)); - break; - } - - case FieldDescriptorProto::TYPE_UINT32: - case FieldDescriptorProto::TYPE_UINT64: - case FieldDescriptorProto::TYPE_FIXED32: - case FieldDescriptorProto::TYPE_FIXED64: { - uint64 max_value = kuint64max; - if (field->type() == FieldDescriptorProto::TYPE_UINT32 || - field->type() == FieldDescriptorProto::TYPE_FIXED32) { - max_value = kuint32max; - } - - // Numeric, not negative. - if (TryConsume("-")) { - AddError("Unsigned field can't have negative default value."); - } - // Parse the integer to verify that it is not out-of-range. - uint64 value; - DO(ConsumeInteger64(max_value, &value, "Expected integer.")); - // And stringify it again. - default_value->append(SimpleItoa(value)); - break; - } - - case FieldDescriptorProto::TYPE_FLOAT: - case FieldDescriptorProto::TYPE_DOUBLE: - // These types can be negative. - if (TryConsume("-")) { - default_value->append("-"); - } - // Parse the integer because we have to convert hex integers to decimal - // floats. - double value; - DO(ConsumeNumber(&value, "Expected number.")); - // And stringify it again. - default_value->append(SimpleDtoa(value)); - break; - - case FieldDescriptorProto::TYPE_BOOL: - if (TryConsume("true")) { - default_value->assign("true"); - } else if (TryConsume("false")) { - default_value->assign("false"); - } else { - AddError("Expected \"true\" or \"false\"."); - return false; - } - break; - - case FieldDescriptorProto::TYPE_STRING: - DO(ConsumeString(default_value, "Expected string.")); - break; - - case FieldDescriptorProto::TYPE_BYTES: - DO(ConsumeString(default_value, "Expected string.")); - *default_value = CEscape(*default_value); - break; - - case FieldDescriptorProto::TYPE_ENUM: - DO(ConsumeIdentifier(default_value, "Expected identifier.")); - break; - - case FieldDescriptorProto::TYPE_MESSAGE: - case FieldDescriptorProto::TYPE_GROUP: - AddError("Messages can't have default values."); - return false; - } - - return true; -} - -bool Parser::ParseOptionAssignment(Message* options) { - const Reflection* reflection = options->GetReflection(); - const Descriptor* descriptor = options->GetDescriptor(); - - // Parse name. - string name; - int line = input_->current().line; - int column = input_->current().column; - DO(ConsumeIdentifier(&name, "Expected option name.")); - - // Is it valid? - const FieldDescriptor* field = descriptor->FindFieldByName(name); - if (field == NULL) { - AddError(line, column, "Unknown option: " + name); - return false; - } - if (field->is_repeated()) { - AddError(line, column, "Not implemented: repeated options."); - return false; - } - if (reflection->HasField(*options, field)) { - AddError(line, column, "Option \"" + name + "\" was already set."); - return false; - } - - // Are we trying to assign a member of a message? - if (LookingAt(".")) { - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - AddError("Option \"" + name + "\" is an atomic type, not a message."); - return false; - } - DO(Consume(".")); - - // This field is a message/group. The user must identify a field within - // it to set. - return ParseOptionAssignment(reflection->MutableMessage(options, field)); - } - - DO(Consume("=")); - - // Parse the option value. - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: { - uint64 value; - bool is_negative = TryConsume("-"); - uint64 max_value = kint32max; - if (is_negative) ++max_value; - DO(ConsumeInteger64(max_value, &value, "Expected integer.")); - reflection->SetInt32(options, field, is_negative ? -value : value); - break; - } - - case FieldDescriptor::CPPTYPE_INT64: { - uint64 value; - bool is_negative = TryConsume("-"); - uint64 max_value = kint64max; - if (is_negative) ++max_value; - DO(ConsumeInteger64(max_value, &value, "Expected integer.")); - reflection->SetInt64(options, field, is_negative ? -value : value); - break; - } - - case FieldDescriptor::CPPTYPE_UINT32: { - uint64 value; - DO(ConsumeInteger64(kuint32max, &value, "Expected integer.")); - reflection->SetUInt32(options, field, value); - break; - } - - case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value; - DO(ConsumeInteger64(kuint64max, &value, "Expected integer.")); - reflection->SetUInt64(options, field, value); - break; - } - - case FieldDescriptor::CPPTYPE_DOUBLE: { - double value; - bool is_negative = TryConsume("-"); - DO(ConsumeNumber(&value, "Expected number.")); - reflection->SetDouble(options, field, is_negative ? -value : value); - break; - } - - case FieldDescriptor::CPPTYPE_FLOAT: { - double value; - bool is_negative = TryConsume("-"); - DO(ConsumeNumber(&value, "Expected number.")); - reflection->SetFloat(options, field, is_negative ? -value : value); - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: - if (TryConsume("true")) { - reflection->SetBool(options, field, true); - } else if (TryConsume("false")) { - reflection->SetBool(options, field, false); - } else { - AddError("Expected \"true\" or \"false\"."); - return false; - } - break; - - case FieldDescriptor::CPPTYPE_ENUM: { - string value_name; - int value_line = input_->current().line; - int value_column = input_->current().column; - DO(ConsumeIdentifier(&value_name, "Expected enum value.")); - const EnumValueDescriptor* value = - field->enum_type()->FindValueByName(value_name); - if (value == NULL) { - AddError(value_line, value_column, - "Enum type \"" + field->enum_type()->full_name() + "\" has no value " - "named \"" + value_name + "\"."); - return false; - } - reflection->SetEnum(options, field, value); - break; - } - - case FieldDescriptor::CPPTYPE_STRING: { - string value; - DO(ConsumeString(&value, "Expected string.")); - reflection->SetString(options, field, value); - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: { - // TODO(kenton): Allow use of protocol buffer text format here? - AddError("\"" + name + "\" is a message. To set fields within it, use " - "syntax like \"" + name + ".foo = value\"."); - return false; - break; - } - } - - return true; -} - -bool Parser::ParseExtensions(DescriptorProto* message) { - // Parse the declaration. - DO(Consume("extensions")); - - do { - DescriptorProto::ExtensionRange* range = message->add_extension_range(); - RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER); - - int start, end; - DO(ConsumeInteger(&start, "Expected field number range.")); - - if (TryConsume("to")) { - if (TryConsume("max")) { - end = FieldDescriptor::kMaxNumber; - } else { - DO(ConsumeInteger(&end, "Expected integer.")); - } - } else { - end = start; - } - - // Users like to specify inclusive ranges, but in code we like the end - // number to be exclusive. - ++end; - - range->set_start(start); - range->set_end(end); - } while (TryConsume(",")); - - DO(Consume(";")); - return true; -} - -bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, - RepeatedPtrField<DescriptorProto>* messages) { - 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())); - - // Parse the block. - DO(Consume("{")); - - bool is_first = true; - - do { - if (AtEnd()) { - AddError("Reached end of input in extend definition (missing '}')."); - return false; - } - - FieldDescriptorProto* field; - if (is_first) { - field = first_field; - is_first = false; - } else { - field = extensions->Add(); - field->set_extendee(first_field->extendee()); - } - - if (!ParseMessageField(field, messages)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); - } - } while(!TryConsume("}")); - - return true; -} - -// ------------------------------------------------------------------- -// Enums - -bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) { - DO(Consume("enum")); - RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); - DO(ParseEnumBlock(enum_type)); - return true; -} - -bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) { - DO(Consume("{")); - - while (!TryConsume("}")) { - if (AtEnd()) { - AddError("Reached end of input in enum definition (missing '}')."); - return false; - } - - if (!ParseEnumStatement(enum_type)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); - } - } - - return true; -} - -bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) { - if (TryConsume(";")) { - // empty statement; ignore - return true; - } else if (LookingAt("option")) { - return ParseOption(enum_type->mutable_options()); - } else { - return ParseEnumConstant(enum_type->add_value()); - } -} - -bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) { - RecordLocation(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); - - // TODO(kenton): Options for enum values? - - DO(Consume(";")); - - return true; -} - -// ------------------------------------------------------------------- -// Services - -bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) { - DO(Consume("service")); - RecordLocation(service, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); - DO(ParseServiceBlock(service)); - return true; -} - -bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) { - DO(Consume("{")); - - while (!TryConsume("}")) { - if (AtEnd()) { - AddError("Reached end of input in service definition (missing '}')."); - return false; - } - - if (!ParseServiceStatement(service)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); - } - } - - return true; -} - -bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) { - if (TryConsume(";")) { - // empty statement; ignore - return true; - } else if (LookingAt("option")) { - return ParseOption(service->mutable_options()); - } else { - return ParseServiceMethod(service->add_method()); - } -} - -bool Parser::ParseServiceMethod(MethodDescriptorProto* method) { - DO(Consume("rpc")); - RecordLocation(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())); - DO(Consume(")")); - - // Parse output type. - DO(Consume("returns")); - DO(Consume("(")); - RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); - DO(ParseUserDefinedType(method->mutable_output_type())); - DO(Consume(")")); - - if (TryConsume("{")) { - // Options! - while (!TryConsume("}")) { - if (AtEnd()) { - AddError("Reached end of input in method options (missing '}')."); - return false; - } - - if (TryConsume(";")) { - // empty statement; ignore - } else { - if (!ParseOption(method->mutable_options())) { - // This statement failed to parse. Skip it, but keep looping to - // parse other statements. - SkipStatement(); - } - } - } - } else { - DO(Consume(";")); - } - - return true; -} - -// ------------------------------------------------------------------- - -bool Parser::ParseLabel(FieldDescriptorProto::Label* label) { - if (TryConsume("optional")) { - *label = FieldDescriptorProto::LABEL_OPTIONAL; - return true; - } else if (TryConsume("repeated")) { - *label = FieldDescriptorProto::LABEL_REPEATED; - return true; - } else if (TryConsume("required")) { - *label = FieldDescriptorProto::LABEL_REQUIRED; - return true; - } else { - AddError("Expected \"required\", \"optional\", or \"repeated\"."); - // We can actually reasonably recover here by just assuming the user - // forgot the label altogether. - *label = FieldDescriptorProto::LABEL_OPTIONAL; - return true; - } -} - -bool Parser::ParseType(FieldDescriptorProto::Type* type, - string* type_name) { - TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); - if (iter != kTypeNames.end()) { - *type = iter->second; - input_->Next(); - } else { - DO(ParseUserDefinedType(type_name)); - } - return true; -} - -bool Parser::ParseUserDefinedType(string* type_name) { - type_name->clear(); - - TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text); - if (iter != kTypeNames.end()) { - // Note: The only place enum types are allowed is for field types, but - // if we are parsing a field type then we would not get here because - // primitives are allowed there as well. So this error message doesn't - // need to account for enums. - AddError("Expected message type."); - - // Pretend to accept this type so that we can go on parsing. - *type_name = input_->current().text; - input_->Next(); - return true; - } - - // A leading "." means the name is fully-qualified. - if (TryConsume(".")) type_name->append("."); - - // Consume the first part of the name. - string identifier; - DO(ConsumeIdentifier(&identifier, "Expected type name.")); - type_name->append(identifier); - - // Consume more parts. - while (TryConsume(".")) { - type_name->append("."); - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - type_name->append(identifier); - } - - return true; -} - -// =================================================================== - -bool Parser::ParsePackage(FileDescriptorProto* file) { - if (file->has_package()) { - AddError("Multiple package definitions."); - // Don't append the new package to the old one. Just replace it. Not - // that it really matters since this is an error anyway. - file->clear_package(); - } - - DO(Consume("package")); - - RecordLocation(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("."); - } - - DO(Consume(";")); - return true; -} - -bool Parser::ParseImport(string* import_filename) { - DO(Consume("import")); - DO(ConsumeString(import_filename, - "Expected a string naming the file to import.")); - DO(Consume(";")); - return true; -} - -bool Parser::ParseOption(Message* options) { - DO(Consume("option")); - DO(ParseOptionAssignment(options)); - DO(Consume(";")); - return true; -} - -// =================================================================== - -SourceLocationTable::SourceLocationTable() {} -SourceLocationTable::~SourceLocationTable() {} - -bool SourceLocationTable::Find( - const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int* line, int* column) const { - const pair<int, int>* result = - FindOrNull(location_map_, make_pair(descriptor, location)); - if (result == NULL) { - *line = -1; - *column = 0; - return false; - } else { - *line = result->first; - *column = result->second; - return true; - } -} - -void SourceLocationTable::Add( - const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int line, int column) { - location_map_[make_pair(descriptor, location)] = make_pair(line, column); -} - -void SourceLocationTable::Clear() { - location_map_.clear(); -} - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h deleted file mode 100644 index adf6e9b1..00000000 --- a/src/google/protobuf/compiler/parser.h +++ /dev/null @@ -1,301 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Implements parsing of .proto files to FileDescriptorProtos. - -#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__ -#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__ - -#include <map> -#include <string> -#include <utility> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/repeated_field.h> -#include <google/protobuf/io/tokenizer.h> - -namespace google { -namespace protobuf { class Message; } - -namespace protobuf { -namespace compiler { - -// Defined in this file. -class Parser; -class SourceLocationTable; - -// Implements parsing of protocol definitions (such as .proto files). -// -// Note that most users will be more interested in the Importer class. -// Parser is a lower-level class which simply converts a single .proto file -// to a FileDescriptorProto. It does not resolve import directives or perform -// many other kinds of validation needed to construct a complete -// FileDescriptor. -class LIBPROTOBUF_EXPORT Parser { - public: - Parser(); - ~Parser(); - - // Parse the entire input and construct a FileDescriptorProto representing - // it. Returns true if no errors occurred, false otherwise. - bool Parse(io::Tokenizer* input, FileDescriptorProto* file); - - // Optional fetaures: - - // 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. - // Set to NULL (the default) to discard source location information. - void RecordSourceLocationsTo(SourceLocationTable* location_table) { - source_location_table_ = location_table; - } - - // Requsets 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; - } - - // Returns the identifier used in the "syntax = " declaration, if one was - // seen during the last call to Parse(), or the empty string otherwise. - const string& GetSyntaxIndentifier() { return syntax_identifier_; } - - // If set true, input files will be required to begin with a syntax - // identifier. Otherwise, files may omit this. If a syntax identifier - // is provided, it must be 'syntax = "proto2";' and must appear at the - // top of this file regardless of whether or not it was required. - void SetRequireSyntaxIdentifier(bool value) { - require_syntax_identifier_ = value; - } - - private: - // ================================================================= - // Error recovery helpers - - // Consume the rest of the current statement. This consumes tokens - // until it sees one of: - // ';' Consumes the token and returns. - // '{' Consumes the brace then calls SkipRestOfBlock(). - // '}' Returns without consuming. - // EOF Returns (can't consume). - // The Parser often calls SkipStatement() after encountering a syntax - // error. This allows it to go on parsing the following lines, allowing - // it to report more than just one error in the file. - void SkipStatement(); - - // Consume the rest of the current block, including nested blocks, - // ending after the closing '}' is encountered and consumed, or at EOF. - void SkipRestOfBlock(); - - // ----------------------------------------------------------------- - // Single-token consuming helpers - // - // These make parsing code more readable. - - // True if the current token is TYPE_END. - inline bool AtEnd(); - - // True if the next token matches the given text. - inline bool LookingAt(const char* text); - // True if the next token is of the given type. - inline bool LookingAtType(io::Tokenizer::TokenType token_type); - - // If the next token exactly matches the text given, consume it and return - // true. Otherwise, return false without logging an error. - bool TryConsume(const char* text); - - // These attempt to read some kind of token from the input. If successful, - // they return true. Otherwise they return false and add the given error - // to the error list. - - // Consume a token with the exact text given. - bool Consume(const char* text, const char* error); - // Same as above, but automatically generates the error "Expected \"text\".", - // where "text" is the expected token text. - bool Consume(const char* text); - // Consume a token of type IDENTIFIER and store its text in "output". - bool ConsumeIdentifier(string* output, const char* error); - // Consume an integer and store its value in "output". - bool ConsumeInteger(int* output, const char* error); - // Consume a 64-bit integer and store its value in "output". If the value - // is greater than max_value, an error will be reported. - bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error); - // Consume a number and store its value in "output". This will accept - // tokens of either INTEGER or FLOAT type. - bool ConsumeNumber(double* output, const char* error); - // Consume a string literal and store its (unescaped) value in "output". - bool ConsumeString(string* output, const char* error); - - // ----------------------------------------------------------------- - // Error logging helpers - - // Invokes error_collector_->AddError(), if error_collector_ is not NULL. - void AddError(int line, int column, const string& error); - - // Invokes error_collector_->AddError() with the line and column number - // 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); - - // ================================================================= - // Parsers for various language constructs - - // Parses the "syntax = \"proto2\";" line at the top of the file. Returns - // false if it failed to parse or if the syntax identifier was not - // recognized. - bool ParseSyntaxIdentifier(); - - // These methods parse various individual bits of code. They return - // false if they completely fail to parse the construct. In this case, - // it is probably necessary to skip the rest of the statement to recover. - // However, if these methods return true, it does NOT mean that there - // were no errors; only that there were no *syntax* errors. For instance, - // if a service method is defined using proper syntax but uses a primitive - // type as its input or output, ParseMethodField() still returns true - // and only reports the error by calling AddError(). In practice, this - // makes logic much simpler for the caller. - - // Parse a top-level message, enum, service, etc. - bool ParseTopLevelStatement(FileDescriptorProto* file); - - // 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); - - // 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); - - // 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); - - // Parse a field of a message. If the field is a group, its type will be - // added to "messages". - bool ParseMessageField(FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages); - - // Parse an "extensions" declaration. - bool ParseExtensions(DescriptorProto* message); - - // Parse an "extend" declaration. - bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, - RepeatedPtrField<DescriptorProto>* messages); - - // Parse a single enum value within an enum block. - bool ParseEnumConstant(EnumValueDescriptorProto* enum_value); - - // Parse a single method within a service definition. - bool ParseServiceMethod(MethodDescriptorProto* method); - - // Parse "required", "optional", or "repeated" and fill in "label" - // with the value. - bool ParseLabel(FieldDescriptorProto::Label* label); - - // Parse a type name and fill in "type" (if it is a primitive) or - // "type_name" (if it is not) with the type parsed. - bool ParseType(FieldDescriptorProto::Type* type, - string* type_name); - // Parse a user-defined type and fill in "type_name" with the name. - // If a primitive type is named, it is treated as an error. - bool ParseUserDefinedType(string* type_name); - - // 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); - - // Parse the "default" option. This needs special handling because its - // type is the field's type. - bool ParseDefaultAssignment(FieldDescriptorProto* field); - - // 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); - - // ================================================================= - - io::Tokenizer* input_; - io::ErrorCollector* error_collector_; - SourceLocationTable* source_location_table_; - bool had_errors_; - bool require_syntax_identifier_; - string syntax_identifier_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser); -}; - -// A table mapping (descriptor, ErrorLocation) pairs -- as reported by -// DescriptorPool when validating descriptors -- to line and column numbers -// within the original source code. -class LIBPROTOBUF_EXPORT SourceLocationTable { - public: - SourceLocationTable(); - ~SourceLocationTable(); - - // Finds the precise location of the given error and fills in *line and - // *column with the line and column numbers. If not found, sets *line to - // -1 and *column to 0 (since line = -1 is used to mean "error has no exact - // location" in the ErrorCollector interface). Returns true if found, false - // otherwise. - bool Find(const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int* line, int* column) const; - - // Adds a location to the table. - void Add(const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int line, int column); - - // Clears the contents of the table. - void Clear(); - - private: - typedef map< - pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>, - pair<int, int> > LocationMap; - LocationMap location_map_; -}; - -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__ diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc deleted file mode 100644 index 489106b0..00000000 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ /dev/null @@ -1,1142 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> -#include <algorithm> - -#include <google/protobuf/compiler/parser.h> - -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace compiler { - -namespace { - -class MockErrorCollector : public io::ErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(int line, int column, const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", - line, column, message); - } -}; - -class MockValidationErrorCollector : public DescriptorPool::ErrorCollector { - public: - MockValidationErrorCollector(const SourceLocationTable& source_locations, - io::ErrorCollector* wrapped_collector) - : source_locations_(source_locations), - wrapped_collector_(wrapped_collector) {} - ~MockValidationErrorCollector() {} - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, - const string& element_name, - const Message* descriptor, - ErrorLocation location, - const string& message) { - int line, column; - source_locations_.Find(descriptor, location, &line, &column); - wrapped_collector_->AddError(line, column, message); - } - - private: - const SourceLocationTable& source_locations_; - io::ErrorCollector* wrapped_collector_; -}; - -class ParserTest : public testing::Test { - protected: - ParserTest() - : require_syntax_identifier_(false) {} - - // Set up the parser to parse the given text. - void SetupParser(const char* text) { - raw_input_.reset(new io::ArrayInputStream(text, strlen(text))); - input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_)); - parser_.reset(new Parser()); - parser_->RecordErrorsTo(&error_collector_); - parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_); - } - - // Parse the input and expect that the resulting FileDescriptorProto matches - // the given output. The output is a FileDescriptorProto in protocol buffer - // text format. - void ExpectParsesTo(const char* input, const char* output) { - SetupParser(input); - FileDescriptorProto actual, expected; - - parser_->Parse(input_.get(), &actual); - EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); - ASSERT_EQ("", error_collector_.text_); - - // 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() - // produces. - ASSERT_TRUE(TextFormat::ParseFromString(output, &expected)); - - // Compare by comparing debug strings. - // TODO(kenton): Use differencer, once it is available. - EXPECT_EQ(expected.DebugString(), actual.DebugString()); - } - - // Parse the text and expect that the given errors are reported. - void ExpectHasErrors(const char* text, const char* expected_errors) { - ExpectHasEarlyExitErrors(text, expected_errors); - EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); - } - - // Same as above but does not expect that the parser parses the complete - // input. - void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) { - SetupParser(text); - FileDescriptorProto file; - parser_->Parse(input_.get(), &file); - EXPECT_EQ(expected_errors, error_collector_.text_); - } - - // Parse the text as a file and validate it (with a DescriptorPool), and - // expect that the validation step reports the given errors. - void ExpectHasValidationErrors(const char* text, - const char* expected_errors) { - SetupParser(text); - SourceLocationTable source_locations; - parser_->RecordSourceLocationsTo(&source_locations); - - FileDescriptorProto file; - file.set_name("foo.proto"); - parser_->Parse(input_.get(), &file); - EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); - ASSERT_EQ("", error_collector_.text_); - - MockValidationErrorCollector validation_error_collector( - source_locations, &error_collector_); - EXPECT_TRUE(pool_.BuildFileCollectingErrors( - file, &validation_error_collector) == NULL); - EXPECT_EQ(expected_errors, error_collector_.text_); - } - - MockErrorCollector error_collector_; - DescriptorPool pool_; - - scoped_ptr<io::ZeroCopyInputStream> raw_input_; - scoped_ptr<io::Tokenizer> input_; - scoped_ptr<Parser> parser_; - bool require_syntax_identifier_; -}; - -// =================================================================== - -typedef ParserTest ParseMessageTest; - -TEST_F(ParseMessageTest, SimpleMessage) { - ExpectParsesTo( - "message TestMessage {\n" - " required int32 foo = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" - "}"); -} - -TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) { - require_syntax_identifier_ = false; - ExpectParsesTo( - "message TestMessage {\n" - " required int32 foo = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" - "}"); - EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) { - ExpectParsesTo( - "syntax = \"proto2\";\n" - "message TestMessage {\n" - " required int32 foo = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" - "}"); - EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) { - require_syntax_identifier_ = true; - ExpectParsesTo( - "syntax = \"proto2\";\n" - "message TestMessage {\n" - " required int32 foo = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" - "}"); - EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseMessageTest, SimpleFields) { - ExpectParsesTo( - "message TestMessage {\n" - " required int32 foo = 15;\n" - " optional int32 bar = 34;\n" - " repeated int32 baz = 3;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }" - " field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }" - " field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3 }" - "}"); -} - -TEST_F(ParseMessageTest, PrimitiveFieldTypes) { - ExpectParsesTo( - "message TestMessage {\n" - " required int32 foo = 1;\n" - " required int64 foo = 1;\n" - " required uint32 foo = 1;\n" - " required uint64 foo = 1;\n" - " required sint32 foo = 1;\n" - " required sint64 foo = 1;\n" - " required fixed32 foo = 1;\n" - " required fixed64 foo = 1;\n" - " required sfixed32 foo = 1;\n" - " required sfixed64 foo = 1;\n" - " required float foo = 1;\n" - " required double foo = 1;\n" - " required string foo = 1;\n" - " required bytes foo = 1;\n" - " required bool foo = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES number:1 }" - " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL number:1 }" - "}"); -} - -TEST_F(ParseMessageTest, FieldDefaults) { - ExpectParsesTo( - "message TestMessage {\n" - " required int32 foo = 1 [default= 1 ];\n" - " required int32 foo = 1 [default= -2 ];\n" - " required int64 foo = 1 [default= 3 ];\n" - " required int64 foo = 1 [default= -4 ];\n" - " required uint32 foo = 1 [default= 5 ];\n" - " required uint64 foo = 1 [default= 6 ];\n" - " required float foo = 1 [default= 7.5];\n" - " required float foo = 1 [default= -8.5];\n" - " required float foo = 1 [default= 9 ];\n" - " required double foo = 1 [default= 10.5];\n" - " required double foo = 1 [default=-11.5];\n" - " required double foo = 1 [default= 12 ];\n" - " required string foo = 1 [default='13\\001'];\n" - " required bytes foo = 1 [default='14\\002'];\n" - " required bool foo = 1 [default=true ];\n" - " required Foo foo = 1 [default=FOO ];\n" - - " required int32 foo = 1 [default= 0x7FFFFFFF];\n" - " required int32 foo = 1 [default=-0x80000000];\n" - " required uint32 foo = 1 [default= 0xFFFFFFFF];\n" - " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n" - " required int64 foo = 1 [default=-0x8000000000000000];\n" - " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n" - " required double foo = 1 [default= 0xabcd];\n" - "}\n", - -#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1" - "message_type {" - " name: \"TestMessage\"" - " field { type:TYPE_INT32 default_value:\"1\" "ETC" }" - " field { type:TYPE_INT32 default_value:\"-2\" "ETC" }" - " field { type:TYPE_INT64 default_value:\"3\" "ETC" }" - " field { type:TYPE_INT64 default_value:\"-4\" "ETC" }" - " field { type:TYPE_UINT32 default_value:\"5\" "ETC" }" - " field { type:TYPE_UINT64 default_value:\"6\" "ETC" }" - " field { type:TYPE_FLOAT default_value:\"7.5\" "ETC" }" - " field { type:TYPE_FLOAT default_value:\"-8.5\" "ETC" }" - " field { type:TYPE_FLOAT default_value:\"9\" "ETC" }" - " field { type:TYPE_DOUBLE default_value:\"10.5\" "ETC" }" - " field { type:TYPE_DOUBLE default_value:\"-11.5\" "ETC" }" - " field { type:TYPE_DOUBLE default_value:\"12\" "ETC" }" - " field { type:TYPE_STRING default_value:\"13\\001\" "ETC" }" - " field { type:TYPE_BYTES default_value:\"14\\\\002\" "ETC" }" - " field { type:TYPE_BOOL default_value:\"true\" "ETC" }" - " field { type_name:\"Foo\" default_value:\"FOO\" "ETC" }" - - " field { type:TYPE_INT32 default_value:\"2147483647\" "ETC" }" - " field { type:TYPE_INT32 default_value:\"-2147483648\" "ETC" }" - " field { type:TYPE_UINT32 default_value:\"4294967295\" "ETC" }" - " field { type:TYPE_INT64 default_value:\"9223372036854775807\" "ETC" }" - " field { type:TYPE_INT64 default_value:\"-9223372036854775808\" "ETC" }" - " field { type:TYPE_UINT64 default_value:\"18446744073709551615\" "ETC" }" - " field { type:TYPE_DOUBLE default_value:\"43981\" "ETC" }" - "}"); -#undef ETC -} - -TEST_F(ParseMessageTest, FieldOptions) { - ExpectParsesTo( - "message TestMessage {\n" - " optional string foo = 1 [ctype=CORD];\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_STRING number:1" - " options { ctype:CORD } }" - "}"); -} - -TEST_F(ParseMessageTest, Group) { - ExpectParsesTo( - "message TestMessage {\n" - " optional group TestGroup = 1 {};\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " nested_type { name: \"TestGroup\" }" - " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1" - " type:TYPE_GROUP type_name: \"TestGroup\" }" - "}"); -} - -TEST_F(ParseMessageTest, NestedMessage) { - ExpectParsesTo( - "message TestMessage {\n" - " message Nested {}\n" - " optional Nested test_nested = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " nested_type { name: \"Nested\" }" - " field { name:\"test_nested\" label:LABEL_OPTIONAL number:1" - " type_name: \"Nested\" }" - "}"); -} - -TEST_F(ParseMessageTest, NestedEnum) { - ExpectParsesTo( - "message TestMessage {\n" - " enum NestedEnum {}\n" - " optional NestedEnum test_enum = 1;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " enum_type { name: \"NestedEnum\" }" - " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1" - " type_name: \"NestedEnum\" }" - "}"); -} - -TEST_F(ParseMessageTest, ExtensionRange) { - ExpectParsesTo( - "message TestMessage {\n" - " extensions 10 to 19;\n" - " extensions 30 to max;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " extension_range { start:10 end:20 }" - " extension_range { start:30 end:536870912 }" - "}"); -} - -TEST_F(ParseMessageTest, CompoundExtensionRange) { - ExpectParsesTo( - "message TestMessage {\n" - " extensions 2, 15, 9 to 11, 100 to max, 3;\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " extension_range { start:2 end:3 }" - " extension_range { start:15 end:16 }" - " extension_range { start:9 end:12 }" - " extension_range { start:100 end:536870912 }" - " extension_range { start:3 end:4 }" - "}"); -} - -TEST_F(ParseMessageTest, Extensions) { - ExpectParsesTo( - "extend Extendee1 { optional int32 foo = 12; }\n" - "extend Extendee2 { repeated TestMessage bar = 22; }\n", - - "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" - " extendee: \"Extendee1\" } " - "extension { name:\"bar\" label:LABEL_REPEATED number:22" - " type_name:\"TestMessage\" extendee: \"Extendee2\" }"); -} - -TEST_F(ParseMessageTest, ExtensionsInMessageScope) { - ExpectParsesTo( - "message TestMessage {\n" - " extend Extendee1 { optional int32 foo = 12; }\n" - " extend Extendee2 { repeated TestMessage bar = 22; }\n" - "}\n", - - "message_type {" - " name: \"TestMessage\"" - " extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" - " extendee: \"Extendee1\" }" - " extension { name:\"bar\" label:LABEL_REPEATED number:22" - " type_name:\"TestMessage\" extendee: \"Extendee2\" }" - "}"); -} - -TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) { - ExpectParsesTo( - "extend Extendee1 {\n" - " optional int32 foo = 12;\n" - " repeated TestMessage bar = 22;\n" - "}\n", - - "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12" - " extendee: \"Extendee1\" } " - "extension { name:\"bar\" label:LABEL_REPEATED number:22" - " type_name:\"TestMessage\" extendee: \"Extendee1\" }"); -} - -// =================================================================== - -typedef ParserTest ParseEnumTest; - -TEST_F(ParseEnumTest, SimpleEnum) { - ExpectParsesTo( - "enum TestEnum {\n" - " FOO = 0;\n" - "}\n", - - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"FOO\" number:0 }" - "}"); -} - -TEST_F(ParseEnumTest, Values) { - ExpectParsesTo( - "enum TestEnum {\n" - " FOO = 13;\n" - " BAR = -10;\n" - " BAZ = 500;\n" - "}\n", - - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"FOO\" number:13 }" - " value { name:\"BAR\" number:-10 }" - " value { name:\"BAZ\" number:500 }" - "}"); -} - -// =================================================================== - -typedef ParserTest ParseServiceTest; - -TEST_F(ParseServiceTest, SimpleService) { - ExpectParsesTo( - "service TestService {\n" - " rpc Foo(In) returns (Out);\n" - "}\n", - - "service {" - " name: \"TestService\"" - " method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }" - "}"); -} - -TEST_F(ParseServiceTest, Methods) { - ExpectParsesTo( - "service TestService {\n" - " rpc Foo(In1) returns (Out1);\n" - " rpc Bar(In2) returns (Out2);\n" - " rpc Baz(In3) returns (Out3);\n" - "}\n", - - "service {" - " name: \"TestService\"" - " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }" - " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }" - " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }" - "}"); -} - -// =================================================================== -// imports and packages - -typedef ParserTest ParseMiscTest; - -TEST_F(ParseMiscTest, ParseImport) { - ExpectParsesTo( - "import \"foo/bar/baz.proto\";\n", - "dependency: \"foo/bar/baz.proto\""); -} - -TEST_F(ParseMiscTest, ParseMultipleImports) { - ExpectParsesTo( - "import \"foo.proto\";\n" - "import \"bar.proto\";\n" - "import \"baz.proto\";\n", - "dependency: \"foo.proto\"" - "dependency: \"bar.proto\"" - "dependency: \"baz.proto\""); -} - -TEST_F(ParseMiscTest, ParsePackage) { - ExpectParsesTo( - "package foo.bar.baz;\n", - "package: \"foo.bar.baz\""); -} - -TEST_F(ParseMiscTest, ParsePackageWithSpaces) { - ExpectParsesTo( - "package foo . bar. \n" - " baz;\n", - "package: \"foo.bar.baz\""); -} - -// =================================================================== -// options - -TEST_F(ParseMiscTest, ParseFileOptions) { - ExpectParsesTo( - "option java_package = \"com.google.foo\";\n" - "option optimize_for = CODE_SIZE;", - - "options {" - " java_package: \"com.google.foo\"" - " optimize_for: CODE_SIZE" - "}"); -} - -// TODO(kenton): We'd like to be able to test all possible option types, -// but we are unable to do so here because we can only test the options -// that actually exist, which currently doesn't cover everything. Perhaps -// we can solve this in the future by allowing options to be extended, then -// defining extensions of every type? - -// =================================================================== -// Error tests -// -// There are a very large number of possible errors that the parser could -// report, so it's infeasible to test every single one of them. Instead, -// we test each unique call to AddError() in parser.h. This does not mean -// we are testing every possible error that Parser can generate because -// each variant of the Consume() helper only counts as one unique call to -// AddError(). - -typedef ParserTest ParseErrorTest; - -TEST_F(ParseErrorTest, MissingSyntaxIdentifier) { - require_syntax_identifier_ = true; - ExpectHasEarlyExitErrors( - "message TestMessage {}", - "0:0: File must begin with 'syntax = \"proto2\";'.\n"); - EXPECT_EQ("", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) { - ExpectHasEarlyExitErrors( - "syntax = \"no_such_syntax\";", - "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser " - "only recognizes \"proto2\".\n"); - EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseErrorTest, SimpleSyntaxError) { - ExpectHasErrors( - "message TestMessage @#$ { blah }", - "0:20: Expected \"{\".\n"); - EXPECT_EQ("proto2", parser_->GetSyntaxIndentifier()); -} - -TEST_F(ParseErrorTest, ExpectedTopLevel) { - ExpectHasErrors( - "blah;", - "0:0: Expected top-level statement (e.g. \"message\").\n"); -} - -TEST_F(ParseErrorTest, UnmatchedCloseBrace) { - // This used to cause an infinite loop. Doh. - ExpectHasErrors( - "}", - "0:0: Expected top-level statement (e.g. \"message\").\n" - "0:0: Unmatched \"}\".\n"); -} - -// ------------------------------------------------------------------- -// Message errors - -TEST_F(ParseErrorTest, MessageMissingName) { - ExpectHasErrors( - "message {}", - "0:8: Expected message name.\n"); -} - -TEST_F(ParseErrorTest, MessageMissingBody) { - ExpectHasErrors( - "message TestMessage;", - "0:19: Expected \"{\".\n"); -} - -TEST_F(ParseErrorTest, EofInMessage) { - ExpectHasErrors( - "message TestMessage {", - "0:21: Reached end of input in message definition (missing '}').\n"); -} - -TEST_F(ParseErrorTest, MissingFieldNumber) { - ExpectHasErrors( - "message TestMessage {\n" - " optional int32 foo;\n" - "}\n", - "1:20: Missing field number.\n"); -} - -TEST_F(ParseErrorTest, ExpectedFieldNumber) { - ExpectHasErrors( - "message TestMessage {\n" - " optional int32 foo = ;\n" - "}\n", - "1:23: Expected field number.\n"); -} - -TEST_F(ParseErrorTest, FieldNumberOutOfRange) { - ExpectHasErrors( - "message TestMessage {\n" - " optional int32 foo = 0x100000000;\n" - "}\n", - "1:23: Integer out of range.\n"); -} - -TEST_F(ParseErrorTest, MissingLabel) { - ExpectHasErrors( - "message TestMessage {\n" - " int32 foo = 1;\n" - "}\n", - "1:2: Expected \"required\", \"optional\", or \"repeated\".\n"); -} - -TEST_F(ParseErrorTest, ExpectedOptionName) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [];\n" - "}\n", - "1:27: Expected option name.\n"); -} - -TEST_F(ParseErrorTest, UnknownOption) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [nosuchoption=5];\n" - "}\n", - "1:27: Unknown option: nosuchoption\n"); -} - -TEST_F(ParseErrorTest, DefaultValueTypeMismatch) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [default=true];\n" - "}\n", - "1:35: Expected integer.\n"); -} - -TEST_F(ParseErrorTest, DefaultValueNotBoolean) { - ExpectHasErrors( - "message TestMessage {\n" - " optional bool foo = 1 [default=blah];\n" - "}\n", - "1:33: Expected \"true\" or \"false\".\n"); -} - -TEST_F(ParseErrorTest, DefaultValueNotString) { - ExpectHasErrors( - "message TestMessage {\n" - " optional string foo = 1 [default=1];\n" - "}\n", - "1:35: Expected string.\n"); -} - -TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [default=-1];\n" - "}\n", - "1:36: Unsigned field can't have negative default value.\n"); -} - -TEST_F(ParseErrorTest, DefaultValueTooLarge) { - ExpectHasErrors( - "message TestMessage {\n" - " optional int32 foo = 1 [default= 0x80000000];\n" - " optional int32 foo = 1 [default=-0x80000001];\n" - " optional uint32 foo = 1 [default= 0x100000000];\n" - " optional int64 foo = 1 [default= 0x80000000000000000];\n" - " optional int64 foo = 1 [default=-0x80000000000000001];\n" - " optional uint64 foo = 1 [default= 0x100000000000000000];\n" - "}\n", - "1:36: Integer out of range.\n" - "2:36: Integer out of range.\n" - "3:36: Integer out of range.\n" - "4:36: Integer out of range.\n" - "5:36: Integer out of range.\n" - "6:36: Integer out of range.\n"); -} - -TEST_F(ParseErrorTest, DefaultValueMissing) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [default=];\n" - "}\n", - "1:35: Expected integer.\n"); -} - -TEST_F(ParseErrorTest, DefaultValueForGroup) { - ExpectHasErrors( - "message TestMessage {\n" - " optional group Foo = 1 [default=blah] {}\n" - "}\n", - "1:34: Messages can't have default values.\n"); -} - -TEST_F(ParseErrorTest, DuplicateDefaultValue) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [default=1,default=2];\n" - "}\n", - "1:37: Already set option \"default\".\n"); -} - -TEST_F(ParseErrorTest, GroupNotCapitalized) { - ExpectHasErrors( - "message TestMessage {\n" - " optional group foo = 1 {}\n" - "}\n", - "1:17: Group names must start with a capital letter.\n"); -} - -TEST_F(ParseErrorTest, GroupMissingBody) { - ExpectHasErrors( - "message TestMessage {\n" - " optional group Foo = 1;\n" - "}\n", - "1:24: Missing group body.\n"); -} - -TEST_F(ParseErrorTest, ExtendingPrimitive) { - ExpectHasErrors( - "extend int32 { optional string foo = 4; }\n", - "0:7: Expected message type.\n"); -} - -TEST_F(ParseErrorTest, ErrorInExtension) { - ExpectHasErrors( - "message Foo { extensions 100 to 199; }\n" - "extend Foo { optional string foo; }\n", - "1:32: Missing field number.\n"); -} - -TEST_F(ParseErrorTest, MultipleParseErrors) { - // When a statement has a parse error, the parser should be able to continue - // parsing at the next statement. - ExpectHasErrors( - "message TestMessage {\n" - " optional int32 foo;\n" - " !invalid statement ending in a block { blah blah { blah } blah }\n" - " optional int32 bar = 3 {}\n" - "}\n", - "1:20: Missing field number.\n" - "2:2: Expected \"required\", \"optional\", or \"repeated\".\n" - "2:2: Expected type name.\n" - "3:25: Expected \";\".\n"); -} - -// ------------------------------------------------------------------- -// Enum errors - -TEST_F(ParseErrorTest, EofInEnum) { - ExpectHasErrors( - "enum TestEnum {", - "0:15: Reached end of input in enum definition (missing '}').\n"); -} - -TEST_F(ParseErrorTest, EnumValueMissingNumber) { - ExpectHasErrors( - "enum TestEnum {\n" - " FOO;\n" - "}\n", - "1:5: Missing numeric value for enum constant.\n"); -} - -// ------------------------------------------------------------------- -// Service errors - -TEST_F(ParseErrorTest, EofInService) { - ExpectHasErrors( - "service TestService {", - "0:21: Reached end of input in service definition (missing '}').\n"); -} - -TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) { - ExpectHasErrors( - "service TestService {\n" - " rpc Foo(int32) returns (string);\n" - "}\n", - "1:10: Expected message type.\n" - "1:26: Expected message type.\n"); -} - -TEST_F(ParseErrorTest, EofInMethodOptions) { - ExpectHasErrors( - "service TestService {\n" - " rpc Foo(Bar) returns(Bar) {", - "1:29: Reached end of input in method options (missing '}').\n" - "1:29: Reached end of input in service definition (missing '}').\n"); -} - -TEST_F(ParseErrorTest, PrimitiveMethodInput) { - ExpectHasErrors( - "service TestService {\n" - " rpc Foo(int32) returns(Bar);\n" - "}\n", - "1:10: Expected message type.\n"); -} - -TEST_F(ParseErrorTest, MethodOptionTypeError) { - // This used to cause an infinite loop. - ExpectHasErrors( - "message Baz {}\n" - "service Foo {\n" - " rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n" - "}\n", - "2:37: Unknown option: invalid\n"); -} - -// ------------------------------------------------------------------- -// Import and package errors - -TEST_F(ParseErrorTest, ImportNotQuoted) { - ExpectHasErrors( - "import foo;\n", - "0:7: Expected a string naming the file to import.\n"); -} - -TEST_F(ParseErrorTest, MultiplePackagesInFile) { - ExpectHasErrors( - "package foo;\n" - "package bar;\n", - "1:0: Multiple package definitions.\n"); -} - -// ------------------------------------------------------------------- -// Option errors - -TEST_F(ParseErrorTest, OptionWrongType) { - ExpectHasErrors( - "message TestMessage {\n" - " optional string foo = 1 [ctype=1];\n" - "}\n", - "1:33: Expected enum value.\n"); -} - -TEST_F(ParseErrorTest, DupOption) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [ctype=CORD,ctype=CORD];\n" - "}\n", - "1:38: Option \"ctype\" was already set.\n"); -} - -TEST_F(ParseErrorTest, NotMessageOption) { - ExpectHasErrors( - "message TestMessage {\n" - " optional uint32 foo = 1 [ctype.blah=1];\n" - "}\n", - "1:32: Option \"ctype\" is an atomic type, not a message.\n"); -} - -// TODO(kenton): Test errors for all possible option types (see TODO above, -// under the option parsing tests). - -// =================================================================== -// Test that errors detected by DescriptorPool correctly report line and -// column numbers. We have one test for every call to RecordLocation() in -// parser.cc. - -typedef ParserTest ParserValidationErrorTest; - -TEST_F(ParserValidationErrorTest, PackageNameError) { - // Create another file which defines symbol "foo". - FileDescriptorProto other_file; - other_file.set_name("bar.proto"); - other_file.add_message_type()->set_name("foo"); - EXPECT_TRUE(pool_.BuildFile(other_file) != NULL); - - // Now try to define it as a package. - ExpectHasValidationErrors( - "package foo.bar;", - "0:8: \"foo\" is already defined (as something other than a package) " - "in file \"bar.proto\".\n"); -} - -TEST_F(ParserValidationErrorTest, MessageNameError) { - ExpectHasValidationErrors( - "message Foo {}\n" - "message Foo {}\n", - "1:8: \"Foo\" is already defined.\n"); -} - -TEST_F(ParserValidationErrorTest, FieldNameError) { - ExpectHasValidationErrors( - "message Foo {\n" - " optional int32 bar = 1;\n" - " optional int32 bar = 2;\n" - "}\n", - "2:17: \"bar\" is already defined in \"Foo\".\n"); -} - -TEST_F(ParserValidationErrorTest, FieldTypeError) { - ExpectHasValidationErrors( - "message Foo {\n" - " optional Baz bar = 1;\n" - "}\n", - "1:11: \"Baz\" is not defined.\n"); -} - -TEST_F(ParserValidationErrorTest, FieldNumberError) { - ExpectHasValidationErrors( - "message Foo {\n" - " optional int32 bar = 0;\n" - "}\n", - "1:23: Field numbers must be positive integers.\n"); -} - -TEST_F(ParserValidationErrorTest, FieldExtendeeError) { - ExpectHasValidationErrors( - "extend Baz { optional int32 bar = 1; }\n", - "0:7: \"Baz\" is not defined.\n"); -} - -TEST_F(ParserValidationErrorTest, FieldDefaultValueError) { - ExpectHasValidationErrors( - "enum Baz { QUX = 1; }\n" - "message Foo {\n" - " optional Baz bar = 1 [default=NO_SUCH_VALUE];\n" - "}\n", - "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n"); -} - -TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) { - ExpectHasValidationErrors( - "message Foo {\n" - " extensions 0;\n" - "}\n", - "1:13: Extension numbers must be positive integers.\n"); -} - -TEST_F(ParserValidationErrorTest, EnumNameError) { - ExpectHasValidationErrors( - "enum Foo {A = 1;}\n" - "enum Foo {B = 1;}\n", - "1:5: \"Foo\" is already defined.\n"); -} - -TEST_F(ParserValidationErrorTest, EnumValueNameError) { - ExpectHasValidationErrors( - "enum Foo {\n" - " BAR = 1;\n" - " BAR = 1;\n" - "}\n", - "2:2: \"BAR\" is already defined.\n"); -} - -TEST_F(ParserValidationErrorTest, ServiceNameError) { - ExpectHasValidationErrors( - "service Foo {}\n" - "service Foo {}\n", - "1:8: \"Foo\" is already defined.\n"); -} - -TEST_F(ParserValidationErrorTest, MethodNameError) { - ExpectHasValidationErrors( - "message Baz {}\n" - "service Foo {\n" - " rpc Bar(Baz) returns(Baz);\n" - " rpc Bar(Baz) returns(Baz);\n" - "}\n", - "3:6: \"Bar\" is already defined in \"Foo\".\n"); -} - -TEST_F(ParserValidationErrorTest, MethodInputTypeError) { - ExpectHasValidationErrors( - "message Baz {}\n" - "service Foo {\n" - " rpc Bar(Qux) returns(Baz);\n" - "}\n", - "2:10: \"Qux\" is not defined.\n"); -} - -TEST_F(ParserValidationErrorTest, MethodOutputTypeError) { - ExpectHasValidationErrors( - "message Baz {}\n" - "service Foo {\n" - " rpc Bar(Baz) returns(Qux);\n" - "}\n", - "2:23: \"Qux\" is not defined.\n"); -} - -// =================================================================== -// Test that the output from FileDescriptor::DebugString() (and all other -// descriptor types) is parseable, and results in the same Descriptor -// definitions again afoter parsing (not, however, that the order of messages -// cannot be guaranteed to be the same) - -typedef ParserTest ParseDecriptorDebugTest; - -class CompareDescriptorNames { - public: - bool operator()(const DescriptorProto* left, const DescriptorProto* right) { - return left->name() < right->name(); - } -}; - -// Sorts nested DescriptorProtos of a DescriptoProto, by name. -void SortMessages(DescriptorProto *descriptor_proto) { - int size = descriptor_proto->nested_type_size(); - // recursively sort; we can't guarantee the order of nested messages either - for (int i = 0; i < size; ++i) { - SortMessages(descriptor_proto->mutable_nested_type(i)); - } - DescriptorProto **data = - descriptor_proto->mutable_nested_type()->mutable_data(); - sort(data, data + size, CompareDescriptorNames()); -} - -// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name. -void SortMessages(FileDescriptorProto *file_descriptor_proto) { - int size = file_descriptor_proto->message_type_size(); - // recursively sort; we can't guarantee the order of nested messages either - for (int i = 0; i < size; ++i) { - SortMessages(file_descriptor_proto->mutable_message_type(i)); - } - DescriptorProto **data = - file_descriptor_proto->mutable_message_type()->mutable_data(); - sort(data, data + size, CompareDescriptorNames()); -} - -TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) { - const FileDescriptor* original_file = - protobuf_unittest::TestAllTypes::descriptor()->file(); - FileDescriptorProto expected; - original_file->CopyTo(&expected); - - // Get the DebugString of the unittest.proto FileDecriptor, which includes - // all other descriptor types - string debug_string = original_file->DebugString(); - - // Parse the debug string - SetupParser(debug_string.c_str()); - FileDescriptorProto parsed; - parser_->Parse(input_.get(), &parsed); - EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); - ASSERT_EQ("", error_collector_.text_); - - // We now have a FileDescriptorProto, but to compare with the expected we - // need to link to a FileDecriptor, then output back to a proto. We'll - // also need to give it the same name as the original. - parsed.set_name("google/protobuf/unittest.proto"); - // We need the imported dependency before we can build our parsed proto - const FileDescriptor* import = - protobuf_unittest_import::ImportMessage::descriptor()->file(); - FileDescriptorProto import_proto; - import->CopyTo(&import_proto); - ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); - const FileDescriptor* actual = pool_.BuildFile(parsed); - parsed.Clear(); - actual->CopyTo(&parsed); - ASSERT_TRUE(actual != NULL); - - // The messages might be in different orders, making them hard to compare. - // So, sort the messages in the descriptor protos (including nested messages, - // recursively). - SortMessages(&expected); - SortMessages(&parsed); - - // I really wanted to use StringDiff here for the debug output on fail, - // but the strings are too long for it, and if I increase its max size, - // we get a memory allocation failure :( - EXPECT_EQ(expected.DebugString(), parsed.DebugString()); -} - -// =================================================================== - -} // anonymous namespace - -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc deleted file mode 100644 index e1171382..00000000 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ /dev/null @@ -1,794 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: robinson@google.com (Will Robinson) -// -// This module outputs pure-Python protocol message classes that will -// largely be constructed at runtime via the metaclass in reflection.py. -// In other words, our job is basically to output a Python equivalent -// of the C++ *Descriptor objects, and fix up all circular references -// within these objects. -// -// Note that the runtime performance of protocol message classes created in -// this way is expected to be lousy. The plan is to create an alternate -// generator that outputs a Python/C extension module that lets -// performance-minded Python code leverage the fast C++ implementation -// directly. - -#include <utility> -#include <map> -#include <string> -#include <vector> - -#include <google/protobuf/compiler/python/python_generator.h> -#include <google/protobuf/descriptor.pb.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace python { - -namespace { - -// Returns a copy of |filename| with any trailing ".protodevel" or ".proto -// suffix stripped. -// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. -string StripProto(const string& filename) { - const char* suffix = HasSuffixString(filename, ".protodevel") - ? ".protodevel" : ".proto"; - return StripSuffixString(filename, suffix); -} - - -// Returns the Python module name expected for a given .proto filename. -string ModuleName(const string& filename) { - string basename = StripProto(filename); - StripString(&basename, "-", '_'); - StripString(&basename, "/", '.'); - return basename + "_pb2"; -} - - -// Returns the name of all containing types for descriptor, -// in order from outermost to innermost, followed by descriptor's -// own name. Each name is separated by |separator|. -template <typename DescriptorT> -string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, - const string& separator) { - string name = descriptor.name(); - for (const Descriptor* current = descriptor.containing_type(); - current != NULL; current = current->containing_type()) { - name = current->name() + separator + name; - } - return name; -} - - -// Name of the class attribute where we store the Python -// descriptor.Descriptor instance for the generated class. -// Must stay consistent with the _DESCRIPTOR_KEY constant -// in proto2/public/reflection.py. -const char kDescriptorKey[] = "DESCRIPTOR"; - - -// Prints the common boilerplate needed at the top of every .py -// file output by this generator. -void PrintTopBoilerplate( - io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { - // TODO(robinson): Allow parameterization of Python version? - printer->Print( - "#!/usr/bin/python2.4\n" - "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "\n" - "from google.protobuf import descriptor\n" - "from google.protobuf import message\n" - "from google.protobuf import reflection\n" - "from google.protobuf import service\n" - "from google.protobuf import service_reflection\n"); - // Avoid circular imports if this module is descriptor_pb2. - if (!descriptor_proto) { - printer->Print( - "from google.protobuf import descriptor_pb2\n"); - } -} - - -// Returns a Python literal giving the default value for a field. -// If the field specifies no explicit default value, we'll return -// the default default value for the field type (zero for numbers, -// empty string for strings, empty list for repeated fields, and -// None for non-repeated, composite fields). -// -// TODO(robinson): Unify with code from -// //compiler/cpp/internal/primitive_field.cc -// //compiler/cpp/internal/enum_field.cc -// //compiler/cpp/internal/string_field.cc -string StringifyDefaultValue(const FieldDescriptor& field) { - if (field.is_repeated()) { - return "[]"; - } - - switch (field.cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return SimpleItoa(field.default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - return SimpleItoa(field.default_value_uint32()); - case FieldDescriptor::CPPTYPE_INT64: - return SimpleItoa(field.default_value_int64()); - case FieldDescriptor::CPPTYPE_UINT64: - return SimpleItoa(field.default_value_uint64()); - case FieldDescriptor::CPPTYPE_DOUBLE: - return SimpleDtoa(field.default_value_double()); - case FieldDescriptor::CPPTYPE_FLOAT: - return SimpleFtoa(field.default_value_float()); - case FieldDescriptor::CPPTYPE_BOOL: - return field.default_value_bool() ? "True" : "False"; - case FieldDescriptor::CPPTYPE_ENUM: - return SimpleItoa(field.default_value_enum()->number()); - case FieldDescriptor::CPPTYPE_STRING: - return "\"" + CEscape(field.default_value_string()) + "\""; - case FieldDescriptor::CPPTYPE_MESSAGE: - return "None"; - } - // (We could add a default case above but then we wouldn't get the nice - // compiler warning when a new type is added.) - GOOGLE_LOG(FATAL) << "Not reached."; - return ""; -} - - - -} // namespace - - -Generator::Generator() : file_(NULL) { -} - -Generator::~Generator() { -} - -bool Generator::Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const { - - // Completely serialize all Generate() calls on this instance. The - // thread-safety constraints of the CodeGenerator interface aren't clear so - // just be as conservative as possible. It's easier to relax this later if - // we need to, but I doubt it will be an issue. - // TODO(kenton): The proper thing to do would be to allocate any state on - // the stack and use that, so that the Generator class itself does not need - // to have any mutable members. Then it is implicitly thread-safe. - MutexLock lock(&mutex_); - file_ = file; - string module_name = ModuleName(file->name()); - string filename = module_name; - StripString(&filename, ".", '/'); - filename += ".py"; - - - scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename)); - GOOGLE_CHECK(output.get()); - io::Printer printer(output.get(), '$'); - printer_ = &printer; - - PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto()); - 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, - // since they need to call static RegisterExtension() methods on these - // classes. - FixForeignFieldsInExtensions(); - PrintServices(); - return !printer.failed(); -} - -// Prints Python imports for all modules imported by |file|. -void Generator::PrintImports() const { - for (int i = 0; i < file_->dependency_count(); ++i) { - string module_name = ModuleName(file_->dependency(i)->name()); - printer_->Print("import $module$\n", "module", - module_name); - } - printer_->Print("\n"); -} - -// Prints descriptors and module-level constants for all top-level -// enums defined in |file|. -void Generator::PrintTopLevelEnums() const { - vector<pair<string, int> > top_level_enum_values; - for (int i = 0; i < file_->enum_type_count(); ++i) { - const EnumDescriptor& enum_descriptor = *file_->enum_type(i); - PrintEnum(enum_descriptor); - printer_->Print("\n"); - - for (int j = 0; j < enum_descriptor.value_count(); ++j) { - const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); - top_level_enum_values.push_back( - make_pair(value_descriptor.name(), value_descriptor.number())); - } - } - - for (int i = 0; i < top_level_enum_values.size(); ++i) { - printer_->Print("$name$ = $value$\n", - "name", top_level_enum_values[i].first, - "value", SimpleItoa(top_level_enum_values[i].second)); - } - printer_->Print("\n"); -} - -// Prints all enums contained in all message types in |file|. -void Generator::PrintAllNestedEnumsInFile() const { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintNestedEnums(*file_->message_type(i)); - } -} - -// Prints a Python statement assigning the appropriate module-level -// enum name to a Python EnumDescriptor object equivalent to -// enum_descriptor. -void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { - map<string, string> m; - m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); - m["name"] = enum_descriptor.name(); - m["full_name"] = enum_descriptor.full_name(); - m["filename"] = enum_descriptor.name(); - const char enum_descriptor_template[] = - "$descriptor_name$ = descriptor.EnumDescriptor(\n" - " name='$name$',\n" - " full_name='$full_name$',\n" - " filename='$filename$',\n" - " values=[\n"; - string options_string; - enum_descriptor.options().SerializeToString(&options_string); - printer_->Print(m, enum_descriptor_template); - printer_->Indent(); - printer_->Indent(); - for (int i = 0; i < enum_descriptor.value_count(); ++i) { - PrintEnumValueDescriptor(*enum_descriptor.value(i)); - printer_->Print(",\n"); - } - printer_->Outdent(); - printer_->Print("],\n"); - printer_->Print("options=$options_value$,\n", - "options_value", - OptionsValue("EnumOptions", CEscape(options_string))); - printer_->Outdent(); - printer_->Print(")\n"); - printer_->Print("\n"); -} - -// Recursively prints enums in nested types within descriptor, then -// prints enums contained at the top level in descriptor. -void Generator::PrintNestedEnums(const Descriptor& descriptor) const { - for (int i = 0; i < descriptor.nested_type_count(); ++i) { - PrintNestedEnums(*descriptor.nested_type(i)); - } - - for (int i = 0; i < descriptor.enum_type_count(); ++i) { - PrintEnum(*descriptor.enum_type(i)); - } -} - -void Generator::PrintTopLevelExtensions() const { - const bool is_extension = true; - for (int i = 0; i < file_->extension_count(); ++i) { - const FieldDescriptor& extension_field = *file_->extension(i); - printer_->Print("$name$ = ", "name", extension_field.name()); - PrintFieldDescriptor(extension_field, is_extension); - printer_->Print("\n"); - } - printer_->Print("\n"); -} - -// Prints Python equivalents of all Descriptors in |file|. -void Generator::PrintMessageDescriptors() const { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintDescriptor(*file_->message_type(i)); - printer_->Print("\n"); - } -} - -void Generator::PrintServices() const { - for (int i = 0; i < file_->service_count(); ++i) { - PrintServiceDescriptor(*file_->service(i)); - PrintServiceClass(*file_->service(i)); - PrintServiceStub(*file_->service(i)); - printer_->Print("\n"); - } -} - -void Generator::PrintServiceDescriptor( - const ServiceDescriptor& descriptor) const { - printer_->Print("\n"); - string service_name = ModuleLevelServiceDescriptorName(descriptor); - string options_string; - descriptor.options().SerializeToString(&options_string); - - printer_->Print( - "$service_name$ = descriptor.ServiceDescriptor(\n", - "service_name", service_name); - printer_->Indent(); - map<string, string> m; - m["name"] = descriptor.name(); - m["full_name"] = descriptor.full_name(); - m["index"] = SimpleItoa(descriptor.index()); - m["options_value"] = OptionsValue("ServiceOptions", options_string); - const char required_function_arguments[] = - "name='$name$',\n" - "full_name='$full_name$',\n" - "index=$index$,\n" - "options=$options_value$,\n" - "methods=[\n"; - printer_->Print(m, required_function_arguments); - for (int i = 0; i < descriptor.method_count(); ++i) { - const MethodDescriptor* method = descriptor.method(i); - string options_string; - method->options().SerializeToString(&options_string); - - m.clear(); - m["name"] = method->name(); - m["full_name"] = method->full_name(); - m["index"] = SimpleItoa(method->index()); - m["serialized_options"] = CEscape(options_string); - m["input_type"] = ModuleLevelDescriptorName(*(method->input_type())); - m["output_type"] = ModuleLevelDescriptorName(*(method->output_type())); - m["options_value"] = OptionsValue("MethodOptions", options_string); - printer_->Print("descriptor.MethodDescriptor(\n"); - printer_->Indent(); - printer_->Print( - m, - "name='$name$',\n" - "full_name='$full_name$',\n" - "index=$index$,\n" - "containing_service=None,\n" - "input_type=$input_type$,\n" - "output_type=$output_type$,\n" - "options=$options_value$,\n"); - printer_->Outdent(); - printer_->Print("),\n"); - } - - printer_->Outdent(); - printer_->Print("])\n\n"); -} - -void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const { - // Print the service. - printer_->Print("class $class_name$(service.Service):\n", - "class_name", descriptor.name()); - printer_->Indent(); - printer_->Print( - "__metaclass__ = service_reflection.GeneratedServiceType\n" - "$descriptor_key$ = $descriptor_name$\n", - "descriptor_key", kDescriptorKey, - "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); - printer_->Outdent(); -} - -void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { - // Print the service stub. - printer_->Print("class $class_name$_Stub($class_name$):\n", - "class_name", descriptor.name()); - printer_->Indent(); - printer_->Print( - "__metaclass__ = service_reflection.GeneratedServiceStubType\n" - "$descriptor_key$ = $descriptor_name$\n", - "descriptor_key", kDescriptorKey, - "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); - printer_->Outdent(); -} - -// Prints statement assigning ModuleLevelDescriptorName(message_descriptor) -// to a Python Descriptor object for message_descriptor. -// -// Mutually recursive with PrintNestedDescriptors(). -void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { - PrintNestedDescriptors(message_descriptor); - - printer_->Print("\n"); - printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n", - "descriptor_name", - ModuleLevelDescriptorName(message_descriptor)); - printer_->Indent(); - map<string, string> m; - m["name"] = message_descriptor.name(); - m["full_name"] = message_descriptor.full_name(); - m["filename"] = message_descriptor.file()->name(); - const char required_function_arguments[] = - "name='$name$',\n" - "full_name='$full_name$',\n" - "filename='$filename$',\n" - "containing_type=None,\n"; // TODO(robinson): Implement containing_type. - printer_->Print(m, required_function_arguments); - PrintFieldsInDescriptor(message_descriptor); - PrintExtensionsInDescriptor(message_descriptor); - // TODO(robinson): implement printing of nested_types. - printer_->Print("nested_types=[], # TODO(robinson): Implement.\n"); - printer_->Print("enum_types=[\n"); - printer_->Indent(); - for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { - const string descriptor_name = ModuleLevelDescriptorName( - *message_descriptor.enum_type(i)); - printer_->Print(descriptor_name.c_str()); - printer_->Print(",\n"); - } - printer_->Outdent(); - printer_->Print("],\n"); - string options_string; - message_descriptor.options().SerializeToString(&options_string); - printer_->Print( - "options=$options_value$", - "options_value", OptionsValue("MessageOptions", options_string)); - printer_->Outdent(); - printer_->Print(")\n"); -} - -// Prints Python Descriptor objects for all nested types contained in -// message_descriptor. -// -// Mutually recursive with PrintDescriptor(). -void Generator::PrintNestedDescriptors( - const Descriptor& containing_descriptor) const { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintDescriptor(*containing_descriptor.nested_type(i)); - } -} - -// Prints all messages in |file|. -void Generator::PrintMessages() const { - for (int i = 0; i < file_->message_type_count(); ++i) { - PrintMessage(*file_->message_type(i)); - printer_->Print("\n"); - } -} - -// Prints a Python class for the given message descriptor. We defer to the -// metaclass to do almost all of the work of actually creating a useful class. -// The purpose of this function and its many helper functions above is merely -// to output a Python version of the descriptors, which the metaclass in -// reflection.py will use to construct the meat of the class itself. -// -// Mutually recursive with PrintNestedMessages(). -void Generator::PrintMessage( - const Descriptor& message_descriptor) const { - printer_->Print("class $name$(message.Message):\n", "name", - message_descriptor.name()); - printer_->Indent(); - printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n"); - PrintNestedMessages(message_descriptor); - map<string, string> m; - m["descriptor_key"] = kDescriptorKey; - m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); - printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n"); - printer_->Outdent(); -} - -// Prints all nested messages within |containing_descriptor|. -// Mutually recursive with PrintMessage(). -void Generator::PrintNestedMessages( - const Descriptor& containing_descriptor) const { - for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - printer_->Print("\n"); - PrintMessage(*containing_descriptor.nested_type(i)); - } -} - -// Recursively fixes foreign fields in all nested types in |descriptor|, then -// sets the message_type and enum_type of all message and enum fields to point -// to their respective descriptors. -void Generator::FixForeignFieldsInDescriptor( - const Descriptor& descriptor) const { - for (int i = 0; i < descriptor.nested_type_count(); ++i) { - FixForeignFieldsInDescriptor(*descriptor.nested_type(i)); - } - - for (int i = 0; i < descriptor.field_count(); ++i) { - const FieldDescriptor& field_descriptor = *descriptor.field(i); - FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); - } -} - -// Sets any necessary message_type and enum_type attributes -// for the Python version of |field|. -// -// containing_type may be NULL, in which case this is a module-level field. -// -// python_dict_name is the name of the Python dict where we should -// look the field up in the containing type. (e.g., fields_by_name -// or extensions_by_name). We ignore python_dict_name if containing_type -// is NULL. -void Generator::FixForeignFieldsInField(const Descriptor* containing_type, - const FieldDescriptor& field, - const string& python_dict_name) const { - const string field_referencing_expression = FieldReferencingExpression( - containing_type, field, python_dict_name); - map<string, string> m; - m["field_ref"] = field_referencing_expression; - const Descriptor* foreign_message_type = field.message_type(); - if (foreign_message_type) { - m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type); - printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n"); - } - const EnumDescriptor* enum_type = field.enum_type(); - if (enum_type) { - m["enum_type"] = ModuleLevelDescriptorName(*enum_type); - printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n"); - } -} - -// Returns the module-level expression for the given FieldDescriptor. -// Only works for fields in the .proto file this Generator is generating for. -// -// containing_type may be NULL, in which case this is a module-level field. -// -// python_dict_name is the name of the Python dict where we should -// look the field up in the containing type. (e.g., fields_by_name -// or extensions_by_name). We ignore python_dict_name if containing_type -// is NULL. -string Generator::FieldReferencingExpression( - const Descriptor* containing_type, - const FieldDescriptor& field, - const string& python_dict_name) const { - // We should only ever be looking up fields in the current file. - // The only things we refer to from other files are message descriptors. - GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. " - << file_->name(); - if (!containing_type) { - return field.name(); - } - return strings::Substitute( - "$0.$1['$2']", - ModuleLevelDescriptorName(*containing_type), - python_dict_name, field.name()); -} - -// Prints statements setting the message_type and enum_type fields in the -// Python descriptor objects we've already output in ths file. We must -// do this in a separate step due to circular references (otherwise, we'd -// just set everything in the initial assignment statements). -void Generator::FixForeignFieldsInDescriptors() const { - for (int i = 0; i < file_->message_type_count(); ++i) { - FixForeignFieldsInDescriptor(*file_->message_type(i)); - } - printer_->Print("\n"); -} - -// We need to not only set any necessary message_type fields, but -// also need to call RegisterExtension() on each message we're -// extending. -void Generator::FixForeignFieldsInExtensions() const { - // Top-level extensions. - for (int i = 0; i < file_->extension_count(); ++i) { - FixForeignFieldsInExtension(*file_->extension(i)); - } - // Nested extensions. - for (int i = 0; i < file_->message_type_count(); ++i) { - FixForeignFieldsInNestedExtensions(*file_->message_type(i)); - } -} - -void Generator::FixForeignFieldsInExtension( - const FieldDescriptor& extension_field) const { - GOOGLE_CHECK(extension_field.is_extension()); - // extension_scope() will be NULL for top-level extensions, which is - // exactly what FixForeignFieldsInField() wants. - FixForeignFieldsInField(extension_field.extension_scope(), extension_field, - "extensions_by_name"); - - map<string, string> m; - // Confusingly, for FieldDescriptors that happen to be extensions, - // containing_type() means "extended type." - // On the other hand, extension_scope() will give us what we normally - // mean by containing_type(). - m["extended_message_class"] = ModuleLevelMessageName( - *extension_field.containing_type()); - m["field"] = FieldReferencingExpression(extension_field.extension_scope(), - extension_field, - "extensions_by_name"); - printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n"); -} - -void Generator::FixForeignFieldsInNestedExtensions( - const Descriptor& descriptor) const { - // Recursively fix up extensions in all nested types. - for (int i = 0; i < descriptor.nested_type_count(); ++i) { - FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i)); - } - // Fix up extensions directly contained within this type. - for (int i = 0; i < descriptor.extension_count(); ++i) { - FixForeignFieldsInExtension(*descriptor.extension(i)); - } -} - -// Returns a Python expression that instantiates a Python EnumValueDescriptor -// object for the given C++ descriptor. -void Generator::PrintEnumValueDescriptor( - const EnumValueDescriptor& descriptor) const { - // TODO(robinson): Fix up EnumValueDescriptor "type" fields. - // More circular references. ::sigh:: - string options_string; - descriptor.options().SerializeToString(&options_string); - map<string, string> m; - m["name"] = descriptor.name(); - m["index"] = SimpleItoa(descriptor.index()); - m["number"] = SimpleItoa(descriptor.number()); - m["options"] = OptionsValue("EnumValueOptions", options_string); - printer_->Print( - m, - "descriptor.EnumValueDescriptor(\n" - " name='$name$', index=$index$, number=$number$,\n" - " options=$options$,\n" - " type=None)"); -} - -string Generator::OptionsValue( - const string& class_name, const string& serialized_options) const { - if (serialized_options.length() == 0 || GeneratingDescriptorProto()) { - return "None"; - } else { - string full_class_name = "descriptor_pb2." + class_name; - return "descriptor._ParseOptions(" + full_class_name + "(), '" - + CEscape(serialized_options)+ "')"; - } -} - -// Prints an expression for a Python FieldDescriptor for |field|. -void Generator::PrintFieldDescriptor( - const FieldDescriptor& field, bool is_extension) const { - string options_string; - field.options().SerializeToString(&options_string); - map<string, string> m; - m["name"] = field.name(); - m["full_name"] = field.full_name(); - m["index"] = SimpleItoa(field.index()); - m["number"] = SimpleItoa(field.number()); - m["type"] = SimpleItoa(field.type()); - m["cpp_type"] = SimpleItoa(field.cpp_type()); - m["label"] = SimpleItoa(field.label()); - m["default_value"] = StringifyDefaultValue(field); - m["is_extension"] = is_extension ? "True" : "False"; - m["options"] = OptionsValue("FieldOptions", options_string); - // We always set message_type and enum_type to None at this point, and then - // these fields in correctly after all referenced descriptors have been - // defined and/or imported (see FixForeignFieldsInDescriptors()). - const char field_descriptor_decl[] = - "descriptor.FieldDescriptor(\n" - " name='$name$', full_name='$full_name$', index=$index$,\n" - " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" - " default_value=$default_value$,\n" - " message_type=None, enum_type=None, containing_type=None,\n" - " is_extension=$is_extension$, extension_scope=None,\n" - " options=$options$)"; - printer_->Print(m, field_descriptor_decl); -} - -// Helper for Print{Fields,Extensions}InDescriptor(). -void Generator::PrintFieldDescriptorsInDescriptor( - const Descriptor& message_descriptor, - bool is_extension, - const string& list_variable_name, - int (Descriptor::*CountFn)() const, - const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { - printer_->Print("$list$=[\n", "list", list_variable_name); - printer_->Indent(); - for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) { - PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), - is_extension); - printer_->Print(",\n"); - } - printer_->Outdent(); - printer_->Print("],\n"); -} - -// Prints a statement assigning "fields" to a list of Python FieldDescriptors, -// one for each field present in message_descriptor. -void Generator::PrintFieldsInDescriptor( - const Descriptor& message_descriptor) const { - const bool is_extension = false; - PrintFieldDescriptorsInDescriptor( - message_descriptor, is_extension, "fields", - &Descriptor::field_count, &Descriptor::field); -} - -// Prints a statement assigning "extensions" to a list of Python -// FieldDescriptors, one for each extension present in message_descriptor. -void Generator::PrintExtensionsInDescriptor( - const Descriptor& message_descriptor) const { - const bool is_extension = true; - PrintFieldDescriptorsInDescriptor( - message_descriptor, is_extension, "extensions", - &Descriptor::extension_count, &Descriptor::extension); -} - -bool Generator::GeneratingDescriptorProto() const { - return file_->name() == "google/protobuf/descriptor.proto"; -} - -// Returns the unique Python module-level identifier given to a descriptor. -// This name is module-qualified iff the given descriptor describes an -// entity that doesn't come from the current file. -template <typename DescriptorT> -string Generator::ModuleLevelDescriptorName( - const DescriptorT& descriptor) const { - // FIXME(robinson): - // We currently don't worry about collisions with underscores in the type - // names, so these would collide in nasty ways if found in the same file: - // OuterProto.ProtoA.ProtoB - // OuterProto_ProtoA.ProtoB # Underscore instead of period. - // As would these: - // OuterProto.ProtoA_.ProtoB - // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore. - // (Contrived, but certainly possible). - // - // The C++ implementation doesn't guard against this either. Leaving - // it for now... - string name = NamePrefixedWithNestedTypes(descriptor, "_"); - UpperString(&name); - // Module-private for now. Easy to make public later; almost impossible - // to make private later. - name = "_" + name; - // We now have the name relative to its own module. Also qualify with - // the module name iff this descriptor is from a different .proto file. - if (descriptor.file() != file_) { - name = ModuleName(descriptor.file()->name()) + "." + name; - } - return name; -} - -// Returns the name of the message class itself, not the descriptor. -// Like ModuleLevelDescriptorName(), module-qualifies the name iff -// the given descriptor describes an entity that doesn't come from -// the current file. -string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const { - string name = NamePrefixedWithNestedTypes(descriptor, "."); - if (descriptor.file() != file_) { - name = ModuleName(descriptor.file()->name()) + "." + name; - } - return name; -} - -// Returns the unique Python module-level identifier given to a service -// descriptor. -string Generator::ModuleLevelServiceDescriptorName( - const ServiceDescriptor& descriptor) const { - string name = descriptor.name(); - UpperString(&name); - name = "_" + name; - if (descriptor.file() != file_) { - name = ModuleName(descriptor.file()->name()) + "." + name; - } - return name; -} - -} // namespace python -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h deleted file mode 100644 index 98ee0c6d..00000000 --- a/src/google/protobuf/compiler/python/python_generator.h +++ /dev/null @@ -1,129 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: robinson@google.com (Will Robinson) -// -// Generates Python code for a given .proto file. - -#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ - -#include <string> - -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -class Descriptor; -class EnumDescriptor; -class EnumValueDescriptor; -class FieldDescriptor; -class ServiceDescriptor; - -namespace io { class Printer; } - -namespace compiler { -namespace python { - -// CodeGenerator implementation for generated Python protocol buffer classes. -// If you create your own protocol compiler binary and you want it to support -// Python output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class LIBPROTOC_EXPORT Generator : public CodeGenerator { - public: - Generator(); - virtual ~Generator(); - - // CodeGenerator methods. - virtual bool Generate(const FileDescriptor* file, - const string& parameter, - OutputDirectory* output_directory, - string* error) const; - - private: - void PrintImports() const; - void PrintTopLevelEnums() const; - void PrintAllNestedEnumsInFile() const; - void PrintNestedEnums(const Descriptor& descriptor) const; - void PrintEnum(const EnumDescriptor& enum_descriptor) const; - - void PrintTopLevelExtensions() const; - - void PrintFieldDescriptor( - const FieldDescriptor& field, bool is_extension) const; - void PrintFieldDescriptorsInDescriptor( - const Descriptor& message_descriptor, - bool is_extension, - const string& list_variable_name, - int (Descriptor::*CountFn)() const, - const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const; - void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; - void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; - void PrintMessageDescriptors() const; - void PrintDescriptor(const Descriptor& message_descriptor) const; - void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; - - void PrintMessages() const; - void PrintMessage(const Descriptor& message_descriptor) const; - void PrintNestedMessages(const Descriptor& containing_descriptor) const; - - void FixForeignFieldsInDescriptors() const; - void FixForeignFieldsInDescriptor(const Descriptor& descriptor) const; - void FixForeignFieldsInField(const Descriptor* containing_type, - const FieldDescriptor& field, - const string& python_dict_name) const; - string FieldReferencingExpression(const Descriptor* containing_type, - const FieldDescriptor& field, - const string& python_dict_name) const; - - void FixForeignFieldsInExtensions() const; - void FixForeignFieldsInExtension( - const FieldDescriptor& extension_field) const; - void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; - - void PrintServices() const; - void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; - void PrintServiceClass(const ServiceDescriptor& descriptor) const; - void PrintServiceStub(const ServiceDescriptor& descriptor) const; - - void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; - string OptionsValue(const string& class_name, - const string& serialized_options) const; - bool GeneratingDescriptorProto() const; - - template <typename DescriptorT> - string ModuleLevelDescriptorName(const DescriptorT& descriptor) const; - string ModuleLevelMessageName(const Descriptor& descriptor) const; - string ModuleLevelServiceDescriptorName( - const ServiceDescriptor& descriptor) const; - - // Very coarse-grained lock to ensure that Generate() is reentrant. - // Guards file_ and printer_. - mutable Mutex mutex_; - mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. - mutable io::Printer* printer_; // Set in Generate(). Under mutex_. - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); -}; - -} // namespace python -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc deleted file mode 100644 index 8b808565..00000000 --- a/src/google/protobuf/descriptor.cc +++ /dev/null @@ -1,2878 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/stubs/hash.h> -#include <map> -#include <set> -#include <algorithm> - -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/text_format.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> - -#undef PACKAGE // autoheader #defines this. :( - -namespace google { -namespace protobuf { - -const FieldDescriptor::CppType -FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { - static_cast<CppType>(0), // 0 is reserved for errors - - CPPTYPE_DOUBLE, // TYPE_DOUBLE - CPPTYPE_FLOAT, // TYPE_FLOAT - CPPTYPE_INT64, // TYPE_INT64 - CPPTYPE_UINT64, // TYPE_UINT64 - CPPTYPE_INT32, // TYPE_INT32 - CPPTYPE_UINT64, // TYPE_FIXED64 - CPPTYPE_UINT32, // TYPE_FIXED32 - CPPTYPE_BOOL, // TYPE_BOOL - CPPTYPE_STRING, // TYPE_STRING - CPPTYPE_MESSAGE, // TYPE_GROUP - CPPTYPE_MESSAGE, // TYPE_MESSAGE - CPPTYPE_STRING, // TYPE_BYTES - CPPTYPE_UINT32, // TYPE_UINT32 - CPPTYPE_ENUM, // TYPE_ENUM - CPPTYPE_INT32, // TYPE_SFIXED32 - CPPTYPE_INT64, // TYPE_SFIXED64 - CPPTYPE_INT32, // TYPE_SINT32 - CPPTYPE_INT64, // TYPE_SINT64 -}; - -const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { - "ERROR", // 0 is reserved for errors - - "double", // TYPE_DOUBLE - "float", // TYPE_FLOAT - "int64", // TYPE_INT64 - "uint64", // TYPE_UINT64 - "int32", // TYPE_INT32 - "fixed64", // TYPE_FIXED64 - "fixed32", // TYPE_FIXED32 - "bool", // TYPE_BOOL - "string", // TYPE_STRING - "group", // TYPE_GROUP - "message", // TYPE_MESSAGE - "bytes", // TYPE_BYTES - "uint32", // TYPE_UINT32 - "enum", // TYPE_ENUM - "sfixed32", // TYPE_SFIXED32 - "sfixed64", // TYPE_SFIXED64 - "sint32", // TYPE_SINT32 - "sint64", // TYPE_SINT64 -}; - -const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { - "ERROR", // 0 is reserved for errors - - "optional", // LABEL_OPTIONAL - "required", // LABEL_REQUIRED - "repeated", // LABEL_REPEATED -}; - -#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them. -const int FieldDescriptor::kMaxNumber; -const int FieldDescriptor::kFirstReservedNumber; -const int FieldDescriptor::kLastReservedNumber; -#endif - -namespace { - -const string kEmptyString; - -// A DescriptorPool contains a bunch of hash_maps to implement the -// various Find*By*() methods. Since hashtable lookups are O(1), it's -// most efficient to construct a fixed set of large hash_maps used by -// all objects in the pool rather than construct one or more small -// hash_maps for each object. -// -// The keys to these hash_maps are (parent, name) or (parent, number) -// pairs. Unfortunately STL doesn't provide hash functions for pair<>, -// so we must invent our own. -// -// TODO(kenton): Use StringPiece rather than const char* in keys? It would -// be a lot cleaner but we'd just have to convert it back to const char* -// for the open source release. - -typedef pair<const void*, const char*> PointerStringPair; - -// Used by GCC/SGI STL only. (Why isn't this provided by the standard -// library? :( ) -struct CStringEqual { - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) == 0; - } -}; - -struct PointerStringPairEqual { - inline bool operator()(const PointerStringPair& a, - const PointerStringPair& b) const { - return a.first == b.first && strcmp(a.second, b.second) == 0; - } -}; - -template<typename PairType> -struct PointerIntegerPairHash { - size_t operator()(const PairType& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; - } - - // Used only by MSVC and platforms where hash_map is not available. - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline bool operator()(const PairType& a, const PairType& b) const { - return a.first < b.first || - (a.first == b.first && a.second < b.second); - } -}; - -typedef pair<const Descriptor*, int> DescriptorIntPair; -typedef pair<const EnumDescriptor*, int> EnumIntPair; - -struct PointerStringPairHash { - size_t operator()(const PointerStringPair& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - hash<const char*> cstring_hash; - return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + - cstring_hash(p.second); - } - - // Used only by MSVC and platforms where hash_map is not available. - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline bool operator()(const PointerStringPair& a, - const PointerStringPair& b) const { - if (a.first < b.first) return true; - if (a.first > b.first) return false; - return strcmp(a.second, b.second) < 0; - } -}; - - -struct Symbol { - enum Type { - NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE - }; - Type type; - union { - const Descriptor* descriptor; - const FieldDescriptor* field_descriptor; - const EnumDescriptor* enum_descriptor; - const EnumValueDescriptor* enum_value_descriptor; - const ServiceDescriptor* service_descriptor; - const MethodDescriptor* method_descriptor; - const FileDescriptor* package_file_descriptor; - }; - - inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } - inline bool IsNull() const { return type == NULL_SYMBOL; } - -#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ - inline explicit Symbol(const TYPE* value) { \ - type = TYPE_CONSTANT; \ - this->FIELD = value; \ - } - - CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) - CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) - CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) - CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) - CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) - CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) - CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) -#undef CONSTRUCTOR - - const FileDescriptor* GetFile() const { - switch (type) { - case NULL_SYMBOL: return NULL; - case MESSAGE : return descriptor ->file(); - case FIELD : return field_descriptor ->file(); - case ENUM : return enum_descriptor ->file(); - case ENUM_VALUE : return enum_value_descriptor->type()->file(); - case SERVICE : return service_descriptor ->file(); - case METHOD : return method_descriptor ->service()->file(); - case PACKAGE : return package_file_descriptor; - } - return NULL; - } -}; - -const Symbol kNullSymbol; - -typedef hash_map<const char*, Symbol, - hash<const char*>, CStringEqual> - SymbolsByNameMap; -typedef hash_map<PointerStringPair, Symbol, - PointerStringPairHash, PointerStringPairEqual> - SymbolsByParentMap; -typedef hash_map<const char*, const FileDescriptor*, - hash<const char*>, CStringEqual> - FilesByNameMap; -typedef hash_map<DescriptorIntPair, const FieldDescriptor*, - PointerIntegerPairHash<DescriptorIntPair> > - FieldsByNumberMap; -typedef hash_map<EnumIntPair, const EnumValueDescriptor*, - PointerIntegerPairHash<EnumIntPair> > - EnumValuesByNumberMap; - -} // anonymous namespace - -// =================================================================== -// DescriptorPool::Tables - -class DescriptorPool::Tables { - public: - Tables(); - ~Tables(); - - // Checkpoint the state of the tables. Future calls to Rollback() will - // return the Tables to this state. This is used when building files, since - // some kinds of validation errors cannot be detected until the file's - // descriptors have already been added to the tables. BuildFile() calls - // Checkpoint() before it starts building and Rollback() if it encounters - // an error. - void Checkpoint(); - - // Roll back the Tables to the state of the last Checkpoint(), removing - // everything that was added after that point. - void Rollback(); - - // The stack of files which are currently being built. Used to detect - // cyclic dependencies when loading files from a DescriptorDatabase. Not - // used when fallback_database_ == NULL. - vector<string> pending_files_; - - // A set of files which we have tried to load from the fallback database - // and encountered errors. We will not attempt to load them again. - // Not used when fallback_database_ == NULL. - hash_set<string> known_bad_files_; - - // ----------------------------------------------------------------- - // Finding items. - - // Find symbols. These return a null Symbol (symbol.IsNull() is true) - // if not found. FindSymbolOfType() additionally returns null if the - // symbol is not of the given type. - inline Symbol FindSymbol(const string& key) const; - inline Symbol FindSymbolOfType(const string& key, - const Symbol::Type type) const; - inline Symbol FindNestedSymbol(const void* parent, - const string& name) const; - inline Symbol FindNestedSymbolOfType(const void* parent, - const string& name, - const Symbol::Type type) const; - - // These return NULL if not found. - inline const FileDescriptor* FindFile(const string& key) const; - inline const FieldDescriptor* FindFieldByNumber( - const Descriptor* parent, int number) const; - inline const EnumValueDescriptor* FindEnumValueByNumber( - const EnumDescriptor* parent, int number) const; - - // ----------------------------------------------------------------- - // Adding items. - - // These add items to the corresponding tables. They return false if - // the key already exists in the table. For AddSymbol(), the strings passed - // in must be ones that were constructed using AllocateString(), as they will - // be used as keys in the symbols_by_name_ and symbols_by_parent_ maps - // without copying. (If parent is NULL, nothing is added to - // symbols_by_parent_.) - bool AddSymbol(const string& full_name, - const void* parent, const string& name, - Symbol symbol); - bool AddFile(const FileDescriptor* file); - bool AddFieldByNumber(const FieldDescriptor* field); - bool AddEnumValueByNumber(const EnumValueDescriptor* value); - - // Like AddSymbol(), but only adds to symbols_by_parent_, not - // symbols_by_name_. Used for enum values, which need to be registered - // under multiple parents (their type and its parent). - bool AddAliasUnderParent(const void* parent, const string& name, - Symbol symbol); - - // ----------------------------------------------------------------- - // Allocating memory. - - // Allocate an object which will be reclaimed when the pool is - // destroyed. Note that the object's destructor will never be called, - // so its fields must be plain old data (primitive data types and - // pointers). All of the descriptor types are such objects. - template<typename Type> Type* Allocate(); - - // Allocate an array of objects which will be reclaimed when the - // pool in destroyed. Again, destructors are never called. - template<typename Type> Type* AllocateArray(int count); - - // Allocate a string which will be destroyed when the pool is destroyed. - // The string is initialized to the given value for convenience. - string* AllocateString(const string& value); - - // Allocate a protocol message object. - template<typename Type> Type* AllocateMessage(); - - private: - vector<string*> strings_; // All strings in the pool. - vector<Message*> messages_; // All messages in the pool. - vector<void*> allocations_; // All other memory allocated in the pool. - - SymbolsByNameMap symbols_by_name_; - SymbolsByParentMap symbols_by_parent_; - FilesByNameMap files_by_name_; - FieldsByNumberMap fields_by_number_; // Includes extensions. - EnumValuesByNumberMap enum_values_by_number_; - - int strings_before_checkpoint_; - int messages_before_checkpoint_; - int allocations_before_checkpoint_; - vector<const char* > symbols_after_checkpoint_; - vector<PointerStringPair> symbols_by_parent_after_checkpoint_; - vector<const char* > files_after_checkpoint_; - vector<DescriptorIntPair> field_numbers_after_checkpoint_; - vector<EnumIntPair > enum_numbers_after_checkpoint_; - - // Allocate some bytes which will be reclaimed when the pool is - // destroyed. - void* AllocateBytes(int size); -}; - -DescriptorPool::Tables::Tables() - : strings_before_checkpoint_(0), - messages_before_checkpoint_(0), - allocations_before_checkpoint_(0) {} - -DescriptorPool::Tables::~Tables() { - for (int i = 0; i < allocations_.size(); i++) { - operator delete(allocations_[i]); - } - STLDeleteElements(&strings_); - STLDeleteElements(&messages_); -} - -void DescriptorPool::Tables::Checkpoint() { - strings_before_checkpoint_ = strings_.size(); - messages_before_checkpoint_ = messages_.size(); - allocations_before_checkpoint_ = allocations_.size(); - - symbols_after_checkpoint_.clear(); - symbols_by_parent_after_checkpoint_.clear(); - files_after_checkpoint_.clear(); - field_numbers_after_checkpoint_.clear(); - enum_numbers_after_checkpoint_.clear(); -} - -void DescriptorPool::Tables::Rollback() { - for (int i = 0; i < symbols_after_checkpoint_.size(); i++) { - symbols_by_name_.erase(symbols_after_checkpoint_[i]); - } - for (int i = 0; i < symbols_by_parent_after_checkpoint_.size(); i++) { - symbols_by_parent_.erase(symbols_by_parent_after_checkpoint_[i]); - } - for (int i = 0; i < files_after_checkpoint_.size(); i++) { - files_by_name_.erase(files_after_checkpoint_[i]); - } - for (int i = 0; i < field_numbers_after_checkpoint_.size(); i++) { - fields_by_number_.erase(field_numbers_after_checkpoint_[i]); - } - for (int i = 0; i < enum_numbers_after_checkpoint_.size(); i++) { - enum_values_by_number_.erase(enum_numbers_after_checkpoint_[i]); - } - - symbols_after_checkpoint_.clear(); - symbols_by_parent_after_checkpoint_.clear(); - files_after_checkpoint_.clear(); - field_numbers_after_checkpoint_.clear(); - enum_numbers_after_checkpoint_.clear(); - - STLDeleteContainerPointers( - strings_.begin() + strings_before_checkpoint_, strings_.end()); - STLDeleteContainerPointers( - messages_.begin() + messages_before_checkpoint_, messages_.end()); - for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) { - operator delete(allocations_[i]); - } - - strings_.resize(strings_before_checkpoint_); - messages_.resize(messages_before_checkpoint_); - allocations_.resize(allocations_before_checkpoint_); -} - -// ------------------------------------------------------------------- - -inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { - const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); - if (result == NULL) { - return kNullSymbol; - } else { - return *result; - } -} - -inline Symbol DescriptorPool::Tables::FindSymbolOfType( - const string& key, const Symbol::Type type) const { - Symbol result = FindSymbol(key); - if (result.type != type) return kNullSymbol; - return result; -} - -inline Symbol DescriptorPool::Tables::FindNestedSymbol( - const void* parent, const string& name) const { - const Symbol* result = - FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); - if (result == NULL) { - return kNullSymbol; - } else { - return *result; - } -} - -inline Symbol DescriptorPool::Tables::FindNestedSymbolOfType( - const void* parent, const string& name, const Symbol::Type type) const { - Symbol result = FindNestedSymbol(parent, name); - if (result.type != type) return kNullSymbol; - return result; -} - -inline const FileDescriptor* DescriptorPool::Tables::FindFile( - const string& key) const { - return FindPtrOrNull(files_by_name_, key.c_str()); -} - -inline const FieldDescriptor* DescriptorPool::Tables::FindFieldByNumber( - const Descriptor* parent, int number) const { - return FindPtrOrNull(fields_by_number_, make_pair(parent, number)); -} - -inline const EnumValueDescriptor* DescriptorPool::Tables::FindEnumValueByNumber( - const EnumDescriptor* parent, int number) const { - return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number)); -} - -// ------------------------------------------------------------------- - -bool DescriptorPool::Tables::AddSymbol( - const string& full_name, - const void* parent, const string& name, - Symbol symbol) { - if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { - symbols_after_checkpoint_.push_back(full_name.c_str()); - - if (parent != NULL && !AddAliasUnderParent(parent, name, symbol)) { - GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " - "symbols_by_name_, but was defined in symbols_by_parent_; " - "this shouldn't be possible."; - return false; - } - - return true; - } else { - return false; - } -} - -bool DescriptorPool::Tables::AddAliasUnderParent( - const void* parent, const string& name, Symbol symbol) { - PointerStringPair by_parent_key(parent, name.c_str()); - if (InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol)) { - symbols_by_parent_after_checkpoint_.push_back(by_parent_key); - return true; - } else { - return false; - } -} - -bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { - if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { - files_after_checkpoint_.push_back(file->name().c_str()); - return true; - } else { - return false; - } -} - -bool DescriptorPool::Tables::AddFieldByNumber(const FieldDescriptor* field) { - DescriptorIntPair key(field->containing_type(), field->number()); - if (InsertIfNotPresent(&fields_by_number_, key, field)) { - field_numbers_after_checkpoint_.push_back(key); - return true; - } else { - return false; - } -} - -bool DescriptorPool::Tables::AddEnumValueByNumber( - const EnumValueDescriptor* value) { - EnumIntPair key(value->type(), value->number()); - if (InsertIfNotPresent(&enum_values_by_number_, key, value)) { - enum_numbers_after_checkpoint_.push_back(key); - return true; - } else { - return false; - } -} - -// ------------------------------------------------------------------- - -template<typename Type> -Type* DescriptorPool::Tables::Allocate() { - return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type))); -} - -template<typename Type> -Type* DescriptorPool::Tables::AllocateArray(int count) { - return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); -} - -string* DescriptorPool::Tables::AllocateString(const string& value) { - string* result = new string(value); - strings_.push_back(result); - return result; -} - -template<typename Type> -Type* DescriptorPool::Tables::AllocateMessage() { - Type* result = new Type; - messages_.push_back(result); - return result; -} - -void* DescriptorPool::Tables::AllocateBytes(int size) { - // TODO(kenton): Would it be worthwhile to implement this in some more - // sophisticated way? Probably not for the open source release, but for - // internal use we could easily plug in one of our existing memory pool - // allocators... - if (size == 0) return NULL; - - void* result = operator new(size); - allocations_.push_back(result); - return result; -} - -// =================================================================== -// DescriptorPool - -DescriptorPool::ErrorCollector::~ErrorCollector() {} - -DescriptorPool::DescriptorPool() - : mutex_(NULL), - fallback_database_(NULL), - default_error_collector_(NULL), - underlay_(NULL), - tables_(new Tables), - enforce_dependencies_(true), - last_internal_build_generated_file_call_(NULL) {} - -DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, - ErrorCollector* error_collector) - : mutex_(new Mutex), - fallback_database_(fallback_database), - default_error_collector_(error_collector), - underlay_(NULL), - tables_(new Tables), - enforce_dependencies_(true), - last_internal_build_generated_file_call_(NULL) { -} - -DescriptorPool::DescriptorPool(const DescriptorPool* underlay) - : mutex_(NULL), - fallback_database_(NULL), - default_error_collector_(NULL), - underlay_(underlay), - tables_(new Tables), - last_internal_build_generated_file_call_(NULL) {} - -DescriptorPool::~DescriptorPool() { - if (mutex_ != NULL) delete mutex_; -} - -// DescriptorPool::BuildFile() defined later. -// DescriptorPool::BuildFileCollectingErrors() defined later. -// DescriptorPool::InternalBuildGeneratedFile() defined later. - -const DescriptorPool* DescriptorPool::generated_pool() { - return internal_generated_pool(); -} - -DescriptorPool* DescriptorPool::internal_generated_pool() { - static DescriptorPool singleton; - return &singleton; -} - -void DescriptorPool::InternalDontEnforceDependencies() { - enforce_dependencies_ = false; -} - -// Find*By* methods ================================================== - -// TODO(kenton): There's a lot of repeated code here, but I'm not sure if -// there's any good way to factor it out. Think about this some time when -// there's nothing more important to do (read: never). - -const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { - MutexLockMaybe lock(mutex_); - const FileDescriptor* result = tables_->FindFile(name); - if (result != NULL) return result; - if (underlay_ != NULL) { - const FileDescriptor* result = underlay_->FindFileByName(name); - if (result != NULL) return result; - } - if (TryFindFileInFallbackDatabase(name)) { - const FileDescriptor* result = tables_->FindFile(name); - if (result != NULL) return result; - } - return NULL; -} - -const FileDescriptor* DescriptorPool::FindFileContainingSymbol( - const string& symbol_name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbol(symbol_name); - if (!result.IsNull()) return result.GetFile(); - if (underlay_ != NULL) { - const FileDescriptor* result = - underlay_->FindFileContainingSymbol(symbol_name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(symbol_name)) { - Symbol result = tables_->FindSymbol(symbol_name); - if (!result.IsNull()) return result.GetFile(); - } - return NULL; -} - -const Descriptor* DescriptorPool::FindMessageTypeByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE); - if (!result.IsNull()) return result.descriptor; - if (underlay_ != NULL) { - const Descriptor* result = underlay_->FindMessageTypeByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::MESSAGE); - if (!result.IsNull()) return result.descriptor; - } - return NULL; -} - -const FieldDescriptor* DescriptorPool::FindFieldByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD); - if (!result.IsNull() && !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } - if (underlay_ != NULL) { - const FieldDescriptor* result = underlay_->FindFieldByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD); - if (!result.IsNull() && !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } - } - return NULL; -} - -const FieldDescriptor* DescriptorPool::FindExtensionByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } - if (underlay_ != NULL) { - const FieldDescriptor* result = underlay_->FindExtensionByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } - } - return NULL; -} - -const EnumDescriptor* DescriptorPool::FindEnumTypeByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM); - if (!result.IsNull()) return result.enum_descriptor; - if (underlay_ != NULL) { - const EnumDescriptor* result = underlay_->FindEnumTypeByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM); - if (!result.IsNull()) return result.enum_descriptor; - } - return NULL; -} - -const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE); - if (!result.IsNull()) return result.enum_value_descriptor; - if (underlay_ != NULL) { - const EnumValueDescriptor* result = underlay_->FindEnumValueByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::ENUM_VALUE); - if (!result.IsNull()) return result.enum_value_descriptor; - } - return NULL; -} - -const ServiceDescriptor* DescriptorPool::FindServiceByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE); - if (!result.IsNull()) return result.service_descriptor; - if (underlay_ != NULL) { - const ServiceDescriptor* result = underlay_->FindServiceByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::SERVICE); - if (!result.IsNull()) return result.service_descriptor; - } - return NULL; -} - -const MethodDescriptor* DescriptorPool::FindMethodByName( - const string& name) const { - MutexLockMaybe lock(mutex_); - Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD); - if (!result.IsNull()) return result.method_descriptor; - if (underlay_ != NULL) { - const MethodDescriptor* result = underlay_->FindMethodByName(name); - if (result != NULL) return result; - } - if (TryFindSymbolInFallbackDatabase(name)) { - Symbol result = tables_->FindSymbolOfType(name, Symbol::METHOD); - if (!result.IsNull()) return result.method_descriptor; - } - return NULL; -} - -const FieldDescriptor* DescriptorPool::FindExtensionByNumber( - const Descriptor* extendee, int number) const { - MutexLockMaybe lock(mutex_); - const FieldDescriptor* result = tables_->FindFieldByNumber(extendee, number); - if (result != NULL && result->is_extension()) { - return result; - } - if (underlay_ != NULL) { - const FieldDescriptor* result = - underlay_->FindExtensionByNumber(extendee, number); - if (result != NULL) return result; - } - if (TryFindExtensionInFallbackDatabase(extendee, number)) { - const FieldDescriptor* result = - tables_->FindFieldByNumber(extendee, number); - if (result != NULL && result->is_extension()) { - return result; - } - } - return NULL; -} - -// ------------------------------------------------------------------- - -const FieldDescriptor* -Descriptor::FindFieldByNumber(int key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - const FieldDescriptor* result = - file()->pool()->tables_->FindFieldByNumber(this, key); - if (result == NULL || result->is_extension()) { - return NULL; - } else { - return result; - } -} - -const FieldDescriptor* -Descriptor::FindFieldByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && !result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -Descriptor::FindExtensionByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -const Descriptor* -Descriptor::FindNestedTypeByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return NULL; - } -} - -const EnumDescriptor* -Descriptor::FindEnumTypeByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -Descriptor::FindEnumValueByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType( - this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -EnumDescriptor::FindValueByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType( - this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -EnumDescriptor::FindValueByNumber(int key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - return file()->pool()->tables_->FindEnumValueByNumber(this, key); -} - -const MethodDescriptor* -ServiceDescriptor::FindMethodByName(const string& key) const { - MutexLockMaybe lock(file()->pool()->mutex_); - Symbol result = - file()->pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); - if (!result.IsNull()) { - return result.method_descriptor; - } else { - return NULL; - } -} - -const Descriptor* -FileDescriptor::FindMessageTypeByName(const string& key) const { - MutexLockMaybe lock(pool()->mutex_); - Symbol result = - pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); - if (!result.IsNull()) { - return result.descriptor; - } else { - return NULL; - } -} - -const EnumDescriptor* -FileDescriptor::FindEnumTypeByName(const string& key) const { - MutexLockMaybe lock(pool()->mutex_); - Symbol result = - pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); - if (!result.IsNull()) { - return result.enum_descriptor; - } else { - return NULL; - } -} - -const EnumValueDescriptor* -FileDescriptor::FindEnumValueByName(const string& key) const { - MutexLockMaybe lock(pool()->mutex_); - Symbol result = - pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); - if (!result.IsNull()) { - return result.enum_value_descriptor; - } else { - return NULL; - } -} - -const ServiceDescriptor* -FileDescriptor::FindServiceByName(const string& key) const { - MutexLockMaybe lock(pool()->mutex_); - Symbol result = - pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); - if (!result.IsNull()) { - return result.service_descriptor; - } else { - return NULL; - } -} - -const FieldDescriptor* -FileDescriptor::FindExtensionByName(const string& key) const { - MutexLockMaybe lock(pool()->mutex_); - Symbol result = - pool()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); - if (!result.IsNull() && result.field_descriptor->is_extension()) { - return result.field_descriptor; - } else { - return NULL; - } -} - -bool Descriptor::IsExtensionNumber(int number) const { - // Linear search should be fine because we don't expect a message to have - // more than a couple extension ranges. - for (int i = 0; i < extension_range_count(); i++) { - if (number >= extension_range(i)->start && - number < extension_range(i)->end) { - return true; - } - } - return false; -} - -// ------------------------------------------------------------------- - -bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { - if (fallback_database_ == NULL) return false; - - if (tables_->known_bad_files_.count(name) > 0) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileByName(name, &file_proto) || - BuildFileFromDatabase(file_proto) == NULL) { - tables_->known_bad_files_.insert(name); - return false; - } - - return true; -} - -bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { - if (fallback_database_ == NULL) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) { - return false; - } - - if (tables_->FindFile(file_proto.name()) != NULL) { - // We've already loaded this file, and it apparently doesn't contain the - // symbol we're looking for. Some DescriptorDatabases return false - // positives. - return false; - } - - if (BuildFileFromDatabase(file_proto) == NULL) { - return false; - } - - return true; -} - -bool DescriptorPool::TryFindExtensionInFallbackDatabase( - const Descriptor* containing_type, int field_number) const { - if (fallback_database_ == NULL) return false; - - FileDescriptorProto file_proto; - if (!fallback_database_->FindFileContainingExtension( - containing_type->full_name(), field_number, &file_proto)) { - return false; - } - - if (tables_->FindFile(file_proto.name()) != NULL) { - // We've already loaded this file, and it apparently doesn't contain the - // extension we're looking for. Some DescriptorDatabases return false - // positives. - return false; - } - - if (BuildFileFromDatabase(file_proto) == NULL) { - return false; - } - - return true; -} - -// =================================================================== - -string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { - GOOGLE_CHECK(has_default_value()) << "No default value"; - switch (cpp_type()) { - case CPPTYPE_INT32: - return SimpleItoa(default_value_int32()); - break; - case CPPTYPE_INT64: - return SimpleItoa(default_value_int64()); - break; - case CPPTYPE_UINT32: - return SimpleItoa(default_value_uint32()); - break; - case CPPTYPE_UINT64: - return SimpleItoa(default_value_uint64()); - break; - case CPPTYPE_FLOAT: - return SimpleFtoa(default_value_float()); - break; - case CPPTYPE_DOUBLE: - return SimpleDtoa(default_value_double()); - break; - case CPPTYPE_BOOL: - return default_value_bool() ? "true" : "false"; - break; - case CPPTYPE_STRING: - if (quote_string_type) { - return "\"" + CEscape(default_value_string()) + "\""; - } else { - if (type() == TYPE_BYTES) { - return CEscape(default_value_string()); - } else { - return default_value_string(); - } - } - break; - case CPPTYPE_ENUM: - return default_value_enum()->name(); - break; - case CPPTYPE_MESSAGE: - GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; - break; - } - GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; - return ""; -} - -// CopyTo methods ==================================================== - -void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { - proto->set_name(name()); - if (!package().empty()) proto->set_package(package()); - - for (int i = 0; i < dependency_count(); i++) { - proto->add_dependency(dependency(i)->name()); - } - - for (int i = 0; i < message_type_count(); i++) { - message_type(i)->CopyTo(proto->add_message_type()); - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->CopyTo(proto->add_enum_type()); - } - for (int i = 0; i < service_count(); i++) { - service(i)->CopyTo(proto->add_service()); - } - for (int i = 0; i < extension_count(); i++) { - extension(i)->CopyTo(proto->add_extension()); - } - - if (&options() != &FileOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void Descriptor::CopyTo(DescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < field_count(); i++) { - field(i)->CopyTo(proto->add_field()); - } - for (int i = 0; i < nested_type_count(); i++) { - nested_type(i)->CopyTo(proto->add_nested_type()); - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->CopyTo(proto->add_enum_type()); - } - for (int i = 0; i < extension_range_count(); i++) { - DescriptorProto::ExtensionRange* range = proto->add_extension_range(); - range->set_start(extension_range(i)->start); - range->set_end(extension_range(i)->end); - } - for (int i = 0; i < extension_count(); i++) { - extension(i)->CopyTo(proto->add_extension()); - } - - if (&options() != &MessageOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { - proto->set_name(name()); - proto->set_number(number()); - proto->set_label(static_cast<FieldDescriptorProto::Label>(label())); - proto->set_type(static_cast<FieldDescriptorProto::Type>(type())); - - if (is_extension()) { - proto->set_extendee("."); - proto->mutable_extendee()->append(containing_type()->full_name()); - } - - if (cpp_type() == CPPTYPE_MESSAGE) { - proto->set_type_name("."); - proto->mutable_type_name()->append(message_type()->full_name()); - } else if (cpp_type() == CPPTYPE_ENUM) { - proto->set_type_name("."); - proto->mutable_type_name()->append(enum_type()->full_name()); - } - - if (has_default_value()) { - proto->set_default_value(DefaultValueAsString(false)); - } - - if (&options() != &FieldOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < value_count(); i++) { - value(i)->CopyTo(proto->add_value()); - } - - if (&options() != &EnumOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { - proto->set_name(name()); - proto->set_number(number()); - - if (&options() != &EnumValueOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { - proto->set_name(name()); - - for (int i = 0; i < method_count(); i++) { - method(i)->CopyTo(proto->add_method()); - } - - if (&options() != &ServiceOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { - proto->set_name(name()); - - proto->set_input_type("."); - proto->mutable_input_type()->append(input_type()->full_name()); - proto->set_output_type("."); - proto->mutable_output_type()->append(output_type()->full_name()); - - if (&options() != &MethodOptions::default_instance()) { - proto->mutable_options()->CopyFrom(options()); - } -} - -// DebugString methods =============================================== - -namespace { - -// Used by each of the option formatters. -bool RetrieveOptions(const Message &options, vector<string> *option_entries) { - option_entries->clear(); - const Reflection* reflection = options.GetReflection(); - vector<const FieldDescriptor*> fields; - reflection->ListFields(options, &fields); - for (int i = 0; i < fields.size(); i++) { - // Doesn't make sense to have message type fields here - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - continue; - } - int count = 1; - bool repeated = false; - if (fields[i]->is_repeated()) { - count = reflection->FieldSize(options, fields[i]); - repeated = true; - } - for (int j = 0; j < count; j++) { - string fieldval; - TextFormat::PrintFieldValueToString(options, fields[i], - repeated ? count : -1, &fieldval); - option_entries->push_back(fields[i]->name() + " = " + fieldval); - } - } - return !option_entries->empty(); -} - -// Formats options that all appear together in brackets. Does not include -// brackets. -bool FormatBracketedOptions(const Message &options, string *output) { - vector<string> all_options; - if (RetrieveOptions(options, &all_options)) { - output->append(JoinStrings(all_options, ", ")); - } - return !all_options.empty(); -} - -// Formats options one per line -bool FormatLineOptions(int depth, const Message &options, string *output) { - string prefix(depth * 2, ' '); - vector<string> all_options; - if (RetrieveOptions(options, &all_options)) { - for (int i = 0; i < all_options.size(); i++) { - strings::SubstituteAndAppend(output, "$0option $1;\n", - prefix, all_options[i]); - } - } - return !all_options.empty(); -} - -} // anonymous namespace - -string FileDescriptor::DebugString() const { - string contents = "syntax = \"proto2\";\n\n"; - - for (int i = 0; i < dependency_count(); i++) { - strings::SubstituteAndAppend(&contents, "import \"$0\";\n", - dependency(i)->name()); - } - - if (!package().empty()) { - strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); - } - - if (FormatLineOptions(0, options(), &contents)) { - contents.append("\n"); // add some space if we had options - } - - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->DebugString(0, &contents); - contents.append("\n"); - } - - // Find all the 'group' type extensions; we will not output their nested - // definitions (those will be done with their group field descriptor). - set<const Descriptor*> groups; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(extension(i)->message_type()); - } - } - - for (int i = 0; i < message_type_count(); i++) { - if (groups.count(message_type(i)) == 0) { - strings::SubstituteAndAppend(&contents, "message $0", - message_type(i)->name()); - message_type(i)->DebugString(0, &contents); - contents.append("\n"); - } - } - - for (int i = 0; i < service_count(); i++) { - service(i)->DebugString(&contents); - contents.append("\n"); - } - - const Descriptor* containing_type = NULL; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->containing_type() != containing_type) { - if (i > 0) contents.append("}\n\n"); - containing_type = extension(i)->containing_type(); - strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type->full_name()); - } - extension(i)->DebugString(1, &contents); - } - if (extension_count() > 0) contents.append("}\n\n"); - - return contents; -} - -string Descriptor::DebugString() const { - string contents; - strings::SubstituteAndAppend(&contents, "message $0", name()); - DebugString(0, &contents); - return contents; -} - -void Descriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - contents->append(" {\n"); - - FormatLineOptions(depth, options(), contents); - - // Find all the 'group' types for fields and extensions; we will not output - // their nested definitions (those will be done with their group field - // descriptor). - set<const Descriptor*> groups; - for (int i = 0; i < field_count(); i++) { - if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(field(i)->message_type()); - } - } - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { - groups.insert(extension(i)->message_type()); - } - } - - for (int i = 0; i < nested_type_count(); i++) { - if (groups.count(nested_type(i)) == 0) { - strings::SubstituteAndAppend(contents, "$0 message $1", - prefix, nested_type(i)->name()); - nested_type(i)->DebugString(depth, contents); - } - } - for (int i = 0; i < enum_type_count(); i++) { - enum_type(i)->DebugString(depth, contents); - } - for (int i = 0; i < field_count(); i++) { - field(i)->DebugString(depth, contents); - } - - for (int i = 0; i < extension_range_count(); i++) { - strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", - prefix, - extension_range(i)->start, - extension_range(i)->end - 1); - } - - // Group extensions by what they extend, so they can be printed out together. - const Descriptor* containing_type = NULL; - for (int i = 0; i < extension_count(); i++) { - if (extension(i)->containing_type() != containing_type) { - if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); - containing_type = extension(i)->containing_type(); - strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", - prefix, containing_type->full_name()); - } - extension(i)->DebugString(depth + 1, contents); - } - if (extension_count() > 0) - strings::SubstituteAndAppend(contents, "$0 }\n", prefix); - - strings::SubstituteAndAppend(contents, "$0}\n", prefix); -} - -string FieldDescriptor::DebugString() const { - string contents; - int depth = 0; - if (is_extension()) { - strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type()->full_name()); - depth = 1; - } - DebugString(depth, &contents); - if (is_extension()) { - contents.append("}\n"); - } - return contents; -} - -void FieldDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - string field_type; - switch (type()) { - case TYPE_MESSAGE: - field_type = "." + message_type()->full_name(); - break; - case TYPE_ENUM: - field_type = "." + enum_type()->full_name(); - break; - default: - field_type = kTypeToName[type()]; - } - - strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4", - prefix, - kLabelToName[label()], - field_type, - type() == TYPE_GROUP ? message_type()->name() : - name(), - number()); - - bool bracketed = false; - if (has_default_value()) { - bracketed = true; - strings::SubstituteAndAppend(contents, " [default = $0", - DefaultValueAsString(true)); - } - - string formatted_options; - if (FormatBracketedOptions(options(), &formatted_options)) { - contents->append(bracketed ? ", " : " ["); - bracketed = true; - contents->append(formatted_options); - } - - if (bracketed) { - contents->append("]"); - } - - if (type() == TYPE_GROUP) { - message_type()->DebugString(depth, contents); - } else { - contents->append(";\n"); - } -} - -string EnumDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void EnumDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - strings::SubstituteAndAppend(contents, "$0enum $1 {\n", - prefix, name()); - - FormatLineOptions(depth, options(), contents); - - for (int i = 0; i < value_count(); i++) { - value(i)->DebugString(depth, contents); - } - strings::SubstituteAndAppend(contents, "$0}\n", prefix); -} - -string EnumValueDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void EnumValueDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - strings::SubstituteAndAppend(contents, "$0$1 = $2", - prefix, name(), number()); - - string formatted_options; - if (FormatBracketedOptions(options(), &formatted_options)) { - strings::SubstituteAndAppend(contents, " [$0]", formatted_options); - } - contents->append(";\n"); -} - -string ServiceDescriptor::DebugString() const { - string contents; - DebugString(&contents); - return contents; -} - -void ServiceDescriptor::DebugString(string *contents) const { - strings::SubstituteAndAppend(contents, "service $0 {\n", name()); - - FormatLineOptions(1, options(), contents); - - for (int i = 0; i < method_count(); i++) { - method(i)->DebugString(1, contents); - } - - contents->append("}\n"); -} - -string MethodDescriptor::DebugString() const { - string contents; - DebugString(0, &contents); - return contents; -} - -void MethodDescriptor::DebugString(int depth, string *contents) const { - string prefix(depth * 2, ' '); - ++depth; - strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)", - prefix, name(), - input_type()->full_name(), - output_type()->full_name()); - - string formatted_options; - if (FormatLineOptions(depth, options(), &formatted_options)) { - strings::SubstituteAndAppend(contents, " {\n$0$1}\n", - formatted_options, prefix); - } else { - contents->append(";\n"); - } -} -// =================================================================== - -class DescriptorBuilder { - public: - DescriptorBuilder(const DescriptorPool* pool, - DescriptorPool::Tables* tables, - DescriptorPool::ErrorCollector* error_collector); - ~DescriptorBuilder(); - - const FileDescriptor* BuildFile(const FileDescriptorProto& proto); - - private: - const DescriptorPool* pool_; - DescriptorPool::Tables* tables_; // for convenience - DescriptorPool::ErrorCollector* error_collector_; - bool had_errors_; - string filename_; - FileDescriptor* file_; - - // If LookupSymbol() finds a symbol that is in a file which is not a declared - // dependency of this file, it will fail, but will set - // possible_undeclared_dependency_ to point at that file. This is only used - // by AddNotDefinedError() to report a more useful error message. - const FileDescriptor* possible_undeclared_dependency_; - - void AddError(const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& error); - - // Adds an error indicating that undefined_symbol was not defined. Must - // only be called after LookupSymbol() fails. - void AddNotDefinedError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& undefined_symbol); - - // Silly helper which determines if the given file is in the given package. - // I.e., either file->package() == package_name or file->package() is a - // nested package within package_name. - bool IsInPackage(const FileDescriptor* file, const string& package_name); - - // Like tables_->FindSymbol(), but additionally: - // - Search the pool's underlay if not found in tables_. - // - Insure that the resulting Symbol is from one of the file's declared - // dependencies. - Symbol FindSymbol(const string& name); - - // Like FindSymbol(), but looks up the name relative to some other symbol - // name. This first searches syblings of relative_to, then siblings of its - // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes - // the following calls, returning the first non-null result: - // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), - // FindSymbol("foo.bar"). - Symbol LookupSymbol(const string& name, const string& relative_to); - - // Calls tables_->AddSymbol() and records an error if it fails. Returns - // true if successful or false if failed, though most callers can ignore - // the return value since an error has already been recorded. - bool AddSymbol(const string& full_name, - const void* parent, const string& name, - const Message& proto, Symbol symbol); - - // Like AddSymbol(), but succeeds if the symbol is already defined as long - // as the existing definition is also a package (because it's OK to define - // the same package in two different files). Also adds all parents of the - // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add - // "foo.bar" and "foo" to the table). - void AddPackage(const string& name, const Message& proto, - const FileDescriptor* file); - - // Checks that the symbol name contains only alphanumeric characters and - // underscores. Records an error otherwise. - void ValidateSymbolName(const string& name, const string& full_name, - const Message& proto); - - // Used by BUILD_ARRAY macro (below) to avoid having to have the type - // specified as a macro parameter. - template <typename Type> - inline void AllocateArray(int size, Type** output) { - *output = tables_->AllocateArray<Type>(size); - } - - // These methods all have the same signature for the sake of the BUILD_ARRAY - // macro, below. - void BuildMessage(const DescriptorProto& proto, - const Descriptor* parent, - Descriptor* result); - void BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result, - bool is_extension); - void BuildField(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result) { - BuildFieldOrExtension(proto, parent, result, false); - } - void BuildExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result) { - BuildFieldOrExtension(proto, parent, result, true); - } - void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, - const Descriptor* parent, - Descriptor::ExtensionRange* result); - void BuildEnum(const EnumDescriptorProto& proto, - const Descriptor* parent, - EnumDescriptor* result); - void BuildEnumValue(const EnumValueDescriptorProto& proto, - const EnumDescriptor* parent, - EnumValueDescriptor* result); - void BuildService(const ServiceDescriptorProto& proto, - const void* dummy, - ServiceDescriptor* result); - void BuildMethod(const MethodDescriptorProto& proto, - const ServiceDescriptor* parent, - MethodDescriptor* result); - - void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); - void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); - void CrossLinkField(FieldDescriptor* field, - const FieldDescriptorProto& proto); - void CrossLinkService(ServiceDescriptor* service, - const ServiceDescriptorProto& proto); - void CrossLinkMethod(MethodDescriptor* method, - const MethodDescriptorProto& proto); - void CrossLinkMapKey(FieldDescriptor* field, - const FieldDescriptorProto& proto); -}; - -const FileDescriptor* DescriptorPool::BuildFile( - const FileDescriptorProto& proto) { - GOOGLE_CHECK(fallback_database_ == NULL) - << "Cannot call BuildFile on a DescriptorPool that uses a " - "DescriptorDatabase. You must instead find a way to get your file " - "into the underlying database."; - GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. - return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); -} - -const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( - const FileDescriptorProto& proto, - ErrorCollector* error_collector) { - GOOGLE_CHECK(fallback_database_ == NULL) - << "Cannot call BuildFile on a DescriptorPool that uses a " - "DescriptorDatabase. You must instead find a way to get your file " - "into the underlying database."; - GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. - return DescriptorBuilder(this, tables_.get(), - error_collector).BuildFile(proto); -} - -const FileDescriptor* DescriptorPool::BuildFileFromDatabase( - const FileDescriptorProto& proto) const { - mutex_->AssertHeld(); - return DescriptorBuilder(this, tables_.get(), - default_error_collector_).BuildFile(proto); -} - -const FileDescriptor* DescriptorPool::InternalBuildGeneratedFile( - const void* data, int size) { - // So, this function is called in the process of initializing the - // descriptors for generated proto classes. Each generated .pb.cc file - // has an internal procedure called BuildDescriptors() which is called the - // first time one of its descriptors is accessed, and that function calls - // this one in order to parse the raw bytes of the FileDescriptorProto - // representing the file. - // - // Note, though, that FileDescriptorProto is itself a generated protocol - // message. So, when we attempt to construct one below, it will attempt - // to initialize its own descriptors via its own BuildDescriptors() method. - // This will in turn cause InternalBuildGeneratedFile() to build - // descriptor.proto's descriptors. - // - // We are saved from an infinite loop by the fact that BuildDescriptors() - // only does anything the first time it is called. That is, the first few - // lines of any BuildDescriptors() procedure look like this: - // void BuildDescriptors() { - // static bool already_here = false; - // if (already_here) return; - // already_here = true; - // ... - // So, when descriptor.pb.cc's BuildDescriptors() is called recursively, it - // will end up just returning without doing anything. The result is that - // all of the descriptors for FileDescriptorProto and friends will just be - // NULL. - // - // Luckily, it turns out that our limited use of FileDescriptorProto within - // InternalBuildGeneratedFile() does not require that its descriptors be - // initialized. So, this ends up working. As soon as - // InternalBuildGeneratedFile() returns, the descriptors will be initialized - // by the original call to BuildDescriptors(), and everything will be happy - // again. - // - // If this turns out to be too fragile a hack, there are other ways we - // can accomplish bootstrapping here (like building the descriptor for - // descriptor.proto manually), but if this works then it's a lot easier. - // - // Note that because this is only triggered at static initialization time, - // there are no thread-safety concerns here. - FileDescriptorProto proto; - GOOGLE_CHECK(proto.ParseFromArray(data, size)); - const FileDescriptor* result = BuildFile(proto); - GOOGLE_CHECK(result != NULL); - - return result; -} - -DescriptorBuilder::DescriptorBuilder( - const DescriptorPool* pool, - DescriptorPool::Tables* tables, - DescriptorPool::ErrorCollector* error_collector) - : pool_(pool), - tables_(tables), - error_collector_(error_collector), - had_errors_(false), - possible_undeclared_dependency_(NULL) {} - -DescriptorBuilder::~DescriptorBuilder() {} - -void DescriptorBuilder::AddError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& error) { - if (error_collector_ == NULL) { - if (!had_errors_) { - GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ - << "\":"; - } - GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; - } else { - error_collector_->AddError(filename_, element_name, - &descriptor, location, error); - } - had_errors_ = true; -} - -void DescriptorBuilder::AddNotDefinedError( - const string& element_name, - const Message& descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - const string& undefined_symbol) { - if (possible_undeclared_dependency_ == NULL) { - AddError(element_name, descriptor, location, - "\"" + undefined_symbol + "\" is not defined."); - } else { - AddError(element_name, descriptor, location, - "\"" + undefined_symbol + "\" seems to be defined in \"" - + possible_undeclared_dependency_->name() + "\", which is not " - "imported by \"" + filename_ + "\". To use it here, please " - "add the necessary import."); - } -} - -bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, - const string& package_name) { - return HasPrefixString(file->package(), package_name) && - (file->package().size() == package_name.size() || - file->package()[package_name.size()] == '.'); -} - -Symbol DescriptorBuilder::FindSymbol(const string& name) { - Symbol result; - - // We need to search our pool and all its underlays. - const DescriptorPool* pool = pool_; - while (true) { - // If we are looking at an underlay, we must lock its mutex_, since we are - // accessing the underlay's tables_ dircetly. - MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); - - // Note that we don't have to check fallback_database_ here because the - // symbol has to be in one of its file's direct dependencies, and we have - // already loaded those by the time we get here. - result = pool->tables_->FindSymbol(name); - if (!result.IsNull()) break; - if (pool->underlay_ == NULL) return kNullSymbol; - pool = pool->underlay_; - } - - if (!pool_->enforce_dependencies_) { - // Hack for CompilerUpgrader. - return result; - } - - // Only find symbols which were defined in this file or one of its - // dependencies. - const FileDescriptor* file = result.GetFile(); - if (file == file_) return result; - for (int i = 0; i < file_->dependency_count(); i++) { - if (file == file_->dependency(i)) return result; - } - - if (result.type == Symbol::PACKAGE) { - // Arg, this is overcomplicated. The symbol is a package name. It could - // be that the package was defined in multiple files. result.GetFile() - // returns the first file we saw that used this package. We've determined - // that that file is not a direct dependency of the file we are currently - // building, but it could be that some other file which *is* a direct - // dependency also defines the same package. We can't really rule out this - // symbol unless none of the dependencies define it. - if (IsInPackage(file_, name)) return result; - for (int i = 0; i < file_->dependency_count(); i++) { - if (IsInPackage(file_->dependency(i), name)) return result; - } - } - - possible_undeclared_dependency_ = file; - return kNullSymbol; -} - -Symbol DescriptorBuilder::LookupSymbol( - const string& name, const string& relative_to) { - possible_undeclared_dependency_ = NULL; - - if (name.size() > 0 && name[0] == '.') { - // Fully-qualified name. - return FindSymbol(name.substr(1)); - } - - // If name is something like "Foo.Bar.baz", and symbols named "Foo" are - // defined in multiple parent scopes, we only want to find "Bar.baz" in the - // innermost one. E.g., the following should produce an error: - // message Bar { message Baz {} } - // message Foo { - // message Bar { - // } - // optional Bar.Baz baz = 1; - // } - // So, we look for just "Foo" first, then look for "Bar.baz" within it if - // found. - int name_dot_pos = name.find_first_of('.'); - string first_part_of_name; - if (name_dot_pos == string::npos) { - first_part_of_name = name; - } else { - first_part_of_name = name.substr(0, name_dot_pos); - } - - string scope_to_try(relative_to); - - while (true) { - // Chop off the last component of the scope. - string::size_type dot_pos = scope_to_try.find_last_of('.'); - if (dot_pos == string::npos) { - return FindSymbol(name); - } else { - scope_to_try.erase(dot_pos); - } - - // Append ".first_part_of_name" and try to find. - string::size_type old_size = scope_to_try.size(); - scope_to_try.append(1, '.'); - scope_to_try.append(first_part_of_name); - Symbol result = FindSymbol(scope_to_try); - if (!result.IsNull()) { - if (first_part_of_name.size() < name.size()) { - // name is a compound symbol, of which we only found the first part. - // Now try to look up the rest of it. - scope_to_try.append(name, first_part_of_name.size(), - name.size() - first_part_of_name.size()); - result = FindSymbol(scope_to_try); - } - return result; - } - - // Not found. Remove the name so we can try again. - scope_to_try.erase(old_size); - } -} - -bool DescriptorBuilder::AddSymbol( - const string& full_name, const void* parent, const string& name, - const Message& proto, Symbol symbol) { - // If the caller passed NULL for the parent, the symbol is at file scope. - // Use its file as the parent instead. - if (parent == NULL) parent = file_; - - if (tables_->AddSymbol(full_name, parent, name, symbol)) { - return true; - } else { - const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); - if (other_file == file_) { - string::size_type dot_pos = full_name.find_last_of('.'); - if (dot_pos == string::npos) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name + "\" is already defined."); - } else { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name.substr(dot_pos + 1) + - "\" is already defined in \"" + - full_name.substr(0, dot_pos) + "\"."); - } - } else { - // Symbol seems to have been defined in a different file. - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + full_name + "\" is already defined in file \"" + - other_file->name() + "\"."); - } - return false; - } -} - -void DescriptorBuilder::AddPackage( - const string& name, const Message& proto, const FileDescriptor* file) { - if (tables_->AddSymbol(name, NULL, name, Symbol(file))) { - // Success. Also add parent package, if any. - string::size_type dot_pos = name.find_last_of('.'); - if (dot_pos == string::npos) { - // No parents. - ValidateSymbolName(name, name, proto); - } else { - // Has parent. - string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); - AddPackage(*parent_name, proto, file); - ValidateSymbolName(name.substr(dot_pos + 1), name, proto); - } - } else { - Symbol existing_symbol = tables_->FindSymbol(name); - // It's OK to redefine a package. - if (existing_symbol.type != Symbol::PACKAGE) { - // Symbol seems to have been defined in a different file. - AddError(name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + name + "\" is already defined (as something other than " - "a package) in file \"" + existing_symbol.GetFile()->name() + - "\"."); - } - } -} - -void DescriptorBuilder::ValidateSymbolName( - const string& name, const string& full_name, const Message& proto) { - if (name.empty()) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "Missing name."); - } else { - for (int i = 0; i < name.size(); i++) { - // I don't trust isalnum() due to locales. :( - if ((name[i] < 'a' || 'z' < name[i]) && - (name[i] < 'A' || 'Z' < name[i]) && - (name[i] < '0' || '9' < name[i]) && - (name[i] != '_')) { - AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, - "\"" + name + "\" is not a valid identifier."); - } - } - } -} - -// ------------------------------------------------------------------- - -// A common pattern: We want to convert a repeated field in the descriptor -// to an array of values, calling some method to build each value. -#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ - OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ - AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ - for (int i = 0; i < INPUT.NAME##_size(); i++) { \ - METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ - } - -const FileDescriptor* DescriptorBuilder::BuildFile( - const FileDescriptorProto& proto) { - filename_ = proto.name(); - - // Check to see if this file is already on the pending files list. - // TODO(kenton): Allow recursive imports? It may not work with some - // (most?) programming languages. E.g., in C++, a forward declaration - // of a type is not sufficient to allow it to be used even in a - // generated header file due to inlining. This could perhaps be - // worked around using tricks involving inserting #include statements - // mid-file, but that's pretty ugly, and I'm pretty sure there are - // some languages out there that do not allow recursive dependencies - // at all. - for (int i = 0; i < tables_->pending_files_.size(); i++) { - if (tables_->pending_files_[i] == proto.name()) { - string error_message("File recursively imports itself: "); - for (; i < tables_->pending_files_.size(); i++) { - error_message.append(tables_->pending_files_[i]); - error_message.append(" -> "); - } - error_message.append(proto.name()); - - AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, - error_message); - return NULL; - } - } - - // If we have a fallback_database_, attempt to load all dependencies now, - // before checkpointing tables_. This avoids confusion with recursive - // checkpoints. - if (pool_->fallback_database_ != NULL) { - tables_->pending_files_.push_back(proto.name()); - for (int i = 0; i < proto.dependency_size(); i++) { - if (tables_->FindFile(proto.dependency(i)) == NULL && - (pool_->underlay_ == NULL || - pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { - // We don't care what this returns since we'll find out below anyway. - pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); - } - } - tables_->pending_files_.pop_back(); - } - - // Checkpoint the tables so that we can roll back if something goes wrong. - tables_->Checkpoint(); - - FileDescriptor* result = tables_->Allocate<FileDescriptor>(); - file_ = result; - - if (!proto.has_name()) { - AddError("", proto, DescriptorPool::ErrorCollector::OTHER, - "Missing field: FileDescriptorProto.name."); - } - - result->name_ = tables_->AllocateString(proto.name()); - if (proto.has_package()) { - result->package_ = tables_->AllocateString(proto.package()); - } else { - // We cannot rely on proto.package() returning a valid string if - // proto.has_package() is false, because we might be running at static - // initialization time, in which case default values have not yet been - // initialized. - result->package_ = tables_->AllocateString(""); - } - result->pool_ = pool_; - - // Add to tables. - if (!tables_->AddFile(result)) { - AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, - "A file with this name is already in the pool."); - // Bail out early so that if this is actually the exact same file, we - // don't end up reporting that every single symbol is already defined. - tables_->Rollback(); - return NULL; - } - if (!result->package().empty()) { - AddPackage(result->package(), proto, result); - } - - // Make sure all dependencies are loaded. - set<string> seen_dependencies; - result->dependency_count_ = proto.dependency_size(); - result->dependencies_ = - tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); - for (int i = 0; i < proto.dependency_size(); i++) { - if (!seen_dependencies.insert(proto.dependency(i)).second) { - AddError(proto.name(), proto, - DescriptorPool::ErrorCollector::OTHER, - "Import \"" + proto.dependency(i) + "\" was listed twice."); - } - - const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); - if (dependency == NULL && pool_->underlay_ != NULL) { - dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); - } - - if (dependency == NULL) { - string message; - if (pool_->fallback_database_ == NULL) { - message = "Import \"" + proto.dependency(i) + - "\" has not been loaded."; - } else { - message = "Import \"" + proto.dependency(i) + - "\" was not found or had errors."; - } - AddError(proto.name(), proto, - DescriptorPool::ErrorCollector::OTHER, - message); - } - - result->dependencies_[i] = dependency; - } - - // Convert children. - BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); - BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); - BUILD_ARRAY(proto, result, service , BuildService , NULL); - BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); - - // Copy options. - if (!proto.has_options()) { - result->options_ = &FileOptions::default_instance(); - } else { - FileOptions* options = tables_->AllocateMessage<FileOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - // Cross-link. - CrossLinkFile(result, proto); - - if (had_errors_) { - tables_->Rollback(); - return NULL; - } else { - tables_->Checkpoint(); - return result; - } -} - -void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, - const Descriptor* parent, - Descriptor* result) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->containing_type_ = parent; - - BUILD_ARRAY(proto, result, field , BuildField , result); - BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); - BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); - BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); - BUILD_ARRAY(proto, result, extension , BuildExtension , result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = &MessageOptions::default_instance(); - } else { - MessageOptions* options = tables_->AllocateMessage<MessageOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); - - // Check that no fields have numbers in extension ranges. - for (int i = 0; i < result->field_count(); i++) { - const FieldDescriptor* field = result->field(i); - for (int j = 0; j < result->extension_range_count(); j++) { - const Descriptor::ExtensionRange* range = result->extension_range(j); - if (range->start <= field->number() && field->number() < range->end) { - AddError(field->full_name(), proto.extension_range(j), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute( - "Extension range $0 to $1 includes field \"$2\" ($3).", - range->start, range->end - 1, - field->name(), field->number())); - } - } - } - - // Check that extension ranges don't overlap. - for (int i = 0; i < result->extension_range_count(); i++) { - const Descriptor::ExtensionRange* range1 = result->extension_range(i); - for (int j = i + 1; j < result->extension_range_count(); j++) { - const Descriptor::ExtensionRange* range2 = result->extension_range(j); - if (range1->end > range2->start && range2->end > range1->start) { - AddError(result->full_name(), proto.extension_range(j), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension range $0 to $1 overlaps with " - "already-defined range $2 to $3.", - range2->start, range2->end - 1, - range1->start, range1->end - 1)); - } - } - } -} - -void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, - FieldDescriptor* result, - bool is_extension) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->number_ = proto.number(); - result->type_ = static_cast<FieldDescriptor::Type>(proto.type()); - result->label_ = static_cast<FieldDescriptor::Label>(proto.label()); - result->is_extension_ = is_extension; - - // Some of these may be filled in when cross-linking. - result->containing_type_ = NULL; - result->extension_scope_ = NULL; - result->experimental_map_key_ = NULL; - result->message_type_ = NULL; - result->enum_type_ = NULL; - - result->has_default_value_ = proto.has_default_value(); - if (proto.has_type()) { - if (proto.has_default_value()) { - char* end_pos = NULL; - switch (result->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = - strtol(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = - strto64(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = - strtoul(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = - strtou64(proto.default_value().c_str(), &end_pos, 0); - break; - case FieldDescriptor::CPPTYPE_FLOAT: - result->default_value_float_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); - break; - case FieldDescriptor::CPPTYPE_DOUBLE: - result->default_value_double_ = - NoLocaleStrtod(proto.default_value().c_str(), &end_pos); - break; - case FieldDescriptor::CPPTYPE_BOOL: - if (proto.default_value() == "true") { - result->default_value_bool_ = true; - } else if (proto.default_value() == "false") { - result->default_value_bool_ = false; - } else { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Boolean default must be true or false."); - } - break; - case FieldDescriptor::CPPTYPE_ENUM: - // This will be filled in when cross-linking. - result->default_value_enum_ = NULL; - break; - case FieldDescriptor::CPPTYPE_STRING: - if (result->type() == FieldDescriptor::TYPE_BYTES) { - result->default_value_string_ = tables_->AllocateString( - UnescapeCEscapeString(proto.default_value())); - } else { - result->default_value_string_ = - tables_->AllocateString(proto.default_value()); - } - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Messages can't have default values."); - result->has_default_value_ = false; - break; - } - - if (end_pos != NULL) { - // end_pos is only set non-NULL by the parsers for numeric types, above. - // This checks that the default was non-empty and had no extra junk - // after the end of the number. - if (proto.default_value().empty() || *end_pos != '\0') { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Couldn't parse default value."); - } - } - } else { - // No explicit default value - switch (result->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - result->default_value_int32_ = 0; - break; - case FieldDescriptor::CPPTYPE_INT64: - result->default_value_int64_ = 0; - break; - case FieldDescriptor::CPPTYPE_UINT32: - result->default_value_uint32_ = 0; - break; - case FieldDescriptor::CPPTYPE_UINT64: - result->default_value_uint64_ = 0; - break; - case FieldDescriptor::CPPTYPE_FLOAT: - result->default_value_float_ = 0.0f; - break; - case FieldDescriptor::CPPTYPE_DOUBLE: - result->default_value_double_ = 0.0; - break; - case FieldDescriptor::CPPTYPE_BOOL: - result->default_value_bool_ = false; - break; - case FieldDescriptor::CPPTYPE_ENUM: - // This will be filled in when cross-linking. - result->default_value_enum_ = NULL; - break; - case FieldDescriptor::CPPTYPE_STRING: - result->default_value_string_ = &kEmptyString; - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - break; - } - } - } - - if (result->number() <= 0) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - "Field numbers must be positive integers."); - } else if (result->number() > FieldDescriptor::kMaxNumber) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Field numbers cannot be greater than $0.", - FieldDescriptor::kMaxNumber)); - } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && - result->number() <= FieldDescriptor::kLastReservedNumber) { - AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute( - "Field numbers $0 through $1 are reserved for the protocol " - "buffer library implementation.", - FieldDescriptor::kFirstReservedNumber, - FieldDescriptor::kLastReservedNumber)); - } - - if (is_extension) { - if (!proto.has_extendee()) { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "FieldDescriptorProto.extendee not set for extension field."); - } - - result->extension_scope_ = parent; - } else { - if (proto.has_extendee()) { - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "FieldDescriptorProto.extendee set for non-extension field."); - } - - result->containing_type_ = parent; - } - - // Copy options. - if (!proto.has_options()) { - result->options_ = &FieldOptions::default_instance(); - } else { - FieldOptions* options = tables_->AllocateMessage<FieldOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildExtensionRange( - const DescriptorProto::ExtensionRange& proto, - const Descriptor* parent, - Descriptor::ExtensionRange* result) { - result->start = proto.start(); - result->end = proto.end(); - if (result->start <= 0) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - "Extension numbers must be positive integers."); - } - - if (result->end > FieldDescriptor::kMaxNumber + 1) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension numbers cannot be greater than $0.", - FieldDescriptor::kMaxNumber)); - } - - if (result->start >= result->end) { - AddError(parent->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - "Extension range end number must be greater than start number."); - } -} - -void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, - const Descriptor* parent, - EnumDescriptor* result) { - const string& scope = (parent == NULL) ? - file_->package() : parent->full_name(); - string* full_name = tables_->AllocateString(scope); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - result->containing_type_ = parent; - - if (proto.value_size() == 0) { - // We cannot allow enums with no values because this would mean there - // would be no valid default value for fields of this type. - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "Enums must contain at least one value."); - } - - BUILD_ARRAY(proto, result, value, BuildEnumValue, result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = &EnumOptions::default_instance(); - } else { - EnumOptions* options = tables_->AllocateMessage<EnumOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, - const EnumDescriptor* parent, - EnumValueDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); - result->number_ = proto.number(); - result->type_ = parent; - - // Note: full_name for enum values is a sibling to the parent's name, not a - // child of it. - string* full_name = tables_->AllocateString(*parent->full_name_); - full_name->resize(full_name->size() - parent->name_->size()); - full_name->append(*result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); - - // Copy options. - if (!proto.has_options()) { - result->options_ = &EnumValueOptions::default_instance(); - } else { - EnumValueOptions* options = tables_->AllocateMessage<EnumValueOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - // Again, enum values are weird because we makes them appear as siblings - // of the enum type instead of children of it. So, we use - // parent->containing_type() as the value's parent. - bool added_to_outer_scope = - AddSymbol(result->full_name(), parent->containing_type(), result->name(), - proto, Symbol(result)); - - // However, we also want to be able to search for values within a single - // enum type, so we add it as a child of the enum type itself, too. - // Note: This could fail, but if it does, the error has already been - // reported by the above AddSymbol() call, so we ignore the return code. - bool added_to_inner_scope = - tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); - - if (added_to_inner_scope && !added_to_outer_scope) { - // This value did not conflict with any values defined in the same enum, - // but it did conflict with some other symbol defined in the enum type's - // scope. Let's print an additional error to explain this. - string outer_scope; - if (parent->containing_type() == NULL) { - outer_scope = file_->package(); - } else { - outer_scope = parent->containing_type()->full_name(); - } - - if (outer_scope.empty()) { - outer_scope = "the global scope"; - } else { - outer_scope = "\"" + outer_scope + "\""; - } - - AddError(result->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "Note that enum values use C++ scoping rules, meaning that " - "enum values are siblings of their type, not children of it. " - "Therefore, \"" + result->name() + "\" must be unique within " - + outer_scope + ", not just within \"" + parent->name() + "\"."); - } - - // An enum is allowed to define two numbers that refer to the same value. - // FindValueByNumber() should return the first such value, so we simply - // ignore AddEnumValueByNumber()'s return code. - tables_->AddEnumValueByNumber(result); -} - -void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, - const void* dummy, - ServiceDescriptor* result) { - string* full_name = tables_->AllocateString(file_->package()); - if (!full_name->empty()) full_name->append(1, '.'); - full_name->append(proto.name()); - - ValidateSymbolName(proto.name(), *full_name, proto); - - result->name_ = tables_->AllocateString(proto.name()); - result->full_name_ = full_name; - result->file_ = file_; - - BUILD_ARRAY(proto, result, method, BuildMethod, result); - - // Copy options. - if (!proto.has_options()) { - result->options_ = &ServiceOptions::default_instance(); - } else { - ServiceOptions* options = tables_->AllocateMessage<ServiceOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - AddSymbol(result->full_name(), NULL, result->name(), - proto, Symbol(result)); -} - -void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, - const ServiceDescriptor* parent, - MethodDescriptor* result) { - result->name_ = tables_->AllocateString(proto.name()); - result->service_ = parent; - - string* full_name = tables_->AllocateString(parent->full_name()); - full_name->append(1, '.'); - full_name->append(*result->name_); - result->full_name_ = full_name; - - ValidateSymbolName(proto.name(), *full_name, proto); - - // These will be filled in when cross-linking. - result->input_type_ = NULL; - result->output_type_ = NULL; - - // Copy options. - if (!proto.has_options()) { - result->options_ = &MethodOptions::default_instance(); - } else { - MethodOptions* options = tables_->AllocateMessage<MethodOptions>(); - options->CopyFrom(proto.options()); - result->options_ = options; - } - - AddSymbol(result->full_name(), parent, result->name(), - proto, Symbol(result)); -} - -#undef BUILD_ARRAY - -// ------------------------------------------------------------------- - -void DescriptorBuilder::CrossLinkFile( - FileDescriptor* file, const FileDescriptorProto& proto) { - for (int i = 0; i < file->message_type_count(); i++) { - CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); - } - - for (int i = 0; i < file->extension_count(); i++) { - CrossLinkField(&file->extensions_[i], proto.extension(i)); - } - - for (int i = 0; i < file->service_count(); i++) { - CrossLinkService(&file->services_[i], proto.service(i)); - } -} - -void DescriptorBuilder::CrossLinkMessage( - Descriptor* message, const DescriptorProto& proto) { - for (int i = 0; i < message->nested_type_count(); i++) { - CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); - } - - for (int i = 0; i < message->field_count(); i++) { - CrossLinkField(&message->fields_[i], proto.field(i)); - } - - for (int i = 0; i < message->extension_count(); i++) { - CrossLinkField(&message->extensions_[i], proto.extension(i)); - } -} - -void DescriptorBuilder::CrossLinkField( - FieldDescriptor* field, const FieldDescriptorProto& proto) { - if (proto.has_extendee()) { - Symbol extendee = LookupSymbol(proto.extendee(), field->full_name()); - if (extendee.IsNull()) { - AddNotDefinedError(field->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - proto.extendee()); - return; - } else if (extendee.type != Symbol::MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::EXTENDEE, - "\"" + proto.extendee() + "\" is not a message type."); - return; - } - field->containing_type_ = extendee.descriptor; - - if (!field->containing_type()->IsExtensionNumber(field->number())) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("\"$0\" does not declare $1 as an " - "extension number.", - field->containing_type()->full_name(), - field->number())); - } - } - - if (proto.has_type_name()) { - Symbol type = LookupSymbol(proto.type_name(), field->full_name()); - if (type.IsNull()) { - AddNotDefinedError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - proto.type_name()); - return; - } - - if (!proto.has_type()) { - // Choose field type based on symbol. - if (type.type == Symbol::MESSAGE) { - field->type_ = FieldDescriptor::TYPE_MESSAGE; - } else if (type.type == Symbol::ENUM) { - field->type_ = FieldDescriptor::TYPE_ENUM; - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not a type."); - return; - } - } - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (type.type != Symbol::MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not a message type."); - return; - } - field->message_type_ = type.descriptor; - - if (field->has_default_value()) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Messages can't have default values."); - } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - if (type.type != Symbol::ENUM) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "\"" + proto.type_name() + "\" is not an enum type."); - return; - } - field->enum_type_ = type.enum_descriptor; - - if (field->has_default_value()) { - // We can't just use field->enum_type()->FindValueByName() here - // because that locks the pool's mutex, which we have already locked - // at this point. - Symbol default_value = - LookupSymbol(proto.default_value(), field->enum_type()->full_name()); - - if (default_value.type == Symbol::ENUM_VALUE && - default_value.enum_value_descriptor->type() == field->enum_type()) { - field->default_value_enum_ = default_value.enum_value_descriptor; - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::DEFAULT_VALUE, - "Enum type \"" + field->enum_type()->full_name() + - "\" has no value named \"" + proto.default_value() + "\"."); - } - } else if (field->enum_type()->value_count() > 0) { - // All enums must have at least one value, or we would have reported - // an error elsewhere. We use the first defined value as the default - // if a default is not explicitly defined. - field->default_value_enum_ = field->enum_type()->value(0); - } - } else { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Field with primitive type has type_name."); - } - } else { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Field with message or enum type missing type_name."); - } - } - - if (proto.has_options() && proto.options().has_experimental_map_key()) { - CrossLinkMapKey(field, proto); - } - - // Add the field to the fields-by-number table. - // Note: We have to do this *after* cross-linking because extensions do not - // know their containing type until now. - if (!tables_->AddFieldByNumber(field)) { - const FieldDescriptor* conflicting_field = - tables_->FindFieldByNumber(field->containing_type(), field->number()); - if (field->is_extension()) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension number $0 has already been used " - "in \"$1\" by extension \"$2\".", - field->number(), - field->containing_type()->full_name(), - conflicting_field->full_name())); - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Field number $0 has already been used in " - "\"$1\" by field \"$2\".", - field->number(), - field->containing_type()->full_name(), - conflicting_field->name())); - } - } - - // Note: Default instance may not yet be initialized here, so we have to - // avoid reading from it. - if (field->containing_type_ != NULL && - &field->containing_type()->options() != - &MessageOptions::default_instance() && - field->containing_type()->options().message_set_wire_format()) { - if (field->is_extension()) { - if (!field->is_optional() || - field->type() != FieldDescriptor::TYPE_MESSAGE) { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - "Extensions of MessageSets must be optional messages."); - } - } else { - AddError(field->full_name(), proto, - DescriptorPool::ErrorCollector::NAME, - "MessageSets cannot have fields, only extensions."); - } - } -} - -void DescriptorBuilder::CrossLinkService( - ServiceDescriptor* service, const ServiceDescriptorProto& proto) { - for (int i = 0; i < service->method_count(); i++) { - CrossLinkMethod(&service->methods_[i], proto.method(i)); - } -} - -void DescriptorBuilder::CrossLinkMethod( - MethodDescriptor* method, const MethodDescriptorProto& proto) { - Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); - if (input_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::INPUT_TYPE, - proto.input_type()); - } else if (input_type.type != Symbol::MESSAGE) { - AddError(method->full_name(), proto, - DescriptorPool::ErrorCollector::INPUT_TYPE, - "\"" + proto.input_type() + "\" is not a message type."); - } else { - method->input_type_ = input_type.descriptor; - } - - Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); - if (output_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::OUTPUT_TYPE, - proto.output_type()); - } else if (output_type.type != Symbol::MESSAGE) { - AddError(method->full_name(), proto, - DescriptorPool::ErrorCollector::OUTPUT_TYPE, - "\"" + proto.output_type() + "\" is not a message type."); - } else { - method->output_type_ = output_type.descriptor; - } -} - -void DescriptorBuilder::CrossLinkMapKey( - FieldDescriptor* field, - const FieldDescriptorProto& proto) { - if (!field->is_repeated()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map type is only allowed for repeated fields."); - return; - } - - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map type is only allowed for fields with a message type."); - return; - } - - const Descriptor* item_type = field->message_type(); - if (item_type == NULL) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Could not find field type."); - return; - } - - // Find the field in item_type named by "experimental_map_key" - const string& key_name = proto.options().experimental_map_key(); - const Symbol key_symbol = LookupSymbol( - key_name, - // We append ".key_name" to the containing type's name since - // LookupSymbol() searches for peers of the supplied name, not - // children of the supplied name. - item_type->full_name() + "." + key_name); - - if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "Could not find field named \"" + key_name + "\" in type \"" + - item_type->full_name() + "\"."); - return; - } - const FieldDescriptor* key_field = key_symbol.field_descriptor; - - if (key_field->is_repeated()) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map_key must not name a repeated field."); - return; - } - - if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, - "map key must name a scalar or string field."); - return; - } - - field->experimental_map_key_ = key_field; -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h deleted file mode 100644 index 5f3fa0a2..00000000 --- a/src/google/protobuf/descriptor.h +++ /dev/null @@ -1,1185 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains classes which describe a type of protocol message. -// You can use a message's descriptor to learn at runtime what fields -// it contains and what the types of those fields are. The Message -// interface also allows you to dynamically access and modify individual -// fields by passing the FieldDescriptor of the field you are interested -// in. -// -// Most users will not care about descriptors, because they will write -// code specific to certain protocol types and will simply use the classes -// generated by the protocol compiler directly. Advanced users who want -// to operate on arbitrary types (not known at compile time) may want to -// read descriptors in order to learn about the contents of a message. -// A very small number of users will want to construct their own -// Descriptors, either because they are implementing Message manually or -// because they are writing something like the protocol compiler. -// -// For an example of how you might use descriptors, see the code example -// at the top of message.h. - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ -#define GOOGLE_PROTOBUF_DESCRIPTOR_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - - -namespace google { -namespace protobuf { - -// Defined in this file. -class Descriptor; -class FieldDescriptor; -class EnumDescriptor; -class EnumValueDescriptor; -class ServiceDescriptor; -class MethodDescriptor; -class FileDescriptor; -class DescriptorDatabase; -class DescriptorPool; - -// Defined in descriptor.proto -class DescriptorProto; -class FieldDescriptorProto; -class EnumDescriptorProto; -class EnumValueDescriptorProto; -class ServiceDescriptorProto; -class MethodDescriptorProto; -class FileDescriptorProto; -class MessageOptions; -class FieldOptions; -class EnumOptions; -class EnumValueOptions; -class ServiceOptions; -class MethodOptions; -class FileOptions; - -// Defined in message.h -class Message; - -// Defined in descriptor.cc -class DescriptorBuilder; - -// Describes a type of protocol message, or a particular group within a -// message. To obtain the Descriptor for a given message object, call -// Message::GetDescriptor(). Generated message classes also have a -// static method called descriptor() which returns the type's descriptor. -// Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT Descriptor { - public: - // The name of the message type, not including its scope. - const string& name() const; - - // The fully-qualified name of the message type, scope delimited by - // periods. For example, message type "Foo" which is declared in package - // "bar" has full name "bar.Foo". If a type "Baz" is nested within - // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that - // comes after the last '.', use name(). - const string& full_name() const; - - // Index of this descriptor within the file or containing type's message - // type array. - int index() const; - - // The .proto file in which this message type was defined. Never NULL. - const FileDescriptor* file() const; - - // If this Descriptor describes a nested type, this returns the type - // in which it is nested. Otherwise, returns NULL. - const Descriptor* containing_type() const; - - // Get options for this message type. These are specified in the .proto - // file by placing lines like "option foo = 1234;" in the message definition. - // The exact set of known options is defined by MessageOptions in - // google/protobuf/descriptor.proto. - const MessageOptions& options() const; - - // Write the contents of this Descriptor into the given DescriptorProto. - // The target DescriptorProto must be clear before calling this; if it - // isn't, the result may be garbage. - void CopyTo(DescriptorProto* proto) const; - - // Write the contents of this decriptor in a human-readable form. Output - // will be suitable for re-parsing. - string DebugString() const; - - // Field stuff ----------------------------------------------------- - - // The number of fields in this message type. - int field_count() const; - // Gets a field by index, where 0 <= index < field_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* field(int index) const; - - // Looks up a field by declared tag number. Returns NULL if no such field - // exists. - const FieldDescriptor* FindFieldByNumber(int number) const; - // Looks up a field by name. Returns NULL if no such field exists. - const FieldDescriptor* FindFieldByName(const string& name) const; - - // Nested type stuff ----------------------------------------------- - - // The number of nested types in this message type. - int nested_type_count() const; - // Gets a nested type by index, where 0 <= index < nested_type_count(). - // These are returned in the order they were defined in the .proto file. - const Descriptor* nested_type(int index) const; - - // Looks up a nested type by name. Returns NULL if no such nested type - // exists. - const Descriptor* FindNestedTypeByName(const string& name) const; - - // Enum stuff ------------------------------------------------------ - - // The number of enum types in this message type. - int enum_type_count() const; - // Gets an enum type by index, where 0 <= index < enum_type_count(). - // These are returned in the order they were defined in the .proto file. - const EnumDescriptor* enum_type(int index) const; - - // Looks up an enum type by name. Returns NULL if no such enum type exists. - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - - // Looks up an enum value by name, among all enum types in this message. - // Returns NULL if no such value exists. - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - - // Extensions ------------------------------------------------------ - - // A range of field numbers which are designated for third-party - // extensions. - struct ExtensionRange { - int start; // inclusive - int end; // exclusive - }; - - // The number of extension ranges in this message type. - int extension_range_count() const; - // Gets an extension range by index, where 0 <= index < - // extension_range_count(). These are returned in the order they were defined - // in the .proto file. - const ExtensionRange* extension_range(int index) const; - - // Returns true if the number is in one of the extension ranges. - bool IsExtensionNumber(int number) const; - - // The number of extensions -- extending *other* messages -- that were - // defined nested within this message type's scope. - int extension_count() const; - // Get an extension by index, where 0 <= index < extension_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* extension(int index) const; - - // Looks up a named extension (which extends some *other* message type) - // defined within this message type's scope. - const FieldDescriptor* FindExtensionByName(const string& name) const; - - private: - // Internal version of DebugString; controls the level of indenting for - // correct depth - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const MessageOptions* options_; - int field_count_; - FieldDescriptor* fields_; - int nested_type_count_; - Descriptor* nested_types_; - int enum_type_count_; - EnumDescriptor* enum_types_; - int extension_range_count_; - ExtensionRange* extension_ranges_; - int extension_count_; - FieldDescriptor* extensions_; - - // Must be constructed using DescriptorPool. - Descriptor() {} - friend class DescriptorBuilder; - friend class EnumDescriptor; - friend class FieldDescriptor; - friend class FileDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor); -}; - -// Describes a single field of a message. To get the descriptor for a given -// field, first get the Descriptor for the message in which it is defined, -// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for -// an extension, do one of the following: -// - Get the Descriptor or FileDescriptor for its containing scope, then -// call Descriptor::FindExtensionByName() or -// FileDescriptor::FindExtensionByName(). -// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber(). -// - Given a Reflection for a message object, call -// Reflection::FindKnownExtensionByName() or -// Reflection::FindKnownExtensionByNumber(). -// Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT FieldDescriptor { - public: - // Identifies a field type. 0 is reserved for errors. The order is weird - // for historical reasons. Types 12 and up are new in proto2. - enum Type { - TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. - TYPE_FLOAT = 2, // float, exactly four bytes on the wire. - TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4, // uint64, varint on the wire. - TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. - TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. - TYPE_BOOL = 8, // bool, varint on the wire. - TYPE_STRING = 9, // UTF-8 text. - TYPE_GROUP = 10, // Tag-delimited message. Deprecated. - TYPE_MESSAGE = 11, // Length-delimited message. - - TYPE_BYTES = 12, // Arbitrary byte array. - TYPE_UINT32 = 13, // uint32, varint on the wire - TYPE_ENUM = 14, // Enum, varint on the wire - TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire - TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire - TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire - TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire - - MAX_TYPE = 18, // Constant useful for defining lookup tables - // indexed by Type. - }; - - // Specifies the C++ data type used to represent the field. There is a - // fixed mapping from Type to CppType where each Type maps to exactly one - // CppType. 0 is reserved for errors. - enum CppType { - CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 - CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 - CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 - CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 - CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE - CPPTYPE_FLOAT = 6, // TYPE_FLOAT - CPPTYPE_BOOL = 7, // TYPE_BOOL - CPPTYPE_ENUM = 8, // TYPE_ENUM - CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES - CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP - - MAX_CPPTYPE = 10, // Constant useful for defining lookup tables - // indexed by CppType. - }; - - // Identifies whether the field is optional, required, or repeated. 0 is - // reserved for errors. - enum Label { - LABEL_OPTIONAL = 1, // optional - LABEL_REQUIRED = 2, // required - LABEL_REPEATED = 3, // repeated - - MAX_LABEL = 3, // Constant useful for defining lookup tables - // indexed by Label. - }; - - // Valid field numbers are positive integers up to kMaxNumber. - static const int kMaxNumber = (1 << 29) - 1; - - // First field number reserved for the protocol buffer library implementation. - // Users may not declare fields that use reserved numbers. - static const int kFirstReservedNumber = 19000; - // Last field number reserved for the protocol buffer library implementation. - // Users may not declare fields that use reserved numbers. - static const int kLastReservedNumber = 19999; - - const string& name() const; // Name of this field within the message. - const string& full_name() const; // Fully-qualified name of the field. - const FileDescriptor* file() const;// File in which this field was defined. - bool is_extension() const; // Is this an extension field? - int number() const; // Declared tag number. - - Type type() const; // Declared type of this field. - CppType cpp_type() const; // C++ type of this field. - Label label() const; // optional/required/repeated - - bool is_required() const; // shorthand for label() == LABEL_REQUIRED - bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL - bool is_repeated() const; // shorthand for label() == LABEL_REPEATED - - // Index of this field within the message's field array, or the file or - // extension scope's extensions array. - int index() const; - - // Does this field have an explicitly-declared default value? - bool has_default_value() const; - - // Get the field default value if cpp_type() == CPPTYPE_INT32. If no - // explicit default was defined, the default is 0. - int32 default_value_int32() const; - // Get the field default value if cpp_type() == CPPTYPE_INT64. If no - // explicit default was defined, the default is 0. - int64 default_value_int64() const; - // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no - // explicit default was defined, the default is 0. - uint32 default_value_uint32() const; - // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no - // explicit default was defined, the default is 0. - uint64 default_value_uint64() const; - // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no - // explicit default was defined, the default is 0.0. - float default_value_float() const; - // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no - // explicit default was defined, the default is 0.0. - double default_value_double() const; - // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no - // explicit default was defined, the default is false. - bool default_value_bool() const; - // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no - // explicit default was defined, the default is the first value defined - // in the enum type (all enum types are required to have at least one value). - // This never returns NULL. - const EnumValueDescriptor* default_value_enum() const; - // Get the field default value if cpp_type() == CPPTYPE_STRING. If no - // explicit default was defined, the default is the empty string. - const string& default_value_string() const; - - // The Descriptor for the message of which this is a field. For extensions, - // this is the extended type. Never NULL. - const Descriptor* containing_type() const; - - // An extension may be declared within the scope of another message. If this - // field is an extension (is_extension() is true), then extension_scope() - // returns that message, or NULL if the extension was declared at global - // scope. If this is not an extension, extension_scope() is undefined (may - // assert-fail). - const Descriptor* extension_scope() const; - - // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the - // message or the group type. Otherwise, undefined. - const Descriptor* message_type() const; - // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise, - // undefined. - const EnumDescriptor* enum_type() const; - - // EXPERIMENTAL; DO NOT USE. - // If this field is a map field, experimental_map_key() is the field - // that is the key for this map. - // experimental_map_key()->containing_type() is the same as message_type(). - const FieldDescriptor* experimental_map_key() const; - - // Get the FieldOptions for this field. This includes things listed in - // square brackets after the field definition. E.g., the field: - // optional string text = 1 [ctype=CORD]; - // has the "ctype" option set. FieldOptions is actually a protocol message, - // which makes it easier to extend. - const FieldOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(FieldDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - private: - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - // formats the default value appropriately and returns it as a string. - // Must have a default value to call this. If quote_string_type is true, then - // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped. - string DefaultValueAsString(bool quote_string_type) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - int number_; - Type type_; - Label label_; - bool is_extension_; - const Descriptor* containing_type_; - const Descriptor* extension_scope_; - const Descriptor* message_type_; - const EnumDescriptor* enum_type_; - const FieldDescriptor* experimental_map_key_; - const FieldOptions* options_; - - bool has_default_value_; - union { - int32 default_value_int32_; - int64 default_value_int64_; - uint32 default_value_uint32_; - uint64 default_value_uint64_; - float default_value_float_; - double default_value_double_; - bool default_value_bool_; - - const EnumValueDescriptor* default_value_enum_; - const string* default_value_string_; - }; - - static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; - - static const char * const kTypeToName[MAX_TYPE + 1]; - - static const char * const kLabelToName[MAX_LABEL + 1]; - - // Must be constructed using DescriptorPool. - FieldDescriptor() {} - friend class DescriptorBuilder; - friend class FileDescriptor; - friend class Descriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor); -}; - -// Describes an enum type defined in a .proto file. To get the EnumDescriptor -// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool -// to construct your own descriptors. -class LIBPROTOBUF_EXPORT EnumDescriptor { - public: - // The name of this enum type in the containing scope. - const string& name() const; - - // The fully-qualified name of the enum type, scope delimited by periods. - const string& full_name() const; - - // Index of this enum within the file or containing message's enum array. - int index() const; - - // The .proto file in which this enum type was defined. Never NULL. - const FileDescriptor* file() const; - - // The number of values for this EnumDescriptor. Guaranteed to be greater - // than zero. - int value_count() const; - // Gets a value by index, where 0 <= index < value_count(). - // These are returned in the order they were defined in the .proto file. - const EnumValueDescriptor* value(int index) const; - - // Looks up a value by name. Returns NULL if no such value exists. - const EnumValueDescriptor* FindValueByName(const string& name) const; - // Looks up a value by number. Returns NULL if no such value exists. If - // multiple values have this number, the first one defined is returned. - const EnumValueDescriptor* FindValueByNumber(int number) const; - - // If this enum type is nested in a message type, this is that message type. - // Otherwise, NULL. - const Descriptor* containing_type() const; - - // Get options for this enum type. These are specified in the .proto - // file by placing lines like "option foo = 1234;" in the enum definition. - // The exact set of known options is defined by EnumOptions in - // google/protobuf/descriptor.proto. - const EnumOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(EnumDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - int value_count_; - EnumValueDescriptor* values_; - const Descriptor* containing_type_; - const EnumOptions* options_; - - // Must be constructed using DescriptorPool. - EnumDescriptor() {} - friend class DescriptorBuilder; - friend class Descriptor; - friend class EnumValueDescriptor; - friend class FileDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); -}; - -// Describes an individual enum constant of a particular type. To get the -// EnumValueDescriptor for a given enum value, first get the EnumDescriptor -// for its type, then use EnumDescriptor::FindValueByName() or -// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct -// your own descriptors. -class LIBPROTOBUF_EXPORT EnumValueDescriptor { - public: - const string& name() const; // Name of this enum constant. - int index() const; // Index within the enums's Descriptor. - int number() const; // Numeric value of this enum constant. - - // The full_name of an enum value is a sibling symbol of the enum type. - // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually - // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT - // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform - // with C++ scoping rules for enums. - const string& full_name() const; - - // The type of this value. Never NULL. - const EnumDescriptor* type() const; - - // Get options for this enum value. These are specified in the .proto - // file by adding text like "[foo = 1234]" after an enum value definition. - // The exact set of known options is defined by EnumValueOptions in - // google/protobuf/descriptor.proto. - const EnumValueOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(EnumValueDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - int number_; - const EnumDescriptor* type_; - const EnumValueOptions* options_; - - // Must be constructed using DescriptorPool. - EnumValueDescriptor() {} - friend class DescriptorBuilder; - friend class EnumDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); -}; - -// Describes an RPC service. To get the ServiceDescriptor for a service, -// call Service::GetDescriptor(). Generated service classes also have a -// static method called descriptor() which returns the type's -// ServiceDescriptor. Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT ServiceDescriptor { - public: - // The name of the service, not including its containing scope. - const string& name() const; - // The fully-qualified name of the service, scope delimited by periods. - const string& full_name() const; - // Index of this service within the file's services array. - int index() const; - - // The .proto file in which this service was defined. Never NULL. - const FileDescriptor* file() const; - - // Get options for this service type. These are specified in the .proto - // file by placing lines like "option foo = 1234;" in the service definition. - // The exact set of known options is defined by ServiceOptions in - // google/protobuf/descriptor.proto. - const ServiceOptions& options() const; - - // The number of methods this service defines. - int method_count() const; - // Gets a MethodDescriptor by index, where 0 <= index < method_count(). - // These are returned in the order they were defined in the .proto file. - const MethodDescriptor* method(int index) const; - - // Look up a MethodDescriptor by name. - const MethodDescriptor* FindMethodByName(const string& name) const; - - // See Descriptor::CopyTo(). - void CopyTo(ServiceDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - // See Descriptor::DebugString(). - void DebugString(string *contents) const; - - const string* name_; - const string* full_name_; - const FileDescriptor* file_; - const ServiceOptions* options_; - int method_count_; - MethodDescriptor* methods_; - - // Must be constructed using DescriptorPool. - ServiceDescriptor() {} - friend class DescriptorBuilder; - friend class FileDescriptor; - friend class MethodDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor); -}; - -// Describes an individual service method. To obtain a MethodDescriptor given -// a service, first get its ServiceDescriptor, then call -// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your -// own descriptors. -class LIBPROTOBUF_EXPORT MethodDescriptor { - public: - // Name of this method, not including containing scope. - const string& name() const; - // The fully-qualified name of the method, scope delimited by periods. - const string& full_name() const; - // Index within the service's Descriptor. - int index() const; - - // Gets the service to which this method belongs. Never NULL. - const ServiceDescriptor* service() const; - - // Gets the type of protocol message which this method accepts as input. - const Descriptor* input_type() const; - // Gets the type of protocol message which this message produces as output. - const Descriptor* output_type() const; - - // Get options for this method. These are specified in the .proto - // file by placing lines like "option foo = 1234;" in curly-braces after - // a method declaration. The exact set of known options is defined by - // MethodOptions in google/protobuf/descriptor.proto. - const MethodOptions& options() const; - - // See Descriptor::CopyTo(). - void CopyTo(MethodDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - // See Descriptor::DebugString(). - void DebugString(int depth, string *contents) const; - - const string* name_; - const string* full_name_; - const ServiceDescriptor* service_; - const Descriptor* input_type_; - const Descriptor* output_type_; - const MethodOptions* options_; - - // Must be constructed using DescriptorPool. - MethodDescriptor() {} - friend class DescriptorBuilder; - friend class ServiceDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor); -}; - -// Describes a whole .proto file. To get the FileDescriptor for a compiled-in -// file, get the descriptor for something defined in that file and call -// descriptor->file(). Use DescriptorPool to construct your own descriptors. -class LIBPROTOBUF_EXPORT FileDescriptor { - public: - // The filename, relative to the source tree. - // e.g. "google/protobuf/descriptor.proto" - const string& name() const; - - // The package, e.g. "google.protobuf.compiler". - const string& package() const; - - // The DescriptorPool in which this FileDescriptor and all its contents were - // allocated. Never NULL. - const DescriptorPool* pool() const; - - // The number of files imported by this one. - int dependency_count() const; - // Gets an imported file by index, where 0 <= index < dependency_count(). - // These are returned in the order they were defined in the .proto file. - const FileDescriptor* dependency(int index) const; - - // Number of top-level message types defined in this file. (This does not - // include nested types.) - int message_type_count() const; - // Gets a top-level message type, where 0 <= index < message_type_count(). - // These are returned in the order they were defined in the .proto file. - const Descriptor* message_type(int index) const; - - // Number of top-level enum types defined in this file. (This does not - // include nested types.) - int enum_type_count() const; - // Gets a top-level enum type, where 0 <= index < enum_type_count(). - // These are returned in the order they were defined in the .proto file. - const EnumDescriptor* enum_type(int index) const; - - // Number of services defined in this file. - int service_count() const; - // Gets a service, where 0 <= index < service_count(). - // These are returned in the order they were defined in the .proto file. - const ServiceDescriptor* service(int index) const; - - // Number of extensions defined at file scope. (This does not include - // extensions nested within message types.) - int extension_count() const; - // Gets an extension's descriptor, where 0 <= index < extension_count(). - // These are returned in the order they were defined in the .proto file. - const FieldDescriptor* extension(int index) const; - - // Get options for this file. These are specified in the .proto - // file by placing lines like "option foo = 1234;" at the top level, outside - // of any other definitions. The exact set of known options is defined by - // FileOptions in google/protobuf/descriptor.proto. - const FileOptions& options() const; - - // Find a top-level message type by name. Returns NULL if not found. - const Descriptor* FindMessageTypeByName(const string& name) const; - // Find a top-level enum type by name. Returns NULL if not found. - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - // Find an enum value defined in any top-level enum by name. Returns NULL if - // not found. - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - // Find a service definition by name. Returns NULL if not found. - const ServiceDescriptor* FindServiceByName(const string& name) const; - // Find a top-level extension definition by name. Returns NULL if not found. - const FieldDescriptor* FindExtensionByName(const string& name) const; - - // See Descriptor::CopyTo(). - void CopyTo(FileDescriptorProto* proto) const; - - // See Descriptor::DebugString(). - string DebugString() const; - - private: - const string* name_; - const string* package_; - const DescriptorPool* pool_; - int dependency_count_; - const FileDescriptor** dependencies_; - int message_type_count_; - Descriptor* message_types_; - int enum_type_count_; - EnumDescriptor* enum_types_; - int service_count_; - ServiceDescriptor* services_; - int extension_count_; - FieldDescriptor* extensions_; - const FileOptions* options_; - - FileDescriptor() {} - friend class DescriptorBuilder; - friend class Descriptor; - friend class FieldDescriptor; - friend class EnumDescriptor; - friend class ServiceDescriptor; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor); -}; - -// =================================================================== - -// Used to construct descriptors. -// -// Normally you won't want to build your own descriptors. Message classes -// constructed by the protocol compiler will provide them for you. However, -// if you are implementing Message on your own, or if you are writing a -// program which can operate on totally arbitrary types and needs to load -// them from some sort of database, you might need to. -// -// Since Descriptors are composed of a whole lot of cross-linked bits of -// data that would be a pain to put together manually, the -// DescriptorPool class is provided to make the process easier. It can -// take a FileDescriptorProto (defined in descriptor.proto), validate it, -// and convert it to a set of nicely cross-linked Descriptors. -// -// DescriptorPool also helps with memory management. Descriptors are -// composed of many objects containing static data and pointers to each -// other. In all likelihood, when it comes time to delete this data, -// you'll want to delete it all at once. In fact, it is not uncommon to -// have a whole pool of descriptors all cross-linked with each other which -// you wish to delete all at once. This class represents such a pool, and -// handles the memory management for you. -// -// You can also search for descriptors within a DescriptorPool by name, and -// extensions by number. -class LIBPROTOBUF_EXPORT DescriptorPool { - public: - // Create a normal, empty DescriptorPool. - DescriptorPool(); - - // Constructs a DescriptorPool that, when it can't find something among the - // descriptors already in the pool, looks for it in the given - // DescriptorDatabase. - // Notes: - // - If a DescriptorPool is constructed this way, its BuildFile*() methods - // must not be called (they will assert-fail). The only way to populate - // the pool with descriptors is to call the Find*By*() methods. - // - The Find*By*() methods may block the calling thread if the - // DescriptorDatabase blocks. This in turn means that parsing messages - // may block if they need to look up extensions. - // - The Find*By*() methods will use mutexes for thread-safety, thus making - // them slower even when they don't have to fall back to the database. - // In fact, even the Find*By*() methods of descriptor objects owned by - // this pool will be slower, since they will have to obtain locks too. - // - An ErrorCollector may optionally be given to collect validation errors - // in files loaded from the database. If not given, errors will be printed - // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this - // ErrorCollector may be called from any thread that calls one of the - // Find*By*() methods. - class ErrorCollector; - explicit DescriptorPool(DescriptorDatabase* fallback_database, - ErrorCollector* error_collector = NULL); - - ~DescriptorPool(); - - // Get a pointer to the generated pool. Generated protocol message classes - // which are compiled into the binary will allocate their descriptors in - // this pool. Do not add your own descriptors to this pool. - static const DescriptorPool* generated_pool(); - - // Find a FileDescriptor in the pool by file name. Returns NULL if not - // found. - const FileDescriptor* FindFileByName(const string& name) const; - - // Find the FileDescriptor in the pool which defines the given symbol. - // If any of the Find*ByName() methods below would succeed, then this is - // equivalent to calling that method and calling the result's file() method. - // Otherwise this returns NULL. - const FileDescriptor* FindFileContainingSymbol( - const string& symbol_name) const; - - // Looking up descriptors ------------------------------------------ - // These find descriptors by fully-qualified name. These will find both - // top-level descriptors and nested descriptors. They return NULL if not - // found. - - const Descriptor* FindMessageTypeByName(const string& name) const; - const FieldDescriptor* FindFieldByName(const string& name) const; - const FieldDescriptor* FindExtensionByName(const string& name) const; - const EnumDescriptor* FindEnumTypeByName(const string& name) const; - const EnumValueDescriptor* FindEnumValueByName(const string& name) const; - const ServiceDescriptor* FindServiceByName(const string& name) const; - const MethodDescriptor* FindMethodByName(const string& name) const; - - // Finds an extension of the given type by number. The extendee must be - // a member of this DescriptorPool or one of its underlays. - const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee, - int number) const; - - // Building descriptors -------------------------------------------- - - // When converting a FileDescriptorProto to a FileDescriptor, various - // errors might be detected in the input. The caller may handle these - // programmatically by implementing an ErrorCollector. - class LIBPROTOBUF_EXPORT ErrorCollector { - public: - inline ErrorCollector() {} - virtual ~ErrorCollector(); - - // These constants specify what exact part of the construct is broken. - // This is useful e.g. for mapping the error back to an exact location - // in a .proto file. - enum ErrorLocation { - NAME, // the symbol name, or the package name for files - NUMBER, // field or extension range number - TYPE, // field type - EXTENDEE, // field extendee - DEFAULT_VALUE, // field default value - INPUT_TYPE, // method input type - OUTPUT_TYPE, // method output type - OTHER // some other problem - }; - - // Reports an error in the FileDescriptorProto. - virtual void AddError( - const string& filename, // File name in which the error occurred. - const string& element_name, // Full name of the erroneous element. - const Message* descriptor, // Descriptor of the erroneous element. - ErrorLocation location, // One of the location constants, above. - const string& message // Human-readable error message. - ) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); - }; - - // Convert the FileDescriptorProto to real descriptors and place them in - // this DescriptorPool. All dependencies of the file must already be in - // the pool. Returns the resulting FileDescriptor, or NULL if there were - // problems with the input (e.g. the message was invalid, or dependencies - // were missing). Details about the errors are written to GOOGLE_LOG(ERROR). - const FileDescriptor* BuildFile(const FileDescriptorProto& proto); - - // Same as BuildFile() except errors are sent to the given ErrorCollector. - const FileDescriptor* BuildFileCollectingErrors( - const FileDescriptorProto& proto, - ErrorCollector* error_collector); - - // Internal stuff -------------------------------------------------- - // These methods MUST NOT be called from outside the proto2 library. - // These methods may contain hidden pitfalls and may be removed in a - // future library version. - - // DEPRECATED: Use of underlays can lead to many subtle gotchas. Instead, - // try to formulate what you want to do in terms of DescriptorDatabases. - // This constructor will be removed soon. - // - // Create a DescriptorPool which is overlaid on top of some other pool. - // If you search for a descriptor in the overlay and it is not found, the - // underlay will be searched as a backup. If the underlay has its own - // underlay, that will be searched next, and so on. This also means that - // files built in the overlay will be cross-linked with the underlay's - // descriptors if necessary. The underlay remains property of the caller; - // it must remain valid for the lifetime of the newly-constructed pool. - // - // Example: Say you want to parse a .proto file at runtime in order to use - // its type with a DynamicMessage. Say this .proto file has dependencies, - // but you know that all the dependencies will be things that are already - // compiled into the binary. For ease of use, you'd like to load the types - // right out of generated_pool() rather than have to parse redundant copies - // of all these .protos and runtime. But, you don't want to add the parsed - // types directly into generated_pool(): this is not allowed, and would be - // bad design anyway. So, instead, you could use generated_pool() as an - // underlay for a new DescriptorPool in which you add only the new file. - explicit DescriptorPool(const DescriptorPool* underlay); - - // Called by generated classes at init time. Do NOT call this in your - // own code! - const FileDescriptor* InternalBuildGeneratedFile( - const void* data, int size); - - // For internal use only: Gets a non-const pointer to the generated pool. - // This is called at static-initialization time only, so thread-safety is - // not a concern. If both an underlay and a fallback database are present, - // the fallback database takes precedence. - static DescriptorPool* internal_generated_pool(); - - // For internal use only: Changes the behavior of BuildFile() such that it - // allows the file to make reference to message types declared in other files - // which it did not officially declare as dependencies. - void InternalDontEnforceDependencies(); - - // For internal use only. - void internal_set_underlay(const DescriptorPool* underlay) { - underlay_ = underlay; - } - - private: - friend class Descriptor; - friend class FieldDescriptor; - friend class EnumDescriptor; - friend class ServiceDescriptor; - friend class FileDescriptor; - friend class DescriptorBuilder; - - // Tries to find something in the fallback database and link in the - // corresponding proto file. Returns true if successful, in which case - // the caller should search for the thing again. These are declared - // const because they are called by (semantically) const methods. - bool TryFindFileInFallbackDatabase(const string& name) const; - bool TryFindSymbolInFallbackDatabase(const string& name) const; - bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, - int field_number) const; - - // Like BuildFile() but called internally when the file has been loaded from - // fallback_database_. Declared const because it is called by (semantically) - // const methods. - const FileDescriptor* BuildFileFromDatabase( - const FileDescriptorProto& proto) const; - - // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex - // which must be locked while accessing tables_. - Mutex* mutex_; - - // See constructor. - DescriptorDatabase* fallback_database_; - ErrorCollector* default_error_collector_; - const DescriptorPool* underlay_; - - // This class contains a lot of hash maps with complicated types that - // we'd like to keep out of the header. - class Tables; - scoped_ptr<Tables> tables_; - - bool enforce_dependencies_; - - // See InternalBuildGeneratedFile(). - const void* last_internal_build_generated_file_call_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); -}; - -// inline methods ==================================================== - -// These macros makes this repetitive code more readable. -#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \ - inline TYPE CLASS::FIELD() const { return FIELD##_; } - -// Strings fields are stored as pointers but returned as const references. -#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \ - inline const string& CLASS::FIELD() const { return *FIELD##_; } - -// Arrays take an index parameter, obviously. -#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \ - inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; } - -#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ - inline const TYPE& CLASS::options() const { return *options_; } - -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) - -PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) - -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*) - -PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int) -PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range, - const Descriptor::ExtensionRange*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension, - const FieldDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key, - const FieldDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions); -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum, - const EnumValueDescriptor*) -PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) - -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, - const EnumValueDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) -PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, - const MethodDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions); - -PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name) -PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) -PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions); - -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service, - const ServiceDescriptor*) -PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, - const FieldDescriptor*) - -#undef PROTOBUF_DEFINE_ACCESSOR -#undef PROTOBUF_DEFINE_STRING_ACCESSOR -#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR - -// A few accessors differ from the macros... - -inline bool FieldDescriptor::is_required() const { - return label() == LABEL_REQUIRED; -} - -inline bool FieldDescriptor::is_optional() const { - return label() == LABEL_OPTIONAL; -} - -inline bool FieldDescriptor::is_repeated() const { - return label() == LABEL_REPEATED; -} - -// To save space, index() is computed by looking at the descriptor's position -// in the parent's array of children. -inline int FieldDescriptor::index() const { - if (!is_extension_) { - return this - containing_type_->fields_; - } else if (extension_scope_ != NULL) { - return this - extension_scope_->extensions_; - } else { - return this - file_->extensions_; - } -} - -inline int Descriptor::index() const { - if (containing_type_ == NULL) { - return this - file_->message_types_; - } else { - return this - containing_type_->nested_types_; - } -} - -inline int EnumDescriptor::index() const { - if (containing_type_ == NULL) { - return this - file_->enum_types_; - } else { - return this - containing_type_->enum_types_; - } -} - -inline int EnumValueDescriptor::index() const { - return this - type_->values_; -} - -inline int ServiceDescriptor::index() const { - return this - file_->services_; -} - -inline int MethodDescriptor::index() const { - return this - service_->methods_; -} - -inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { - return kTypeToCppTypeMap[type_]; -} - -inline const FileDescriptor* FileDescriptor::dependency(int index) const { - return dependencies_[index]; -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__ diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc deleted file mode 100644 index 0189c76a..00000000 --- a/src/google/protobuf/descriptor.pb.cc +++ /dev/null @@ -1,4298 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -#include "google/protobuf/descriptor.pb.h" -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/wire_format_inl.h> - -namespace google { -namespace protobuf { - -namespace { - -const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileDescriptorSet_reflection_ = NULL; -const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - DescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - DescriptorProto_ExtensionRange_reflection_ = NULL; -const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FieldDescriptorProto_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL; -const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumValueDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - ServiceDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MethodDescriptorProto_reflection_ = NULL; -const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FileOptions_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL; -const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MessageOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - FieldOptions_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL; -const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - EnumValueOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - ServiceOptions_reflection_ = NULL; -const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - MethodOptions_reflection_ = NULL; - -} // namespace - - -void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto() { - static bool already_here = false; - if (already_here) return; - already_here = true; - GOOGLE_PROTOBUF_VERIFY_VERSION; - ::google::protobuf::DescriptorPool* pool = - ::google::protobuf::DescriptorPool::internal_generated_pool(); - - const ::google::protobuf::FileDescriptor* file = pool->InternalBuildGeneratedFile( - "\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" - "(\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" - "gle.protobuf.EnumDescriptorProto\0228\n\007serv" - "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\"\210\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" - "J\n\014optimize_for\030\t \001(\0162).google.protobuf." - "FileOptions.OptimizeMode:\tCODE_SIZE\022\031\n\020c" - "sharp_namespace\030\350\007 \001(\t\022\036\n\025csharp_file_cl" - "assname\030\351\007 \001(\t\022%\n\025csharp_multiple_files\030" - "\352\007 \001(\010:\005false\022#\n\023csharp_nest_classes\030\353\007 " - "\001(\010:\005false\022$\n\025csharp_public_classes\030\354\007 \001" - "(\010:\004true\"(\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tC" - "ODE_SIZE\020\002\"8\n\016MessageOptions\022&\n\027message_" - "set_wire_format\030\001 \001(\010:\005false\"\205\001\n\014FieldOp" - "tions\0222\n\005ctype\030\001 \001(\0162#.google.protobuf.F" - "ieldOptions.CType\022\034\n\024experimental_map_ke" - "y\030\t \001(\t\"#\n\005CType\022\010\n\004CORD\020\001\022\020\n\014STRING_PIE" - "CE\020\002\"\r\n\013EnumOptions\"\022\n\020EnumValueOptions\"" - "\020\n\016ServiceOptions\"\017\n\rMethodOptionsBr\n\023co" - "m.google.protobufB\020DescriptorProtosH\001\302>\'" - "Google.ProtocolBuffers.DescriptorProtos\312" - ">\023DescriptorProtoFile\320>\000\330>\000\340>\001", 2870); - FileDescriptorSet_descriptor_ = file->message_type(0); - FileDescriptorSet_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileDescriptorSet_descriptor_, - &FileDescriptorSet::default_instance(), - FileDescriptorSet::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance()); - FileDescriptorProto_descriptor_ = file->message_type(1); - FileDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileDescriptorProto_descriptor_, - &FileDescriptorProto::default_instance(), - FileDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance()); - DescriptorProto_descriptor_ = file->message_type(2); - DescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - DescriptorProto_descriptor_, - &DescriptorProto::default_instance(), - DescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0); - DescriptorProto_ExtensionRange_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - DescriptorProto_ExtensionRange_descriptor_, - &DescriptorProto_ExtensionRange::default_instance(), - DescriptorProto_ExtensionRange::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - DescriptorProto_descriptor_, &DescriptorProto::default_instance()); - FieldDescriptorProto_descriptor_ = file->message_type(3); - FieldDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FieldDescriptorProto_descriptor_, - &FieldDescriptorProto::default_instance(), - FieldDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0); - FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance()); - EnumDescriptorProto_descriptor_ = file->message_type(4); - EnumDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumDescriptorProto_descriptor_, - &EnumDescriptorProto::default_instance(), - EnumDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance()); - EnumValueDescriptorProto_descriptor_ = file->message_type(5); - EnumValueDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumValueDescriptorProto_descriptor_, - &EnumValueDescriptorProto::default_instance(), - EnumValueDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance()); - ServiceDescriptorProto_descriptor_ = file->message_type(6); - ServiceDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - ServiceDescriptorProto_descriptor_, - &ServiceDescriptorProto::default_instance(), - ServiceDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance()); - MethodDescriptorProto_descriptor_ = file->message_type(7); - MethodDescriptorProto_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MethodDescriptorProto_descriptor_, - &MethodDescriptorProto::default_instance(), - MethodDescriptorProto::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance()); - FileOptions_descriptor_ = file->message_type(8); - FileOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FileOptions_descriptor_, - &FileOptions::default_instance(), - FileOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FileOptions_descriptor_, &FileOptions::default_instance()); - MessageOptions_descriptor_ = file->message_type(9); - MessageOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MessageOptions_descriptor_, - &MessageOptions::default_instance(), - MessageOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MessageOptions_descriptor_, &MessageOptions::default_instance()); - FieldOptions_descriptor_ = file->message_type(10); - FieldOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - FieldOptions_descriptor_, - &FieldOptions::default_instance(), - FieldOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - FieldOptions_descriptor_, &FieldOptions::default_instance()); - EnumOptions_descriptor_ = file->message_type(11); - EnumOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumOptions_descriptor_, - &EnumOptions::default_instance(), - EnumOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumOptions_descriptor_, &EnumOptions::default_instance()); - EnumValueOptions_descriptor_ = file->message_type(12); - EnumValueOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - EnumValueOptions_descriptor_, - &EnumValueOptions::default_instance(), - EnumValueOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - EnumValueOptions_descriptor_, &EnumValueOptions::default_instance()); - ServiceOptions_descriptor_ = file->message_type(13); - ServiceOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - ServiceOptions_descriptor_, - &ServiceOptions::default_instance(), - ServiceOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - ServiceOptions_descriptor_, &ServiceOptions::default_instance()); - MethodOptions_descriptor_ = file->message_type(14); - MethodOptions_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - MethodOptions_descriptor_, - &MethodOptions::default_instance(), - MethodOptions::_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - MethodOptions_descriptor_, &MethodOptions::default_instance()); -} - -// Force BuildDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { - StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() { - protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - } -} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_; - - -// =================================================================== - -const FileDescriptorSet FileDescriptorSet::default_instance_; - - -const int FileDescriptorSet::_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_), -}; - -FileDescriptorSet::FileDescriptorSet() - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -FileDescriptorSet::~FileDescriptorSet() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { - if (FileDescriptorSet_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileDescriptorSet_descriptor_; -} - -FileDescriptorSet* FileDescriptorSet::New() const { - return new FileDescriptorSet; -} - -void FileDescriptorSet::Clear() { - file_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileDescriptorSet::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::WireFormat::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.FileDescriptorProto file = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_file: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_file())); - if (input->ExpectTag(10)) goto parse_file; - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool FileDescriptorSet::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // repeated .google.protobuf.FileDescriptorProto file = 1; - for (int i = 0; i < file_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(1, this->file(i), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int FileDescriptorSet::ByteSize() const { - int total_size = 0; - - // repeated .google.protobuf.FileDescriptorProto file = 1; - total_size += 1 * file_size(); - for (int i = 0; i < file_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->file(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileDescriptorSet* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { - GOOGLE_CHECK_NE(&from, this); - file_.MergeFrom(from.file_); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileDescriptorSet::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* FileDescriptorSet::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileDescriptorSet::GetReflection() const { - if (FileDescriptorSet_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileDescriptorSet_reflection_; -} - -// =================================================================== - -const FileDescriptorProto FileDescriptorProto::default_instance_; - -const ::std::string FileDescriptorProto::_default_name_; -const ::std::string FileDescriptorProto::_default_package_; - - - - - - -const int FileDescriptorProto::_offsets_[8] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_), -}; - -FileDescriptorProto::FileDescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - package_(const_cast< ::std::string*>(&_default_package_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); - } -} - -FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - package_(const_cast< ::std::string*>(&_default_package_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -FileDescriptorProto::~FileDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (package_ != &_default_package_) { - delete package_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { - if (FileDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileDescriptorProto_descriptor_; -} - -FileDescriptorProto* FileDescriptorProto::New() const { - return new FileDescriptorProto; -} - -void FileDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(1)) { - if (package_ != &_default_package_) { - package_->clear(); - } - } - if (_has_bit(7)) { - if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); - } - } - dependency_.Clear(); - message_type_.Clear(); - enum_type_.Clear(); - service_.Clear(); - extension_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_package; - break; - } - - // optional string package = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_package: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_package())); - if (input->ExpectTag(26)) goto parse_dependency; - break; - } - - // repeated string dependency = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_dependency: - DO_(::google::protobuf::internal::WireFormat::ReadString( - input, add_dependency())); - if (input->ExpectTag(26)) goto parse_dependency; - if (input->ExpectTag(34)) goto parse_message_type; - break; - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_message_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_message_type())); - if (input->ExpectTag(34)) goto parse_message_type; - if (input->ExpectTag(42)) goto parse_enum_type; - break; - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_enum_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_enum_type())); - if (input->ExpectTag(42)) goto parse_enum_type; - if (input->ExpectTag(50)) goto parse_service; - break; - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_service: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_service())); - if (input->ExpectTag(50)) goto parse_service; - if (input->ExpectTag(58)) goto parse_extension; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_extension: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension())); - if (input->ExpectTag(58)) goto parse_extension; - if (input->ExpectTag(66)) goto parse_options; - break; - } - - // optional .google.protobuf.FileOptions options = 8; - case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool FileDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // optional string package = 2; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->package(), output)); - } - - // repeated string dependency = 3; - for (int i = 0; i < dependency_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteString(3, this->dependency(i), output)); - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - for (int i = 0; i < message_type_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->message_type(i), output)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - for (int i = 0; i < enum_type_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->enum_type(i), output)); - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - for (int i = 0; i < service_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->service(i), output)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - for (int i = 0; i < extension_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->extension(i), output)); - } - - // optional .google.protobuf.FileOptions options = 8; - if (_has_bit(7)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int FileDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional string package = 2; - if (has_package()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->package()); - } - - // optional .google.protobuf.FileOptions options = 8; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated string dependency = 3; - total_size += 1 * dependency_size(); - for (int i = 0; i < dependency_size(); i++) { - total_size += ::google::protobuf::internal::WireFormat::StringSize( - this->dependency(i)); - } - - // repeated .google.protobuf.DescriptorProto message_type = 4; - total_size += 1 * message_type_size(); - for (int i = 0; i < message_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->message_type(i)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - total_size += 1 * enum_type_size(); - for (int i = 0; i < enum_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->enum_type(i)); - } - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - total_size += 1 * service_size(); - for (int i = 0; i < service_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->service(i)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - total_size += 1 * extension_size(); - for (int i = 0; i < extension_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->extension(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - dependency_.MergeFrom(from.dependency_); - message_type_.MergeFrom(from.message_type_); - enum_type_.MergeFrom(from.enum_type_); - service_.MergeFrom(from.service_); - extension_.MergeFrom(from.extension_); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_package(from.package()); - } - if (from._has_bit(7)) { - mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* FileDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileDescriptorProto::GetReflection() const { - if (FileDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileDescriptorProto_reflection_; -} - -// =================================================================== - -const DescriptorProto_ExtensionRange DescriptorProto_ExtensionRange::default_instance_; - - - -const int DescriptorProto_ExtensionRange::_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_), -}; - -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() - : _cached_size_(0), - start_(0), - end_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) - : _cached_size_(0), - start_(0), - end_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() { - if (DescriptorProto_ExtensionRange_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return DescriptorProto_ExtensionRange_descriptor_; -} - -DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const { - return new DescriptorProto_ExtensionRange; -} - -void DescriptorProto_ExtensionRange::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - start_ = 0; - end_ = 0; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool DescriptorProto_ExtensionRange::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::WireFormat::GetTagFieldNumber(tag)) { - // optional int32 start = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadInt32( - input, &start_)); - _set_bit(0); - if (input->ExpectTag(16)) goto parse_end; - break; - } - - // optional int32 end = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_end: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( - input, &end_)); - _set_bit(1); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool DescriptorProto_ExtensionRange::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional int32 start = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteInt32(1, this->start(), output)); - } - - // optional int32 end = 2; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteInt32(2, this->end(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int DescriptorProto_ExtensionRange::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional int32 start = 1; - if (has_start()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( - this->start()); - } - - // optional int32 end = 2; - if (has_end()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( - this->end()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const DescriptorProto_ExtensionRange* source = - ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_start(from.start()); - } - if (from._has_bit(1)) { - set_end(from.end()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DescriptorProto_ExtensionRange::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* DescriptorProto_ExtensionRange::GetReflection() const { - if (DescriptorProto_ExtensionRange_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return DescriptorProto_ExtensionRange_reflection_; -} - -// ------------------------------------------------------------------- - -const DescriptorProto DescriptorProto::default_instance_; - -const ::std::string DescriptorProto::_default_name_; - - - - - - -const int DescriptorProto::_offsets_[7] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_), -}; - -DescriptorProto::DescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance()); - } -} - -DescriptorProto::DescriptorProto(const DescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -DescriptorProto::~DescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { - if (DescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return DescriptorProto_descriptor_; -} - -DescriptorProto* DescriptorProto::New() const { - return new DescriptorProto; -} - -void DescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(6)) { - if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); - } - } - field_.Clear(); - extension_.Clear(); - nested_type_.Clear(); - enum_type_.Clear(); - extension_range_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool DescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_field; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_field: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_field())); - if (input->ExpectTag(18)) goto parse_field; - if (input->ExpectTag(26)) goto parse_nested_type; - break; - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_nested_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_nested_type())); - if (input->ExpectTag(26)) goto parse_nested_type; - if (input->ExpectTag(34)) goto parse_enum_type; - break; - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_enum_type: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_enum_type())); - if (input->ExpectTag(34)) goto parse_enum_type; - if (input->ExpectTag(42)) goto parse_extension_range; - break; - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_extension_range: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension_range())); - if (input->ExpectTag(42)) goto parse_extension_range; - if (input->ExpectTag(50)) goto parse_extension; - break; - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_extension: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_extension())); - if (input->ExpectTag(50)) goto parse_extension; - if (input->ExpectTag(58)) goto parse_options; - break; - } - - // optional .google.protobuf.MessageOptions options = 7; - case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool DescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - for (int i = 0; i < field_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->field(i), output)); - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - for (int i = 0; i < nested_type_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->nested_type(i), output)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - for (int i = 0; i < enum_type_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->enum_type(i), output)); - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - for (int i = 0; i < extension_range_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(5, this->extension_range(i), output)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - for (int i = 0; i < extension_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(6, this->extension(i), output)); - } - - // optional .google.protobuf.MessageOptions options = 7; - if (_has_bit(6)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(7, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int DescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional .google.protobuf.MessageOptions options = 7; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.FieldDescriptorProto field = 2; - total_size += 1 * field_size(); - for (int i = 0; i < field_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->field(i)); - } - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - total_size += 1 * extension_size(); - for (int i = 0; i < extension_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->extension(i)); - } - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - total_size += 1 * nested_type_size(); - for (int i = 0; i < nested_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->nested_type(i)); - } - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - total_size += 1 * enum_type_size(); - for (int i = 0; i < enum_type_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->enum_type(i)); - } - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - total_size += 1 * extension_range_size(); - for (int i = 0; i < extension_range_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->extension_range(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const DescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void DescriptorProto::MergeFrom(const DescriptorProto& from) { - GOOGLE_CHECK_NE(&from, this); - field_.MergeFrom(from.field_); - extension_.MergeFrom(from.extension_); - nested_type_.MergeFrom(from.nested_type_); - 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)) { - set_name(from.name()); - } - if (from._has_bit(6)) { - mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void DescriptorProto::CopyFrom(const DescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool DescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* DescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* DescriptorProto::GetReflection() const { - if (DescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return DescriptorProto_reflection_; -} - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { - if (FieldDescriptorProto_Type_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldDescriptorProto_Type_descriptor_; -} -bool FieldDescriptorProto_Type_IsValid(int value) { - switch(value) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32; -const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64; -const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN; -const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX; -#endif // _MSC_VER -const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() { - if (FieldDescriptorProto_Label_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldDescriptorProto_Label_descriptor_; -} -bool FieldDescriptorProto_Label_IsValid(int value) { - switch(value) { - case 1: - case 2: - case 3: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL; -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED; -const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED; -const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; -const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; -#endif // _MSC_VER -const FieldDescriptorProto FieldDescriptorProto::default_instance_; - -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_; - -const int FieldDescriptorProto::_offsets_[8] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_), -}; - -FieldDescriptorProto::FieldDescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - 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_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance()); - } -} - -FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - 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_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -FieldDescriptorProto::~FieldDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (type_name_ != &_default_type_name_) { - delete type_name_; - } - if (extendee_ != &_default_extendee_) { - delete extendee_; - } - if (default_value_ != &_default_default_value_) { - delete default_value_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { - if (FieldDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldDescriptorProto_descriptor_; -} - -FieldDescriptorProto* FieldDescriptorProto::New() const { - return new FieldDescriptorProto; -} - -void FieldDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - number_ = 0; - label_ = 1; - type_ = 1; - if (_has_bit(4)) { - if (type_name_ != &_default_type_name_) { - type_name_->clear(); - } - } - if (_has_bit(5)) { - if (extendee_ != &_default_extendee_) { - extendee_->clear(); - } - } - if (_has_bit(6)) { - if (default_value_ != &_default_default_value_) { - default_value_->clear(); - } - } - if (_has_bit(7)) { - if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FieldDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_extendee; - break; - } - - // optional string extendee = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_extendee: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_extendee())); - if (input->ExpectTag(24)) goto parse_number; - break; - } - - // optional int32 number = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_number: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( - input, &number_)); - _set_bit(1); - if (input->ExpectTag(32)) goto parse_label; - break; - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_label: - int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); - if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) { - set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value)); - } else { - mutable_unknown_fields()->AddField(4)->add_varint(value); - } - if (input->ExpectTag(40)) goto parse_type; - break; - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - case 5: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_type: - int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); - if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) { - set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value)); - } else { - mutable_unknown_fields()->AddField(5)->add_varint(value); - } - if (input->ExpectTag(50)) goto parse_type_name; - break; - } - - // optional string type_name = 6; - case 6: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_type_name: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_type_name())); - if (input->ExpectTag(58)) goto parse_default_value; - break; - } - - // optional string default_value = 7; - case 7: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_default_value: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_default_value())); - if (input->ExpectTag(66)) goto parse_options; - break; - } - - // optional .google.protobuf.FieldOptions options = 8; - case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool FieldDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // optional string extendee = 2; - if (_has_bit(5)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->extendee(), output)); - } - - // optional int32 number = 3; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteInt32(3, this->number(), output)); - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteEnum(4, this->label(), output)); - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (_has_bit(3)) { - DO_(::google::protobuf::internal::WireFormat::WriteEnum(5, this->type(), output)); - } - - // optional string type_name = 6; - if (_has_bit(4)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(6, this->type_name(), output)); - } - - // optional string default_value = 7; - if (_has_bit(6)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(7, this->default_value(), output)); - } - - // optional .google.protobuf.FieldOptions options = 8; - if (_has_bit(7)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(8, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int FieldDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional int32 number = 3; - if (has_number()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( - this->number()); - } - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (has_label()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->label()); - } - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (has_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->type()); - } - - // optional string type_name = 6; - if (has_type_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->type_name()); - } - - // optional string extendee = 2; - if (has_extendee()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->extendee()); - } - - // optional string default_value = 7; - if (has_default_value()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->default_value()); - } - - // optional .google.protobuf.FieldOptions options = 8; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FieldDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_number(from.number()); - } - if (from._has_bit(2)) { - set_label(from.label()); - } - if (from._has_bit(3)) { - set_type(from.type()); - } - if (from._has_bit(4)) { - set_type_name(from.type_name()); - } - if (from._has_bit(5)) { - set_extendee(from.extendee()); - } - if (from._has_bit(6)) { - set_default_value(from.default_value()); - } - if (from._has_bit(7)) { - mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FieldDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* FieldDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FieldDescriptorProto::GetReflection() const { - if (FieldDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldDescriptorProto_reflection_; -} - -// =================================================================== - -const EnumDescriptorProto EnumDescriptorProto::default_instance_; - -const ::std::string EnumDescriptorProto::_default_name_; - - -const int EnumDescriptorProto::_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_), -}; - -EnumDescriptorProto::EnumDescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance()); - } -} - -EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -EnumDescriptorProto::~EnumDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { - if (EnumDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumDescriptorProto_descriptor_; -} - -EnumDescriptorProto* EnumDescriptorProto::New() const { - return new EnumDescriptorProto; -} - -void EnumDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); - } - } - value_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_value; - break; - } - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_value: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_value())); - if (input->ExpectTag(18)) goto parse_value; - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.EnumOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool EnumDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - for (int i = 0; i < value_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->value(i), output)); - } - - // optional .google.protobuf.EnumOptions options = 3; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int EnumDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional .google.protobuf.EnumOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - total_size += 1 * value_size(); - for (int i = 0; i < value_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->value(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_name(from.name()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* EnumDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumDescriptorProto::GetReflection() const { - if (EnumDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumDescriptorProto_reflection_; -} - -// =================================================================== - -const EnumValueDescriptorProto EnumValueDescriptorProto::default_instance_; - -const ::std::string EnumValueDescriptorProto::_default_name_; - - -const int EnumValueDescriptorProto::_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_), -}; - -EnumValueDescriptorProto::EnumValueDescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - number_(0), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance()); - } -} - -EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - number_(0), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -EnumValueDescriptorProto::~EnumValueDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { - if (EnumValueDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumValueDescriptorProto_descriptor_; -} - -EnumValueDescriptorProto* EnumValueDescriptorProto::New() const { - return new EnumValueDescriptorProto; -} - -void EnumValueDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - number_ = 0; - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumValueDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(16)) goto parse_number; - break; - } - - // optional int32 number = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_number: - DO_(::google::protobuf::internal::WireFormat::ReadInt32( - input, &number_)); - _set_bit(1); - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.EnumValueOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool EnumValueDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // optional int32 number = 2; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteInt32(2, this->number(), output)); - } - - // optional .google.protobuf.EnumValueOptions options = 3; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int EnumValueDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional int32 number = 2; - if (has_number()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::Int32Size( - this->number()); - } - - // optional .google.protobuf.EnumValueOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const EnumValueDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_number(from.number()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumValueDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* EnumValueDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumValueDescriptorProto::GetReflection() const { - if (EnumValueDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumValueDescriptorProto_reflection_; -} - -// =================================================================== - -const ServiceDescriptorProto ServiceDescriptorProto::default_instance_; - -const ::std::string ServiceDescriptorProto::_default_name_; - - -const int ServiceDescriptorProto::_offsets_[3] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_), -}; - -ServiceDescriptorProto::ServiceDescriptorProto() - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance()); - } -} - -ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) - : _cached_size_(0), - name_(const_cast< ::std::string*>(&_default_name_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -ServiceDescriptorProto::~ServiceDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { - if (ServiceDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return ServiceDescriptorProto_descriptor_; -} - -ServiceDescriptorProto* ServiceDescriptorProto::New() const { - return new ServiceDescriptorProto; -} - -void ServiceDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(2)) { - if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); - } - } - method_.Clear(); - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool ServiceDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_method; - break; - } - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_method: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, add_method())); - if (input->ExpectTag(18)) goto parse_method; - if (input->ExpectTag(26)) goto parse_options; - break; - } - - // optional .google.protobuf.ServiceOptions options = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool ServiceDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - for (int i = 0; i < method_.size(); i++) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(2, this->method(i), output)); - } - - // optional .google.protobuf.ServiceOptions options = 3; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(3, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int ServiceDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional .google.protobuf.ServiceOptions options = 3; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - // repeated .google.protobuf.MethodDescriptorProto method = 2; - total_size += 1 * method_size(); - for (int i = 0; i < method_size(); i++) { - total_size += - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->method(i)); - } - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const ServiceDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_name(from.name()); - } - if (from._has_bit(2)) { - mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool ServiceDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* ServiceDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* ServiceDescriptorProto::GetReflection() const { - if (ServiceDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return ServiceDescriptorProto_reflection_; -} - -// =================================================================== - -const MethodDescriptorProto MethodDescriptorProto::default_instance_; - -const ::std::string MethodDescriptorProto::_default_name_; -const ::std::string MethodDescriptorProto::_default_input_type_; -const ::std::string MethodDescriptorProto::_default_output_type_; - -const int MethodDescriptorProto::_offsets_[4] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_), -}; - -MethodDescriptorProto::MethodDescriptorProto() - : _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_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance()); - } -} - -MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) - : _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_)), - options_(NULL) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -MethodDescriptorProto::~MethodDescriptorProto() { - if (name_ != &_default_name_) { - delete name_; - } - if (input_type_ != &_default_input_type_) { - delete input_type_; - } - if (output_type_ != &_default_output_type_) { - delete output_type_; - } - if (this != &default_instance_) { - delete options_; - } -} - -const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { - if (MethodDescriptorProto_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MethodDescriptorProto_descriptor_; -} - -MethodDescriptorProto* MethodDescriptorProto::New() const { - return new MethodDescriptorProto; -} - -void MethodDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { - name_->clear(); - } - } - if (_has_bit(1)) { - if (input_type_ != &_default_input_type_) { - input_type_->clear(); - } - } - if (_has_bit(2)) { - if (output_type_ != &_default_output_type_) { - output_type_->clear(); - } - } - if (_has_bit(3)) { - if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MethodDescriptorProto::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_name())); - if (input->ExpectTag(18)) goto parse_input_type; - break; - } - - // optional string input_type = 2; - case 2: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_input_type: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_input_type())); - if (input->ExpectTag(26)) goto parse_output_type; - break; - } - - // optional string output_type = 3; - case 3: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_output_type: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_output_type())); - if (input->ExpectTag(34)) goto parse_options; - break; - } - - // optional .google.protobuf.MethodOptions options = 4; - case 4: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_options: - DO_(::google::protobuf::internal::WireFormat::ReadMessageNoVirtual( - input, mutable_options())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool MethodDescriptorProto::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string name = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->name(), output)); - } - - // optional string input_type = 2; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(2, this->input_type(), output)); - } - - // optional string output_type = 3; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(3, this->output_type(), output)); - } - - // optional .google.protobuf.MethodOptions options = 4; - if (_has_bit(3)) { - DO_(::google::protobuf::internal::WireFormat::WriteMessageNoVirtual(4, this->options(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int MethodDescriptorProto::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->name()); - } - - // optional string input_type = 2; - if (has_input_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->input_type()); - } - - // optional string output_type = 3; - if (has_output_type()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->output_type()); - } - - // optional .google.protobuf.MethodOptions options = 4; - if (has_options()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::MessageSizeNoVirtual( - this->options()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MethodDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -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)) { - set_name(from.name()); - } - if (from._has_bit(1)) { - set_input_type(from.input_type()); - } - if (from._has_bit(2)) { - set_output_type(from.output_type()); - } - if (from._has_bit(3)) { - mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MethodDescriptorProto::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* MethodDescriptorProto::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MethodDescriptorProto::GetReflection() const { - if (MethodDescriptorProto_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MethodDescriptorProto_reflection_; -} - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() { - if (FileOptions_OptimizeMode_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileOptions_OptimizeMode_descriptor_; -} -bool FileOptions_OptimizeMode_IsValid(int value) { - switch(value) { - case 1: - case 2: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FileOptions_OptimizeMode FileOptions::SPEED; -const FileOptions_OptimizeMode FileOptions::CODE_SIZE; -const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; -const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; -#endif // _MSC_VER -const FileOptions FileOptions::default_instance_; - -const ::std::string FileOptions::_default_java_package_; -const ::std::string FileOptions::_default_java_outer_classname_; - - -const ::std::string FileOptions::_default_csharp_namespace_; -const ::std::string FileOptions::_default_csharp_file_classname_; - - - -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, optimize_for_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_file_classname_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_multiple_files_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_nest_classes_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_public_classes_), -}; - -FileOptions::FileOptions() - : _cached_size_(0), - java_package_(const_cast< ::std::string*>(&_default_java_package_)), - java_outer_classname_(const_cast< ::std::string*>(&_default_java_outer_classname_)), - java_multiple_files_(false), - optimize_for_(2), - csharp_namespace_(const_cast< ::std::string*>(&_default_csharp_namespace_)), - csharp_file_classname_(const_cast< ::std::string*>(&_default_csharp_file_classname_)), - csharp_multiple_files_(false), - csharp_nest_classes_(false), - csharp_public_classes_(true) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -FileOptions::FileOptions(const FileOptions& from) - : _cached_size_(0), - java_package_(const_cast< ::std::string*>(&_default_java_package_)), - java_outer_classname_(const_cast< ::std::string*>(&_default_java_outer_classname_)), - java_multiple_files_(false), - optimize_for_(2), - csharp_namespace_(const_cast< ::std::string*>(&_default_csharp_namespace_)), - csharp_file_classname_(const_cast< ::std::string*>(&_default_csharp_file_classname_)), - csharp_multiple_files_(false), - csharp_nest_classes_(false), - csharp_public_classes_(true) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -FileOptions::~FileOptions() { - if (java_package_ != &_default_java_package_) { - delete java_package_; - } - if (java_outer_classname_ != &_default_java_outer_classname_) { - delete java_outer_classname_; - } - if (csharp_namespace_ != &_default_csharp_namespace_) { - delete csharp_namespace_; - } - if (csharp_file_classname_ != &_default_csharp_file_classname_) { - delete csharp_file_classname_; - } - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* FileOptions::descriptor() { - if (FileOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileOptions_descriptor_; -} - -FileOptions* FileOptions::New() const { - return new FileOptions; -} - -void FileOptions::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (java_package_ != &_default_java_package_) { - java_package_->clear(); - } - } - if (_has_bit(1)) { - if (java_outer_classname_ != &_default_java_outer_classname_) { - java_outer_classname_->clear(); - } - } - java_multiple_files_ = false; - optimize_for_ = 2; - if (_has_bit(4)) { - if (csharp_namespace_ != &_default_csharp_namespace_) { - csharp_namespace_->clear(); - } - } - if (_has_bit(5)) { - if (csharp_file_classname_ != &_default_csharp_file_classname_) { - csharp_file_classname_->clear(); - } - } - csharp_multiple_files_ = false; - csharp_nest_classes_ = false; - } - if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { - csharp_public_classes_ = true; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FileOptions::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::WireFormat::GetTagFieldNumber(tag)) { - // optional string java_package = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_package())); - if (input->ExpectTag(66)) goto parse_java_outer_classname; - break; - } - - // optional string java_outer_classname = 8; - case 8: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_java_outer_classname: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_java_outer_classname())); - if (input->ExpectTag(72)) goto parse_optimize_for; - break; - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE]; - case 9: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_optimize_for: - int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); - if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) { - set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value)); - } else { - mutable_unknown_fields()->AddField(9)->add_varint(value); - } - if (input->ExpectTag(80)) goto parse_java_multiple_files; - break; - } - - // optional bool java_multiple_files = 10 [default = false]; - case 10: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_java_multiple_files: - DO_(::google::protobuf::internal::WireFormat::ReadBool( - input, &java_multiple_files_)); - _set_bit(2); - if (input->ExpectTag(8002)) goto parse_csharp_namespace; - break; - } - - // optional string csharp_namespace = 1000; - case 1000: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_csharp_namespace: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_csharp_namespace())); - if (input->ExpectTag(8010)) goto parse_csharp_file_classname; - break; - } - - // optional string csharp_file_classname = 1001; - case 1001: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_csharp_file_classname: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_csharp_file_classname())); - if (input->ExpectTag(8016)) goto parse_csharp_multiple_files; - break; - } - - // optional bool csharp_multiple_files = 1002 [default = false]; - case 1002: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_csharp_multiple_files: - DO_(::google::protobuf::internal::WireFormat::ReadBool( - input, &csharp_multiple_files_)); - _set_bit(6); - if (input->ExpectTag(8024)) goto parse_csharp_nest_classes; - break; - } - - // optional bool csharp_nest_classes = 1003 [default = false]; - case 1003: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_csharp_nest_classes: - DO_(::google::protobuf::internal::WireFormat::ReadBool( - input, &csharp_nest_classes_)); - _set_bit(7); - if (input->ExpectTag(8032)) goto parse_csharp_public_classes; - break; - } - - // optional bool csharp_public_classes = 1004 [default = true]; - case 1004: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - parse_csharp_public_classes: - DO_(::google::protobuf::internal::WireFormat::ReadBool( - input, &csharp_public_classes_)); - _set_bit(8); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool FileOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional string java_package = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1, this->java_package(), output)); - } - - // optional string java_outer_classname = 8; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(8, this->java_outer_classname(), output)); - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE]; - if (_has_bit(3)) { - DO_(::google::protobuf::internal::WireFormat::WriteEnum(9, this->optimize_for(), output)); - } - - // optional bool java_multiple_files = 10 [default = false]; - if (_has_bit(2)) { - DO_(::google::protobuf::internal::WireFormat::WriteBool(10, this->java_multiple_files(), output)); - } - - // optional string csharp_namespace = 1000; - if (_has_bit(4)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1000, this->csharp_namespace(), output)); - } - - // optional string csharp_file_classname = 1001; - if (_has_bit(5)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(1001, this->csharp_file_classname(), output)); - } - - // optional bool csharp_multiple_files = 1002 [default = false]; - if (_has_bit(6)) { - DO_(::google::protobuf::internal::WireFormat::WriteBool(1002, this->csharp_multiple_files(), output)); - } - - // optional bool csharp_nest_classes = 1003 [default = false]; - if (_has_bit(7)) { - DO_(::google::protobuf::internal::WireFormat::WriteBool(1003, this->csharp_nest_classes(), output)); - } - - // optional bool csharp_public_classes = 1004 [default = true]; - if (_has_bit(8)) { - DO_(::google::protobuf::internal::WireFormat::WriteBool(1004, this->csharp_public_classes(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int FileOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional string java_package = 1; - if (has_java_package()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->java_package()); - } - - // optional string java_outer_classname = 8; - if (has_java_outer_classname()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->java_outer_classname()); - } - - // optional bool java_multiple_files = 10 [default = false]; - if (has_java_multiple_files()) { - total_size += 1 + 1; - } - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE]; - if (has_optimize_for()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->optimize_for()); - } - - // optional string csharp_namespace = 1000; - if (has_csharp_namespace()) { - total_size += 2 + - ::google::protobuf::internal::WireFormat::StringSize(this->csharp_namespace()); - } - - // optional string csharp_file_classname = 1001; - if (has_csharp_file_classname()) { - total_size += 2 + - ::google::protobuf::internal::WireFormat::StringSize(this->csharp_file_classname()); - } - - // optional bool csharp_multiple_files = 1002 [default = false]; - if (has_csharp_multiple_files()) { - total_size += 2 + 1; - } - - // optional bool csharp_nest_classes = 1003 [default = false]; - if (has_csharp_nest_classes()) { - total_size += 2 + 1; - } - - } - if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { - // optional bool csharp_public_classes = 1004 [default = true]; - if (has_csharp_public_classes()) { - total_size += 2 + 1; - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void FileOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FileOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FileOptions::MergeFrom(const FileOptions& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_java_package(from.java_package()); - } - if (from._has_bit(1)) { - set_java_outer_classname(from.java_outer_classname()); - } - if (from._has_bit(2)) { - set_java_multiple_files(from.java_multiple_files()); - } - if (from._has_bit(3)) { - set_optimize_for(from.optimize_for()); - } - if (from._has_bit(4)) { - set_csharp_namespace(from.csharp_namespace()); - } - if (from._has_bit(5)) { - set_csharp_file_classname(from.csharp_file_classname()); - } - if (from._has_bit(6)) { - set_csharp_multiple_files(from.csharp_multiple_files()); - } - if (from._has_bit(7)) { - set_csharp_nest_classes(from.csharp_nest_classes()); - } - } - if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { - if (from._has_bit(8)) { - set_csharp_public_classes(from.csharp_public_classes()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FileOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FileOptions::CopyFrom(const FileOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FileOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* FileOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FileOptions::GetReflection() const { - if (FileOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FileOptions_reflection_; -} - -// =================================================================== - -const MessageOptions MessageOptions::default_instance_; - - -const int MessageOptions::_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_), -}; - -MessageOptions::MessageOptions() - : _cached_size_(0), - message_set_wire_format_(false) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -MessageOptions::MessageOptions(const MessageOptions& from) - : _cached_size_(0), - message_set_wire_format_(false) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -MessageOptions::~MessageOptions() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* MessageOptions::descriptor() { - if (MessageOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MessageOptions_descriptor_; -} - -MessageOptions* MessageOptions::New() const { - return new MessageOptions; -} - -void MessageOptions::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - message_set_wire_format_ = false; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MessageOptions::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::WireFormat::GetTagFieldNumber(tag)) { - // optional bool message_set_wire_format = 1 [default = false]; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - DO_(::google::protobuf::internal::WireFormat::ReadBool( - input, &message_set_wire_format_)); - _set_bit(0); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool MessageOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional bool message_set_wire_format = 1 [default = false]; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteBool(1, this->message_set_wire_format(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int MessageOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional bool message_set_wire_format = 1 [default = false]; - if (has_message_set_wire_format()) { - total_size += 1 + 1; - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MessageOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void MessageOptions::MergeFrom(const MessageOptions& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_message_set_wire_format(from.message_set_wire_format()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MessageOptions::CopyFrom(const MessageOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MessageOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* MessageOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MessageOptions::GetReflection() const { - if (MessageOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MessageOptions_reflection_; -} - -// =================================================================== - -const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() { - if (FieldOptions_CType_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldOptions_CType_descriptor_; -} -bool FieldOptions_CType_IsValid(int value) { - switch(value) { - case 1: - case 2: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const FieldOptions_CType FieldOptions::CORD; -const FieldOptions_CType FieldOptions::STRING_PIECE; -const FieldOptions_CType FieldOptions::CType_MIN; -const FieldOptions_CType FieldOptions::CType_MAX; -#endif // _MSC_VER -const FieldOptions FieldOptions::default_instance_; - - -const ::std::string FieldOptions::_default_experimental_map_key_; -const int FieldOptions::_offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_), -}; - -FieldOptions::FieldOptions() - : _cached_size_(0), - ctype_(1), - experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -FieldOptions::FieldOptions(const FieldOptions& from) - : _cached_size_(0), - ctype_(1), - experimental_map_key_(const_cast< ::std::string*>(&_default_experimental_map_key_)) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -FieldOptions::~FieldOptions() { - if (experimental_map_key_ != &_default_experimental_map_key_) { - delete experimental_map_key_; - } - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* FieldOptions::descriptor() { - if (FieldOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldOptions_descriptor_; -} - -FieldOptions* FieldOptions::New() const { - return new FieldOptions; -} - -void FieldOptions::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - ctype_ = 1; - if (_has_bit(1)) { - if (experimental_map_key_ != &_default_experimental_map_key_) { - experimental_map_key_->clear(); - } - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool FieldOptions::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::WireFormat::GetTagFieldNumber(tag)) { - // optional .google.protobuf.FieldOptions.CType ctype = 1; - case 1: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_VARINT) { - goto handle_uninterpreted; - } - int value; - DO_(::google::protobuf::internal::WireFormat::ReadEnum(input, &value)); - if (::google::protobuf::FieldOptions_CType_IsValid(value)) { - set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value)); - } else { - mutable_unknown_fields()->AddField(1)->add_varint(value); - } - if (input->ExpectTag(74)) goto parse_experimental_map_key; - break; - } - - // optional string experimental_map_key = 9; - case 9: { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) != - ::google::protobuf::internal::WireFormat::WIRETYPE_LENGTH_DELIMITED) { - goto handle_uninterpreted; - } - parse_experimental_map_key: - DO_(::google::protobuf::internal::WireFormat::ReadString(input, mutable_experimental_map_key())); - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -bool FieldOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - // optional .google.protobuf.FieldOptions.CType ctype = 1; - if (_has_bit(0)) { - DO_(::google::protobuf::internal::WireFormat::WriteEnum(1, this->ctype(), output)); - } - - // optional string experimental_map_key = 9; - if (_has_bit(1)) { - DO_(::google::protobuf::internal::WireFormat::WriteString(9, this->experimental_map_key(), output)); - } - - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int FieldOptions::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // optional .google.protobuf.FieldOptions.CType ctype = 1; - if (has_ctype()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::EnumSize(this->ctype()); - } - - // optional string experimental_map_key = 9; - if (has_experimental_map_key()) { - total_size += 1 + - ::google::protobuf::internal::WireFormat::StringSize(this->experimental_map_key()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const FieldOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void FieldOptions::MergeFrom(const FieldOptions& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { - set_ctype(from.ctype()); - } - if (from._has_bit(1)) { - set_experimental_map_key(from.experimental_map_key()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FieldOptions::CopyFrom(const FieldOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FieldOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* FieldOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* FieldOptions::GetReflection() const { - if (FieldOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return FieldOptions_reflection_; -} - -// =================================================================== - -const EnumOptions EnumOptions::default_instance_; - -const int EnumOptions::_offsets_[1] = { -}; - -EnumOptions::EnumOptions() - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -EnumOptions::EnumOptions(const EnumOptions& from) - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -EnumOptions::~EnumOptions() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* EnumOptions::descriptor() { - if (EnumOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumOptions_descriptor_; -} - -EnumOptions* EnumOptions::New() const { - return new EnumOptions; -} - -void EnumOptions::Clear() { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - } - return true; -#undef DO_ -} - -bool EnumOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int EnumOptions::ByteSize() const { - int total_size = 0; - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); -} - -void EnumOptions::MergeFrom(const EnumOptions& from) { - GOOGLE_CHECK_NE(&from, this); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumOptions::CopyFrom(const EnumOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* EnumOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumOptions::GetReflection() const { - if (EnumOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumOptions_reflection_; -} - -// =================================================================== - -const EnumValueOptions EnumValueOptions::default_instance_; - -const int EnumValueOptions::_offsets_[1] = { -}; - -EnumValueOptions::EnumValueOptions() - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -EnumValueOptions::~EnumValueOptions() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { - if (EnumValueOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumValueOptions_descriptor_; -} - -EnumValueOptions* EnumValueOptions::New() const { - return new EnumValueOptions; -} - -void EnumValueOptions::Clear() { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool EnumValueOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - } - return true; -#undef DO_ -} - -bool EnumValueOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int EnumValueOptions::ByteSize() const { - int total_size = 0; - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); -} - -void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { - GOOGLE_CHECK_NE(&from, this); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void EnumValueOptions::CopyFrom(const EnumValueOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool EnumValueOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* EnumValueOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* EnumValueOptions::GetReflection() const { - if (EnumValueOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return EnumValueOptions_reflection_; -} - -// =================================================================== - -const ServiceOptions ServiceOptions::default_instance_; - -const int ServiceOptions::_offsets_[1] = { -}; - -ServiceOptions::ServiceOptions() - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -ServiceOptions::ServiceOptions(const ServiceOptions& from) - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -ServiceOptions::~ServiceOptions() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { - if (ServiceOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return ServiceOptions_descriptor_; -} - -ServiceOptions* ServiceOptions::New() const { - return new ServiceOptions; -} - -void ServiceOptions::Clear() { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool ServiceOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - } - return true; -#undef DO_ -} - -bool ServiceOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int ServiceOptions::ByteSize() const { - int total_size = 0; - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); -} - -void ServiceOptions::MergeFrom(const ServiceOptions& from) { - GOOGLE_CHECK_NE(&from, this); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void ServiceOptions::CopyFrom(const ServiceOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool ServiceOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* ServiceOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* ServiceOptions::GetReflection() const { - if (ServiceOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return ServiceOptions_reflection_; -} - -// =================================================================== - -const MethodOptions MethodOptions::default_instance_; - -const int MethodOptions::_offsets_[1] = { -}; - -MethodOptions::MethodOptions() - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - if (this == &default_instance_) { - } -} - -MethodOptions::MethodOptions(const MethodOptions& from) - : _cached_size_(0) { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - MergeFrom(from); -} - -MethodOptions::~MethodOptions() { - if (this != &default_instance_) { - } -} - -const ::google::protobuf::Descriptor* MethodOptions::descriptor() { - if (MethodOptions_descriptor_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MethodOptions_descriptor_; -} - -MethodOptions* MethodOptions::New() const { - return new MethodOptions; -} - -void MethodOptions::Clear() { - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool MethodOptions::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - } - return true; -#undef DO_ -} - -bool MethodOptions::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - if (!unknown_fields().empty()) { - DO_(::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output)); - } - return true; -#undef DO_ -} - -int MethodOptions::ByteSize() const { - int total_size = 0; - - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - _cached_size_ = total_size; - return total_size; -} - -void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); -} - -void MethodOptions::MergeFrom(const MethodOptions& from) { - GOOGLE_CHECK_NE(&from, this); - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MethodOptions::CopyFrom(const MethodOptions& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MethodOptions::IsInitialized() const { - - return true; -} - -const ::google::protobuf::Descriptor* MethodOptions::GetDescriptor() const { - return descriptor(); -} - -const ::google::protobuf::Reflection* MethodOptions::GetReflection() const { - if (MethodOptions_reflection_ == NULL) protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - return MethodOptions_reflection_; -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h deleted file mode 100644 index ea8b67a3..00000000 --- a/src/google/protobuf/descriptor.pb.h +++ /dev/null @@ -1,3221 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! - -#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED -#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED - -#include <string> - -#include <google/protobuf/stubs/common.h> - -#if GOOGLE_PROTOBUF_VERSION < 2000001 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 2000001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/repeated_field.h> -#include <google/protobuf/extension_set.h> - -namespace google { -namespace protobuf { - -// Internal implementation detail -- do not call this. -void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - -class FileDescriptorSet; -class FileDescriptorProto; -class DescriptorProto; -class DescriptorProto_ExtensionRange; -class FieldDescriptorProto; -class EnumDescriptorProto; -class EnumValueDescriptorProto; -class ServiceDescriptorProto; -class MethodDescriptorProto; -class FileOptions; -class MessageOptions; -class FieldOptions; -class EnumOptions; -class EnumValueOptions; -class ServiceOptions; -class MethodOptions; - -enum FieldDescriptorProto_Type { - FieldDescriptorProto_Type_TYPE_DOUBLE = 1, - FieldDescriptorProto_Type_TYPE_FLOAT = 2, - FieldDescriptorProto_Type_TYPE_INT64 = 3, - FieldDescriptorProto_Type_TYPE_UINT64 = 4, - FieldDescriptorProto_Type_TYPE_INT32 = 5, - FieldDescriptorProto_Type_TYPE_FIXED64 = 6, - FieldDescriptorProto_Type_TYPE_FIXED32 = 7, - FieldDescriptorProto_Type_TYPE_BOOL = 8, - FieldDescriptorProto_Type_TYPE_STRING = 9, - FieldDescriptorProto_Type_TYPE_GROUP = 10, - FieldDescriptorProto_Type_TYPE_MESSAGE = 11, - FieldDescriptorProto_Type_TYPE_BYTES = 12, - FieldDescriptorProto_Type_TYPE_UINT32 = 13, - FieldDescriptorProto_Type_TYPE_ENUM = 14, - FieldDescriptorProto_Type_TYPE_SFIXED32 = 15, - FieldDescriptorProto_Type_TYPE_SFIXED64 = 16, - FieldDescriptorProto_Type_TYPE_SINT32 = 17, - FieldDescriptorProto_Type_TYPE_SINT64 = 18, -}; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor(); -LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value); -const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE; -const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64; - -enum FieldDescriptorProto_Label { - FieldDescriptorProto_Label_LABEL_OPTIONAL = 1, - FieldDescriptorProto_Label_LABEL_REQUIRED = 2, - FieldDescriptorProto_Label_LABEL_REPEATED = 3, -}; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor(); -LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value); -const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL; -const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED; - -enum FileOptions_OptimizeMode { - FileOptions_OptimizeMode_SPEED = 1, - FileOptions_OptimizeMode_CODE_SIZE = 2, -}; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor(); -LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value); -const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED; -const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_CODE_SIZE; - -enum FieldOptions_CType { - FieldOptions_CType_CORD = 1, - FieldOptions_CType_STRING_PIECE = 2, -}; -LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor(); -LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value); -const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_CORD; -const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE; - -// =================================================================== - -class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message { - public: - FileDescriptorSet(); - virtual ~FileDescriptorSet(); - - FileDescriptorSet(const FileDescriptorSet& from); - - inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { - CopyFrom(from); - return *this; - } - - inline static const FileDescriptorSet& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - FileDescriptorSet* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileDescriptorSet& from); - void MergeFrom(const FileDescriptorSet& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.FileDescriptorProto file = 1; - inline int file_size() const; - inline void clear_file(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& file() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* mutable_file(); - inline const ::google::protobuf::FileDescriptorProto& file(int index) const; - inline ::google::protobuf::FileDescriptorProto* mutable_file(int index); - inline ::google::protobuf::FileDescriptorProto* add_file(); - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const FileDescriptorSet default_instance_; - static const int _offsets_[1]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message { - public: - FileDescriptorProto(); - virtual ~FileDescriptorProto(); - - FileDescriptorProto(const FileDescriptorProto& from); - - inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const FileDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - FileDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileDescriptorProto& from); - void MergeFrom(const FileDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // optional string package = 2; - inline bool has_package() const; - inline void clear_package(); - inline const ::std::string& package() const; - inline void set_package(const ::std::string& value); - inline void set_package(const char* value); - inline ::std::string* mutable_package(); - - // repeated string dependency = 3; - inline int dependency_size() const; - inline void clear_dependency(); - inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; - inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); - inline const ::std::string& dependency(int index) const; - inline ::std::string* mutable_dependency(int index); - inline void set_dependency(int index, const ::std::string& value); - inline void set_dependency(int index, const char* value); - inline ::std::string* add_dependency(); - inline void add_dependency(const ::std::string& value); - inline void add_dependency(const char* value); - - // repeated .google.protobuf.DescriptorProto message_type = 4; - inline int message_type_size() const; - inline void clear_message_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& message_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_message_type(); - inline const ::google::protobuf::DescriptorProto& message_type(int index) const; - inline ::google::protobuf::DescriptorProto* mutable_message_type(int index); - inline ::google::protobuf::DescriptorProto* add_message_type(); - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - inline int enum_type_size() const; - inline void clear_enum_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type(); - inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; - inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); - - // repeated .google.protobuf.ServiceDescriptorProto service = 6; - inline int service_size() const; - inline void clear_service(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& service() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* mutable_service(); - inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const; - inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); - inline ::google::protobuf::ServiceDescriptorProto* add_service(); - - // repeated .google.protobuf.FieldDescriptorProto extension = 7; - inline int extension_size() const; - inline void clear_extension(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension(); - inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - inline ::google::protobuf::FieldDescriptorProto* add_extension(); - - // optional .google.protobuf.FileOptions options = 8; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::FileOptions& options() const; - inline ::google::protobuf::FileOptions* mutable_options(); - - private: - ::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_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const FileDescriptorProto default_instance_; - static const int _offsets_[8]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message { - public: - DescriptorProto_ExtensionRange(); - virtual ~DescriptorProto_ExtensionRange(); - - DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); - - inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { - CopyFrom(from); - return *this; - } - - inline static const DescriptorProto_ExtensionRange& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - DescriptorProto_ExtensionRange* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const DescriptorProto_ExtensionRange& from); - void MergeFrom(const DescriptorProto_ExtensionRange& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional int32 start = 1; - inline bool has_start() const; - inline void clear_start(); - inline ::google::protobuf::int32 start() const; - inline void set_start(::google::protobuf::int32 value); - - // optional int32 end = 2; - inline bool has_end() const; - inline void clear_end(); - inline ::google::protobuf::int32 end() const; - inline void set_end(::google::protobuf::int32 value); - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - ::google::protobuf::int32 start_; - ::google::protobuf::int32 end_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const DescriptorProto_ExtensionRange default_instance_; - static const int _offsets_[2]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { - public: - DescriptorProto(); - virtual ~DescriptorProto(); - - DescriptorProto(const DescriptorProto& from); - - inline DescriptorProto& operator=(const DescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const DescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - DescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const DescriptorProto& from); - void MergeFrom(const DescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - typedef DescriptorProto_ExtensionRange ExtensionRange; - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.FieldDescriptorProto field = 2; - inline int field_size() const; - inline void clear_field(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& field() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_field(); - inline const ::google::protobuf::FieldDescriptorProto& field(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index); - inline ::google::protobuf::FieldDescriptorProto* add_field(); - - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - inline int extension_size() const; - inline void clear_extension(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* mutable_extension(); - inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const; - inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - inline ::google::protobuf::FieldDescriptorProto* add_extension(); - - // repeated .google.protobuf.DescriptorProto nested_type = 3; - inline int nested_type_size() const; - inline void clear_nested_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& nested_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* mutable_nested_type(); - inline const ::google::protobuf::DescriptorProto& nested_type(int index) const; - inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index); - inline ::google::protobuf::DescriptorProto* add_nested_type(); - - // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - inline int enum_type_size() const; - inline void clear_enum_type(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& enum_type() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* mutable_enum_type(); - inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; - inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - inline ::google::protobuf::EnumDescriptorProto* add_enum_type(); - - // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - inline int extension_range_size() const; - inline void clear_extension_range(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& extension_range() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* mutable_extension_range(); - inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; - inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); - inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); - - // optional .google.protobuf.MessageOptions options = 7; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::MessageOptions& options() const; - inline ::google::protobuf::MessageOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const DescriptorProto default_instance_; - static const int _offsets_[7]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message { - public: - FieldDescriptorProto(); - virtual ~FieldDescriptorProto(); - - FieldDescriptorProto(const FieldDescriptorProto& from); - - inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const FieldDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - FieldDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FieldDescriptorProto& from); - void MergeFrom(const FieldDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - typedef FieldDescriptorProto_Type Type; - static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE; - static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT; - static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64; - static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64; - static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32; - static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64; - static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32; - static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL; - static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING; - static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP; - static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE; - static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES; - static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32; - static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM; - static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32; - static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64; - static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32; - static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64; - static inline const ::google::protobuf::EnumDescriptor* - Type_descriptor() { - return FieldDescriptorProto_Type_descriptor(); - } - static inline bool Type_IsValid(int value) { - return FieldDescriptorProto_Type_IsValid(value); - } - static const Type Type_MIN = - FieldDescriptorProto_Type_Type_MIN; - static const Type Type_MAX = - FieldDescriptorProto_Type_Type_MAX; - - typedef FieldDescriptorProto_Label Label; - static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL; - static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED; - static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED; - static inline const ::google::protobuf::EnumDescriptor* - Label_descriptor() { - return FieldDescriptorProto_Label_descriptor(); - } - static inline bool Label_IsValid(int value) { - return FieldDescriptorProto_Label_IsValid(value); - } - static const Label Label_MIN = - FieldDescriptorProto_Label_Label_MIN; - static const Label Label_MAX = - FieldDescriptorProto_Label_Label_MAX; - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // optional int32 number = 3; - inline bool has_number() const; - inline void clear_number(); - inline ::google::protobuf::int32 number() const; - inline void set_number(::google::protobuf::int32 value); - - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - inline bool has_label() const; - inline void clear_label(); - inline ::google::protobuf::FieldDescriptorProto_Label label() const; - inline void set_label(::google::protobuf::FieldDescriptorProto_Label value); - - // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - inline bool has_type() const; - inline void clear_type(); - inline ::google::protobuf::FieldDescriptorProto_Type type() const; - inline void set_type(::google::protobuf::FieldDescriptorProto_Type value); - - // optional string type_name = 6; - inline bool has_type_name() const; - inline void clear_type_name(); - inline const ::std::string& type_name() const; - inline void set_type_name(const ::std::string& value); - inline void set_type_name(const char* value); - inline ::std::string* mutable_type_name(); - - // optional string extendee = 2; - inline bool has_extendee() const; - inline void clear_extendee(); - inline const ::std::string& extendee() const; - inline void set_extendee(const ::std::string& value); - inline void set_extendee(const char* value); - inline ::std::string* mutable_extendee(); - - // optional string default_value = 7; - inline bool has_default_value() const; - inline void clear_default_value(); - inline const ::std::string& default_value() const; - inline void set_default_value(const ::std::string& value); - inline void set_default_value(const char* value); - inline ::std::string* mutable_default_value(); - - // optional .google.protobuf.FieldOptions options = 8; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::FieldOptions& options() const; - inline ::google::protobuf::FieldOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const FieldDescriptorProto default_instance_; - static const int _offsets_[8]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message { - public: - EnumDescriptorProto(); - virtual ~EnumDescriptorProto(); - - EnumDescriptorProto(const EnumDescriptorProto& from); - - inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const EnumDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - EnumDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumDescriptorProto& from); - void MergeFrom(const EnumDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - inline int value_size() const; - inline void clear_value(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& value() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* mutable_value(); - inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; - inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); - inline ::google::protobuf::EnumValueDescriptorProto* add_value(); - - // optional .google.protobuf.EnumOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::EnumOptions& options() const; - inline ::google::protobuf::EnumOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const EnumDescriptorProto default_instance_; - static const int _offsets_[3]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message { - public: - EnumValueDescriptorProto(); - virtual ~EnumValueDescriptorProto(); - - EnumValueDescriptorProto(const EnumValueDescriptorProto& from); - - inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const EnumValueDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - EnumValueDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumValueDescriptorProto& from); - void MergeFrom(const EnumValueDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // optional int32 number = 2; - inline bool has_number() const; - inline void clear_number(); - inline ::google::protobuf::int32 number() const; - inline void set_number(::google::protobuf::int32 value); - - // optional .google.protobuf.EnumValueOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::EnumValueOptions& options() const; - inline ::google::protobuf::EnumValueOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const EnumValueDescriptorProto default_instance_; - static const int _offsets_[3]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message { - public: - ServiceDescriptorProto(); - virtual ~ServiceDescriptorProto(); - - ServiceDescriptorProto(const ServiceDescriptorProto& from); - - inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const ServiceDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - ServiceDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const ServiceDescriptorProto& from); - void MergeFrom(const ServiceDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // repeated .google.protobuf.MethodDescriptorProto method = 2; - inline int method_size() const; - inline void clear_method(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& method() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* mutable_method(); - inline const ::google::protobuf::MethodDescriptorProto& method(int index) const; - inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index); - inline ::google::protobuf::MethodDescriptorProto* add_method(); - - // optional .google.protobuf.ServiceOptions options = 3; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::ServiceOptions& options() const; - inline ::google::protobuf::ServiceOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const ServiceDescriptorProto default_instance_; - static const int _offsets_[3]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message { - public: - MethodDescriptorProto(); - virtual ~MethodDescriptorProto(); - - MethodDescriptorProto(const MethodDescriptorProto& from); - - inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { - CopyFrom(from); - return *this; - } - - inline static const MethodDescriptorProto& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - MethodDescriptorProto* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MethodDescriptorProto& from); - void MergeFrom(const MethodDescriptorProto& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline ::std::string* mutable_name(); - - // optional string input_type = 2; - inline bool has_input_type() const; - inline void clear_input_type(); - inline const ::std::string& input_type() const; - inline void set_input_type(const ::std::string& value); - inline void set_input_type(const char* value); - inline ::std::string* mutable_input_type(); - - // optional string output_type = 3; - inline bool has_output_type() const; - inline void clear_output_type(); - inline const ::std::string& output_type() const; - inline void set_output_type(const ::std::string& value); - inline void set_output_type(const char* value); - inline ::std::string* mutable_output_type(); - - // optional .google.protobuf.MethodOptions options = 4; - inline bool has_options() const; - inline void clear_options(); - inline const ::google::protobuf::MethodOptions& options() const; - inline ::google::protobuf::MethodOptions* mutable_options(); - - private: - ::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 protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const MethodDescriptorProto default_instance_; - static const int _offsets_[4]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { - public: - FileOptions(); - virtual ~FileOptions(); - - FileOptions(const FileOptions& from); - - inline FileOptions& operator=(const FileOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const FileOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - FileOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FileOptions& from); - void MergeFrom(const FileOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - typedef FileOptions_OptimizeMode OptimizeMode; - static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED; - static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE; - static inline const ::google::protobuf::EnumDescriptor* - OptimizeMode_descriptor() { - return FileOptions_OptimizeMode_descriptor(); - } - static inline bool OptimizeMode_IsValid(int value) { - return FileOptions_OptimizeMode_IsValid(value); - } - static const OptimizeMode OptimizeMode_MIN = - FileOptions_OptimizeMode_OptimizeMode_MIN; - static const OptimizeMode OptimizeMode_MAX = - FileOptions_OptimizeMode_OptimizeMode_MAX; - - // accessors ------------------------------------------------------- - - // optional string java_package = 1; - inline bool has_java_package() const; - inline void clear_java_package(); - inline const ::std::string& java_package() const; - inline void set_java_package(const ::std::string& value); - inline void set_java_package(const char* value); - inline ::std::string* mutable_java_package(); - - // optional string java_outer_classname = 8; - inline bool has_java_outer_classname() const; - inline void clear_java_outer_classname(); - inline const ::std::string& java_outer_classname() const; - inline void set_java_outer_classname(const ::std::string& value); - inline void set_java_outer_classname(const char* value); - inline ::std::string* mutable_java_outer_classname(); - - // optional bool java_multiple_files = 10 [default = false]; - inline bool has_java_multiple_files() const; - inline void clear_java_multiple_files(); - inline bool java_multiple_files() const; - inline void set_java_multiple_files(bool value); - - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE]; - inline bool has_optimize_for() const; - inline void clear_optimize_for(); - inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; - inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); - - // optional string csharp_namespace = 1000; - inline bool has_csharp_namespace() const; - inline void clear_csharp_namespace(); - inline const ::std::string& csharp_namespace() const; - inline void set_csharp_namespace(const ::std::string& value); - inline void set_csharp_namespace(const char* value); - inline ::std::string* mutable_csharp_namespace(); - - // optional string csharp_file_classname = 1001; - inline bool has_csharp_file_classname() const; - inline void clear_csharp_file_classname(); - inline const ::std::string& csharp_file_classname() const; - inline void set_csharp_file_classname(const ::std::string& value); - inline void set_csharp_file_classname(const char* value); - inline ::std::string* mutable_csharp_file_classname(); - - // optional bool csharp_multiple_files = 1002 [default = false]; - inline bool has_csharp_multiple_files() const; - inline void clear_csharp_multiple_files(); - inline bool csharp_multiple_files() const; - inline void set_csharp_multiple_files(bool value); - - // optional bool csharp_nest_classes = 1003 [default = false]; - inline bool has_csharp_nest_classes() const; - inline void clear_csharp_nest_classes(); - inline bool csharp_nest_classes() const; - inline void set_csharp_nest_classes(bool value); - - // optional bool csharp_public_classes = 1004 [default = true]; - inline bool has_csharp_public_classes() const; - inline void clear_csharp_public_classes(); - inline bool csharp_public_classes() const; - inline void set_csharp_public_classes(bool value); - - private: - ::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_; - ::std::string* csharp_namespace_; - static const ::std::string _default_csharp_namespace_; - ::std::string* csharp_file_classname_; - static const ::std::string _default_csharp_file_classname_; - bool csharp_multiple_files_; - bool csharp_nest_classes_; - bool csharp_public_classes_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const FileOptions default_instance_; - static const int _offsets_[9]; - - ::google::protobuf::uint32 _has_bits_[(9 + 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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { - public: - MessageOptions(); - virtual ~MessageOptions(); - - MessageOptions(const MessageOptions& from); - - inline MessageOptions& operator=(const MessageOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const MessageOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - MessageOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MessageOptions& from); - void MergeFrom(const MessageOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional bool message_set_wire_format = 1 [default = false]; - inline bool has_message_set_wire_format() const; - inline void clear_message_set_wire_format(); - inline bool message_set_wire_format() const; - inline void set_message_set_wire_format(bool value); - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - bool message_set_wire_format_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const MessageOptions default_instance_; - static const int _offsets_[1]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { - public: - FieldOptions(); - virtual ~FieldOptions(); - - FieldOptions(const FieldOptions& from); - - inline FieldOptions& operator=(const FieldOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const FieldOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - FieldOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const FieldOptions& from); - void MergeFrom(const FieldOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - typedef FieldOptions_CType CType; - static const CType CORD = FieldOptions_CType_CORD; - static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE; - static inline const ::google::protobuf::EnumDescriptor* - CType_descriptor() { - return FieldOptions_CType_descriptor(); - } - static inline bool CType_IsValid(int value) { - return FieldOptions_CType_IsValid(value); - } - static const CType CType_MIN = - FieldOptions_CType_CType_MIN; - static const CType CType_MAX = - FieldOptions_CType_CType_MAX; - - // accessors ------------------------------------------------------- - - // optional .google.protobuf.FieldOptions.CType ctype = 1; - inline bool has_ctype() const; - inline void clear_ctype(); - inline ::google::protobuf::FieldOptions_CType ctype() const; - inline void set_ctype(::google::protobuf::FieldOptions_CType value); - - // optional string experimental_map_key = 9; - inline bool has_experimental_map_key() const; - inline void clear_experimental_map_key(); - inline const ::std::string& experimental_map_key() const; - inline void set_experimental_map_key(const ::std::string& value); - inline void set_experimental_map_key(const char* value); - inline ::std::string* mutable_experimental_map_key(); - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - int ctype_; - ::std::string* experimental_map_key_; - static const ::std::string _default_experimental_map_key_; - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const FieldOptions default_instance_; - static const int _offsets_[2]; - - ::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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { - public: - EnumOptions(); - virtual ~EnumOptions(); - - EnumOptions(const EnumOptions& from); - - inline EnumOptions& operator=(const EnumOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const EnumOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - EnumOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumOptions& from); - void MergeFrom(const EnumOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const EnumOptions default_instance_; - static const int _offsets_[1]; - - ::google::protobuf::uint32 _has_bits_[1]; - - // 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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { - public: - EnumValueOptions(); - virtual ~EnumValueOptions(); - - EnumValueOptions(const EnumValueOptions& from); - - inline EnumValueOptions& operator=(const EnumValueOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const EnumValueOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - EnumValueOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const EnumValueOptions& from); - void MergeFrom(const EnumValueOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const EnumValueOptions default_instance_; - static const int _offsets_[1]; - - ::google::protobuf::uint32 _has_bits_[1]; - - // 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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { - public: - ServiceOptions(); - virtual ~ServiceOptions(); - - ServiceOptions(const ServiceOptions& from); - - inline ServiceOptions& operator=(const ServiceOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const ServiceOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - ServiceOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const ServiceOptions& from); - void MergeFrom(const ServiceOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const ServiceOptions default_instance_; - static const int _offsets_[1]; - - ::google::protobuf::uint32 _has_bits_[1]; - - // 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)); - } -}; -// ------------------------------------------------------------------- - -class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { - public: - MethodOptions(); - virtual ~MethodOptions(); - - MethodOptions(const MethodOptions& from); - - inline MethodOptions& operator=(const MethodOptions& from) { - CopyFrom(from); - return *this; - } - - inline static const MethodOptions& default_instance() { - return default_instance_; - } - - 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(); - - // implements Message ---------------------------------------------- - - MethodOptions* New() const; - void CopyFrom(const ::google::protobuf::Message& from); - void MergeFrom(const ::google::protobuf::Message& from); - void CopyFrom(const MethodOptions& from); - void MergeFrom(const MethodOptions& from); - void Clear(); - bool IsInitialized() const; - int ByteSize() const; - - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input); - bool SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const; - int GetCachedSize() const { return _cached_size_; } - private: - void SetCachedSize(int size) const { _cached_size_ = size; } - public: - - const ::google::protobuf::Descriptor* GetDescriptor() const; - const ::google::protobuf::Reflection* GetReflection() const; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - private: - ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; - - friend void protobuf_BuildDesc_google_2fprotobuf_2fdescriptor_2eproto(); - static const MethodOptions default_instance_; - static const int _offsets_[1]; - - ::google::protobuf::uint32 _has_bits_[1]; - - // 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)); - } -}; -// =================================================================== - - -// =================================================================== - - -// =================================================================== - -// FileDescriptorSet - -// repeated .google.protobuf.FileDescriptorProto file = 1; -inline int FileDescriptorSet::file_size() const { - return file_.size(); -} -inline void FileDescriptorSet::clear_file() { - file_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& -FileDescriptorSet::file() const { - return file_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* -FileDescriptorSet::mutable_file() { - return &file_; -} -inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { - return file_.Get(index); -} -inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) { - return file_.Mutable(index); -} -inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() { - return file_.Add(); -} - -// ------------------------------------------------------------------- - -// FileDescriptorProto - -// optional string name = 1; -inline bool FileDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void FileDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FileDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* FileDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional string package = 2; -inline bool FileDescriptorProto::has_package() const { - return _has_bit(1); -} -inline void FileDescriptorProto::clear_package() { - if (package_ != &_default_package_) { - package_->clear(); - } - _clear_bit(1); -} -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_) { - package_ = new ::std::string; - } - package_->assign(value); -} -inline void FileDescriptorProto::set_package(const char* value) { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - package_->assign(value); -} -inline ::std::string* FileDescriptorProto::mutable_package() { - _set_bit(1); - if (package_ == &_default_package_) { - package_ = new ::std::string; - } - return package_; -} - -// repeated string dependency = 3; -inline int FileDescriptorProto::dependency_size() const { - return dependency_.size(); -} -inline void FileDescriptorProto::clear_dependency() { - dependency_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::std::string>& -FileDescriptorProto::dependency() const { - return dependency_; -} -inline ::google::protobuf::RepeatedPtrField< ::std::string>* -FileDescriptorProto::mutable_dependency() { - return &dependency_; -} -inline const ::std::string& FileDescriptorProto::dependency(int index) const { - return dependency_.Get(index); -} -inline ::std::string* FileDescriptorProto::mutable_dependency(int index) { - return dependency_.Mutable(index); -} -inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) { - dependency_.Mutable(index)->assign(value); -} -inline void FileDescriptorProto::set_dependency(int index, const char* value) { - dependency_.Mutable(index)->assign(value); -} -inline ::std::string* FileDescriptorProto::add_dependency() { - return dependency_.Add(); -} -inline void FileDescriptorProto::add_dependency(const ::std::string& value) { - dependency_.Add()->assign(value); -} -inline void FileDescriptorProto::add_dependency(const char* value) { - dependency_.Add()->assign(value); -} - -// repeated .google.protobuf.DescriptorProto message_type = 4; -inline int FileDescriptorProto::message_type_size() const { - return message_type_.size(); -} -inline void FileDescriptorProto::clear_message_type() { - message_type_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -FileDescriptorProto::message_type() const { - return message_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -FileDescriptorProto::mutable_message_type() { - return &message_type_; -} -inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { - return message_type_.Get(index); -} -inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) { - return message_type_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() { - return message_type_.Add(); -} - -// repeated .google.protobuf.EnumDescriptorProto enum_type = 5; -inline int FileDescriptorProto::enum_type_size() const { - return enum_type_.size(); -} -inline void FileDescriptorProto::clear_enum_type() { - enum_type_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -FileDescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -FileDescriptorProto::mutable_enum_type() { - return &enum_type_; -} -inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { - return enum_type_.Get(index); -} -inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) { - return enum_type_.Mutable(index); -} -inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() { - return enum_type_.Add(); -} - -// repeated .google.protobuf.ServiceDescriptorProto service = 6; -inline int FileDescriptorProto::service_size() const { - return service_.size(); -} -inline void FileDescriptorProto::clear_service() { - service_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& -FileDescriptorProto::service() const { - return service_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* -FileDescriptorProto::mutable_service() { - return &service_; -} -inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { - return service_.Get(index); -} -inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) { - return service_.Mutable(index); -} -inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() { - return service_.Add(); -} - -// repeated .google.protobuf.FieldDescriptorProto extension = 7; -inline int FileDescriptorProto::extension_size() const { - return extension_.size(); -} -inline void FileDescriptorProto::clear_extension() { - extension_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -FileDescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -FileDescriptorProto::mutable_extension() { - return &extension_; -} -inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { - return extension_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) { - return extension_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() { - return extension_.Add(); -} - -// optional .google.protobuf.FileOptions options = 8; -inline bool FileDescriptorProto::has_options() const { - return _has_bit(7); -} -inline void FileDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); - _clear_bit(7); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::FileOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// DescriptorProto_ExtensionRange - -// optional int32 start = 1; -inline bool DescriptorProto_ExtensionRange::has_start() const { - return _has_bit(0); -} -inline void DescriptorProto_ExtensionRange::clear_start() { - start_ = 0; - _clear_bit(0); -} -inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const { - return start_; -} -inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) { - _set_bit(0); - start_ = value; -} - -// optional int32 end = 2; -inline bool DescriptorProto_ExtensionRange::has_end() const { - return _has_bit(1); -} -inline void DescriptorProto_ExtensionRange::clear_end() { - end_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const { - return end_; -} -inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { - _set_bit(1); - end_ = value; -} - -// ------------------------------------------------------------------- - -// DescriptorProto - -// optional string name = 1; -inline bool DescriptorProto::has_name() const { - return _has_bit(0); -} -inline void DescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void DescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* DescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.FieldDescriptorProto field = 2; -inline int DescriptorProto::field_size() const { - return field_.size(); -} -inline void DescriptorProto::clear_field() { - field_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::field() const { - return field_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_field() { - return &field_; -} -inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { - return field_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) { - return field_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() { - return field_.Add(); -} - -// repeated .google.protobuf.FieldDescriptorProto extension = 6; -inline int DescriptorProto::extension_size() const { - return extension_.size(); -} -inline void DescriptorProto::clear_extension() { - extension_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& -DescriptorProto::extension() const { - return extension_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* -DescriptorProto::mutable_extension() { - return &extension_; -} -inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { - return extension_.Get(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) { - return extension_.Mutable(index); -} -inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() { - return extension_.Add(); -} - -// repeated .google.protobuf.DescriptorProto nested_type = 3; -inline int DescriptorProto::nested_type_size() const { - return nested_type_.size(); -} -inline void DescriptorProto::clear_nested_type() { - nested_type_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& -DescriptorProto::nested_type() const { - return nested_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* -DescriptorProto::mutable_nested_type() { - return &nested_type_; -} -inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { - return nested_type_.Get(index); -} -inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) { - return nested_type_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() { - return nested_type_.Add(); -} - -// repeated .google.protobuf.EnumDescriptorProto enum_type = 4; -inline int DescriptorProto::enum_type_size() const { - return enum_type_.size(); -} -inline void DescriptorProto::clear_enum_type() { - enum_type_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& -DescriptorProto::enum_type() const { - return enum_type_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* -DescriptorProto::mutable_enum_type() { - return &enum_type_; -} -inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { - return enum_type_.Get(index); -} -inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) { - return enum_type_.Mutable(index); -} -inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() { - return enum_type_.Add(); -} - -// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; -inline int DescriptorProto::extension_range_size() const { - return extension_range_.size(); -} -inline void DescriptorProto::clear_extension_range() { - extension_range_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& -DescriptorProto::extension_range() const { - return extension_range_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* -DescriptorProto::mutable_extension_range() { - return &extension_range_; -} -inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { - return extension_range_.Get(index); -} -inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) { - return extension_range_.Mutable(index); -} -inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() { - return extension_range_.Add(); -} - -// optional .google.protobuf.MessageOptions options = 7; -inline bool DescriptorProto::has_options() const { - return _has_bit(6); -} -inline void DescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); - _clear_bit(6); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// FieldDescriptorProto - -// optional string name = 1; -inline bool FieldDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void FieldDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void FieldDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* FieldDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional int32 number = 3; -inline bool FieldDescriptorProto::has_number() const { - return _has_bit(1); -} -inline void FieldDescriptorProto::clear_number() { - number_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 FieldDescriptorProto::number() const { - return number_; -} -inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); - number_ = value; -} - -// optional .google.protobuf.FieldDescriptorProto.Label label = 4; -inline bool FieldDescriptorProto::has_label() const { - return _has_bit(2); -} -inline void FieldDescriptorProto::clear_label() { - label_ = 1; - _clear_bit(2); -} -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); - label_ = value; -} - -// optional .google.protobuf.FieldDescriptorProto.Type type = 5; -inline bool FieldDescriptorProto::has_type() const { - return _has_bit(3); -} -inline void FieldDescriptorProto::clear_type() { - type_ = 1; - _clear_bit(3); -} -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); - type_ = value; -} - -// optional string type_name = 6; -inline bool FieldDescriptorProto::has_type_name() const { - return _has_bit(4); -} -inline void FieldDescriptorProto::clear_type_name() { - if (type_name_ != &_default_type_name_) { - type_name_->clear(); - } - _clear_bit(4); -} -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_) { - 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_) { - type_name_ = new ::std::string; - } - type_name_->assign(value); -} -inline ::std::string* FieldDescriptorProto::mutable_type_name() { - _set_bit(4); - if (type_name_ == &_default_type_name_) { - type_name_ = new ::std::string; - } - return type_name_; -} - -// optional string extendee = 2; -inline bool FieldDescriptorProto::has_extendee() const { - return _has_bit(5); -} -inline void FieldDescriptorProto::clear_extendee() { - if (extendee_ != &_default_extendee_) { - extendee_->clear(); - } - _clear_bit(5); -} -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_) { - extendee_ = new ::std::string; - } - extendee_->assign(value); -} -inline void FieldDescriptorProto::set_extendee(const char* value) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - extendee_->assign(value); -} -inline ::std::string* FieldDescriptorProto::mutable_extendee() { - _set_bit(5); - if (extendee_ == &_default_extendee_) { - extendee_ = new ::std::string; - } - return extendee_; -} - -// optional string default_value = 7; -inline bool FieldDescriptorProto::has_default_value() const { - return _has_bit(6); -} -inline void FieldDescriptorProto::clear_default_value() { - if (default_value_ != &_default_default_value_) { - default_value_->clear(); - } - _clear_bit(6); -} -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_) { - 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_) { - default_value_ = new ::std::string; - } - default_value_->assign(value); -} -inline ::std::string* FieldDescriptorProto::mutable_default_value() { - _set_bit(6); - if (default_value_ == &_default_default_value_) { - default_value_ = new ::std::string; - } - return default_value_; -} - -// optional .google.protobuf.FieldOptions options = 8; -inline bool FieldDescriptorProto::has_options() const { - return _has_bit(7); -} -inline void FieldDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); - _clear_bit(7); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// EnumDescriptorProto - -// optional string name = 1; -inline bool EnumDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void EnumDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* EnumDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.EnumValueDescriptorProto value = 2; -inline int EnumDescriptorProto::value_size() const { - return value_.size(); -} -inline void EnumDescriptorProto::clear_value() { - value_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& -EnumDescriptorProto::value() const { - return value_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* -EnumDescriptorProto::mutable_value() { - return &value_; -} -inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { - return value_.Get(index); -} -inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) { - return value_.Mutable(index); -} -inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() { - return value_.Add(); -} - -// optional .google.protobuf.EnumOptions options = 3; -inline bool EnumDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void EnumDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); - _clear_bit(2); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// EnumValueDescriptorProto - -// optional string name = 1; -inline bool EnumValueDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void EnumValueDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void EnumValueDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* EnumValueDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional int32 number = 2; -inline bool EnumValueDescriptorProto::has_number() const { - return _has_bit(1); -} -inline void EnumValueDescriptorProto::clear_number() { - number_ = 0; - _clear_bit(1); -} -inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const { - return number_; -} -inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); - number_ = value; -} - -// optional .google.protobuf.EnumValueOptions options = 3; -inline bool EnumValueDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void EnumValueDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); - _clear_bit(2); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// ServiceDescriptorProto - -// optional string name = 1; -inline bool ServiceDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void ServiceDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void ServiceDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* ServiceDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// repeated .google.protobuf.MethodDescriptorProto method = 2; -inline int ServiceDescriptorProto::method_size() const { - return method_.size(); -} -inline void ServiceDescriptorProto::clear_method() { - method_.Clear(); -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& -ServiceDescriptorProto::method() const { - return method_; -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* -ServiceDescriptorProto::mutable_method() { - return &method_; -} -inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { - return method_.Get(index); -} -inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) { - return method_.Mutable(index); -} -inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() { - return method_.Add(); -} - -// optional .google.protobuf.ServiceOptions options = 3; -inline bool ServiceDescriptorProto::has_options() const { - return _has_bit(2); -} -inline void ServiceDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); - _clear_bit(2); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// MethodDescriptorProto - -// optional string name = 1; -inline bool MethodDescriptorProto::has_name() const { - return _has_bit(0); -} -inline void MethodDescriptorProto::clear_name() { - if (name_ != &_default_name_) { - name_->clear(); - } - _clear_bit(0); -} -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_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline void MethodDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - name_->assign(value); -} -inline ::std::string* MethodDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { - name_ = new ::std::string; - } - return name_; -} - -// optional string input_type = 2; -inline bool MethodDescriptorProto::has_input_type() const { - return _has_bit(1); -} -inline void MethodDescriptorProto::clear_input_type() { - if (input_type_ != &_default_input_type_) { - input_type_->clear(); - } - _clear_bit(1); -} -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_) { - 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_) { - input_type_ = new ::std::string; - } - input_type_->assign(value); -} -inline ::std::string* MethodDescriptorProto::mutable_input_type() { - _set_bit(1); - if (input_type_ == &_default_input_type_) { - input_type_ = new ::std::string; - } - return input_type_; -} - -// optional string output_type = 3; -inline bool MethodDescriptorProto::has_output_type() const { - return _has_bit(2); -} -inline void MethodDescriptorProto::clear_output_type() { - if (output_type_ != &_default_output_type_) { - output_type_->clear(); - } - _clear_bit(2); -} -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_) { - 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_) { - output_type_ = new ::std::string; - } - output_type_->assign(value); -} -inline ::std::string* MethodDescriptorProto::mutable_output_type() { - _set_bit(2); - if (output_type_ == &_default_output_type_) { - output_type_ = new ::std::string; - } - return output_type_; -} - -// optional .google.protobuf.MethodOptions options = 4; -inline bool MethodDescriptorProto::has_options() const { - return _has_bit(3); -} -inline void MethodDescriptorProto::clear_options() { - if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); - _clear_bit(3); -} -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); - if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions; - return options_; -} - -// ------------------------------------------------------------------- - -// FileOptions - -// optional string java_package = 1; -inline bool FileOptions::has_java_package() const { - return _has_bit(0); -} -inline void FileOptions::clear_java_package() { - if (java_package_ != &_default_java_package_) { - java_package_->clear(); - } - _clear_bit(0); -} -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_) { - 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_) { - java_package_ = new ::std::string; - } - java_package_->assign(value); -} -inline ::std::string* FileOptions::mutable_java_package() { - _set_bit(0); - if (java_package_ == &_default_java_package_) { - java_package_ = new ::std::string; - } - return java_package_; -} - -// optional string java_outer_classname = 8; -inline bool FileOptions::has_java_outer_classname() const { - return _has_bit(1); -} -inline void FileOptions::clear_java_outer_classname() { - if (java_outer_classname_ != &_default_java_outer_classname_) { - java_outer_classname_->clear(); - } - _clear_bit(1); -} -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_) { - 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_) { - java_outer_classname_ = new ::std::string; - } - java_outer_classname_->assign(value); -} -inline ::std::string* FileOptions::mutable_java_outer_classname() { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { - java_outer_classname_ = new ::std::string; - } - return java_outer_classname_; -} - -// optional bool java_multiple_files = 10 [default = false]; -inline bool FileOptions::has_java_multiple_files() const { - return _has_bit(2); -} -inline void FileOptions::clear_java_multiple_files() { - java_multiple_files_ = false; - _clear_bit(2); -} -inline bool FileOptions::java_multiple_files() const { - return java_multiple_files_; -} -inline void FileOptions::set_java_multiple_files(bool value) { - _set_bit(2); - java_multiple_files_ = value; -} - -// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = CODE_SIZE]; -inline bool FileOptions::has_optimize_for() const { - return _has_bit(3); -} -inline void FileOptions::clear_optimize_for() { - optimize_for_ = 2; - _clear_bit(3); -} -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); - optimize_for_ = value; -} - -// optional string csharp_namespace = 1000; -inline bool FileOptions::has_csharp_namespace() const { - return _has_bit(4); -} -inline void FileOptions::clear_csharp_namespace() { - if (csharp_namespace_ != &_default_csharp_namespace_) { - csharp_namespace_->clear(); - } - _clear_bit(4); -} -inline const ::std::string& FileOptions::csharp_namespace() const { - return *csharp_namespace_; -} -inline void FileOptions::set_csharp_namespace(const ::std::string& value) { - _set_bit(4); - if (csharp_namespace_ == &_default_csharp_namespace_) { - csharp_namespace_ = new ::std::string; - } - csharp_namespace_->assign(value); -} -inline void FileOptions::set_csharp_namespace(const char* value) { - _set_bit(4); - if (csharp_namespace_ == &_default_csharp_namespace_) { - csharp_namespace_ = new ::std::string; - } - csharp_namespace_->assign(value); -} -inline ::std::string* FileOptions::mutable_csharp_namespace() { - _set_bit(4); - if (csharp_namespace_ == &_default_csharp_namespace_) { - csharp_namespace_ = new ::std::string; - } - return csharp_namespace_; -} - -// optional string csharp_file_classname = 1001; -inline bool FileOptions::has_csharp_file_classname() const { - return _has_bit(5); -} -inline void FileOptions::clear_csharp_file_classname() { - if (csharp_file_classname_ != &_default_csharp_file_classname_) { - csharp_file_classname_->clear(); - } - _clear_bit(5); -} -inline const ::std::string& FileOptions::csharp_file_classname() const { - return *csharp_file_classname_; -} -inline void FileOptions::set_csharp_file_classname(const ::std::string& value) { - _set_bit(5); - if (csharp_file_classname_ == &_default_csharp_file_classname_) { - csharp_file_classname_ = new ::std::string; - } - csharp_file_classname_->assign(value); -} -inline void FileOptions::set_csharp_file_classname(const char* value) { - _set_bit(5); - if (csharp_file_classname_ == &_default_csharp_file_classname_) { - csharp_file_classname_ = new ::std::string; - } - csharp_file_classname_->assign(value); -} -inline ::std::string* FileOptions::mutable_csharp_file_classname() { - _set_bit(5); - if (csharp_file_classname_ == &_default_csharp_file_classname_) { - csharp_file_classname_ = new ::std::string; - } - return csharp_file_classname_; -} - -// optional bool csharp_multiple_files = 1002 [default = false]; -inline bool FileOptions::has_csharp_multiple_files() const { - return _has_bit(6); -} -inline void FileOptions::clear_csharp_multiple_files() { - csharp_multiple_files_ = false; - _clear_bit(6); -} -inline bool FileOptions::csharp_multiple_files() const { - return csharp_multiple_files_; -} -inline void FileOptions::set_csharp_multiple_files(bool value) { - _set_bit(6); - csharp_multiple_files_ = value; -} - -// optional bool csharp_nest_classes = 1003 [default = false]; -inline bool FileOptions::has_csharp_nest_classes() const { - return _has_bit(7); -} -inline void FileOptions::clear_csharp_nest_classes() { - csharp_nest_classes_ = false; - _clear_bit(7); -} -inline bool FileOptions::csharp_nest_classes() const { - return csharp_nest_classes_; -} -inline void FileOptions::set_csharp_nest_classes(bool value) { - _set_bit(7); - csharp_nest_classes_ = value; -} - -// optional bool csharp_public_classes = 1004 [default = true]; -inline bool FileOptions::has_csharp_public_classes() const { - return _has_bit(8); -} -inline void FileOptions::clear_csharp_public_classes() { - csharp_public_classes_ = true; - _clear_bit(8); -} -inline bool FileOptions::csharp_public_classes() const { - return csharp_public_classes_; -} -inline void FileOptions::set_csharp_public_classes(bool value) { - _set_bit(8); - csharp_public_classes_ = value; -} - -// ------------------------------------------------------------------- - -// MessageOptions - -// optional bool message_set_wire_format = 1 [default = false]; -inline bool MessageOptions::has_message_set_wire_format() const { - return _has_bit(0); -} -inline void MessageOptions::clear_message_set_wire_format() { - message_set_wire_format_ = false; - _clear_bit(0); -} -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); - message_set_wire_format_ = value; -} - -// ------------------------------------------------------------------- - -// FieldOptions - -// optional .google.protobuf.FieldOptions.CType ctype = 1; -inline bool FieldOptions::has_ctype() const { - return _has_bit(0); -} -inline void FieldOptions::clear_ctype() { - ctype_ = 1; - _clear_bit(0); -} -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); - ctype_ = value; -} - -// optional string experimental_map_key = 9; -inline bool FieldOptions::has_experimental_map_key() const { - return _has_bit(1); -} -inline void FieldOptions::clear_experimental_map_key() { - if (experimental_map_key_ != &_default_experimental_map_key_) { - experimental_map_key_->clear(); - } - _clear_bit(1); -} -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(1); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - experimental_map_key_->assign(value); -} -inline void FieldOptions::set_experimental_map_key(const char* value) { - _set_bit(1); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - experimental_map_key_->assign(value); -} -inline ::std::string* FieldOptions::mutable_experimental_map_key() { - _set_bit(1); - if (experimental_map_key_ == &_default_experimental_map_key_) { - experimental_map_key_ = new ::std::string; - } - return experimental_map_key_; -} - -// ------------------------------------------------------------------- - -// EnumOptions - -// ------------------------------------------------------------------- - -// EnumValueOptions - -// ------------------------------------------------------------------- - -// ServiceOptions - -// ------------------------------------------------------------------- - -// MethodOptions - - -} // namespace protobuf -} // namespace google -#endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto deleted file mode 100644 index 51ad6e9a..00000000 --- a/src/google/protobuf/descriptor.proto +++ /dev/null @@ -1,329 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// The messages in this file describe the definitions found in .proto files. -// A valid .proto file can be translated directly to a FileDescriptorProto -// without any other information (e.g. without reading its imports). - - - -package google.protobuf; -option java_package = "com.google.protobuf"; -option java_outer_classname = "DescriptorProtos"; - -option csharp_namespace = "Google.ProtocolBuffers.DescriptorProtos"; -option csharp_file_classname = "DescriptorProtoFile"; -option csharp_multiple_files = false; -option csharp_nest_classes = false; -option csharp_public_classes = true; - -// descriptor.proto must be optimized for speed because reflection-based -// algorithms don't work during bootstrapping. -option optimize_for = SPEED; - -// The protocol compiler can output a FileDescriptorSet containing the .proto -// files it parses. -message FileDescriptorSet { - repeated FileDescriptorProto file = 1; -} - -// Describes a complete .proto file. -message FileDescriptorProto { - optional string name = 1; // file name, relative to root of source tree - optional string package = 2; // e.g. "foo", "foo.bar", etc. - - // Names of files imported by this file. - repeated string dependency = 3; - - // All top-level definitions in this file. - repeated DescriptorProto message_type = 4; - repeated EnumDescriptorProto enum_type = 5; - repeated ServiceDescriptorProto service = 6; - repeated FieldDescriptorProto extension = 7; - - optional FileOptions options = 8; -} - -// Describes a message type. -message DescriptorProto { - optional string name = 1; - - repeated FieldDescriptorProto field = 2; - repeated FieldDescriptorProto extension = 6; - - repeated DescriptorProto nested_type = 3; - repeated EnumDescriptorProto enum_type = 4; - - message ExtensionRange { - optional int32 start = 1; - optional int32 end = 2; - } - repeated ExtensionRange extension_range = 5; - - optional MessageOptions options = 7; -} - -// Describes a field within a message. -message FieldDescriptorProto { - enum Type { - // 0 is reserved for errors. - // Order is weird for historical reasons. - TYPE_DOUBLE = 1; - TYPE_FLOAT = 2; - TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4; - TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6; - TYPE_FIXED32 = 7; - TYPE_BOOL = 8; - TYPE_STRING = 9; - TYPE_GROUP = 10; // Tag-delimited aggregate. - TYPE_MESSAGE = 11; // Length-delimited aggregate. - - // New in version 2. - TYPE_BYTES = 12; - TYPE_UINT32 = 13; - TYPE_ENUM = 14; - TYPE_SFIXED32 = 15; - TYPE_SFIXED64 = 16; - TYPE_SINT32 = 17; // Uses ZigZag encoding. - TYPE_SINT64 = 18; // Uses ZigZag encoding. - }; - - enum Label { - // 0 is reserved for errors - LABEL_OPTIONAL = 1; - LABEL_REQUIRED = 2; - LABEL_REPEATED = 3; - // TODO(sanjay): Should we add LABEL_MAP? - }; - - optional string name = 1; - optional int32 number = 3; - optional Label label = 4; - - // If type_name is set, this need not be set. If both this and type_name - // are set, this must be either TYPE_ENUM or TYPE_MESSAGE. - optional Type type = 5; - - // For message and enum types, this is the name of the type. If the name - // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping - // rules are used to find the type (i.e. first the nested types within this - // message are searched, then within the parent, on up to the root - // namespace). - optional string type_name = 6; - - // For extensions, this is the name of the type being extended. It is - // resolved in the same manner as type_name. - optional string extendee = 2; - - // For numeric types, contains the original text representation of the value. - // For booleans, "true" or "false". - // For strings, contains the default text contents (not escaped in any way). - // For bytes, contains the C escaped value. All bytes >= 128 are escaped. - // TODO(kenton): Base-64 encode? - optional string default_value = 7; - - optional FieldOptions options = 8; -} - -// Describes an enum type. -message EnumDescriptorProto { - optional string name = 1; - - repeated EnumValueDescriptorProto value = 2; - - optional EnumOptions options = 3; -} - -// Describes a value within an enum. -message EnumValueDescriptorProto { - optional string name = 1; - optional int32 number = 2; - - optional EnumValueOptions options = 3; -} - -// Describes a service. -message ServiceDescriptorProto { - optional string name = 1; - repeated MethodDescriptorProto method = 2; - - optional ServiceOptions options = 3; -} - -// Describes a method of a service. -message MethodDescriptorProto { - optional string name = 1; - - // Input and output type names. These are resolved in the same way as - // FieldDescriptorProto.type_name, but must refer to a message type. - optional string input_type = 2; - optional string output_type = 3; - - optional MethodOptions options = 4; -} - -// =================================================================== -// Options - -// Each of the definitions above may have "options" attached. These are -// just annotations which may cause code to be generated slightly differently -// or may contain hints for code that manipulates protocol messages. - -// TODO(kenton): Allow extensions to options. - -message FileOptions { - - // Sets the Java package where classes generated from this .proto will be - // placed. By default, the proto package is used, but this is often - // inappropriate because proto packages do not normally start with backwards - // domain names. - optional string java_package = 1; - - - // If set, all the classes from the .proto file are wrapped in a single - // outer class with the given name. This applies to both Proto1 - // (equivalent to the old "--one_java_file" option) and Proto2 (where - // a .proto always translates to a single class, but you may want to - // explicitly choose the class name). - optional string java_outer_classname = 8; - - // If set true, then the Java code generator will generate a separate .java - // file for each top-level message, enum, and service defined in the .proto - // file. Thus, these types will *not* be nested inside the outer class - // named by java_outer_classname. However, the outer class will still be - // generated to contain the file's getDescriptor() method as well as any - // top-level extensions defined in the file. - optional bool java_multiple_files = 10 [default=false]; - - // Generated classes can be optimized for speed or code size. - enum OptimizeMode { - SPEED = 1; // Generate complete code for parsing, serialization, etc. - CODE_SIZE = 2; // Use ReflectionOps to implement these methods. - } - optional OptimizeMode optimize_for = 9 [default=CODE_SIZE]; - - - // C# stuff... generalise to .NET? - // Sets the namespace where classes generated from this .proto will be - // placed. By default, the proto package is used. Unlike the Java - // generator, the C# generator does *not* create a directory structure - // based on the namespace. - optional string csharp_namespace = 1000; - - // One class is generated to represent the .proto file as a whole. - // It contains the file's descriptor as well as any top-level - // extensions. - optional string csharp_file_classname = 1001; - - // If set true, the C# generator will generate a separate .cs file - // for each top-level message, enum and service defined in the .proto - // file. Otherwise, a single .cs file will be generated. - optional bool csharp_multiple_files = 1002 [default=false]; - - // If set true, the C# generator will use the "whole .proto file" class - // as a container for all the other classes. This value is independent - // of csharp_multiple_files - using partial types, the C# generator - // can still nest classes even when generating multiple files, - // and C# allows multiple public top-level classes in the same - // file. - optional bool csharp_nest_classes = 1003 [default=false]; - - // If set true, the C# generator will make all its generated classes - // public. If set false, classes will be internal (i.e. only - // visible within the same assembly). - optional bool csharp_public_classes = 1004 [default=true]; -} - -message MessageOptions { - // Set true to use the old proto1 MessageSet wire format for extensions. - // This is provided for backwards-compatibility with the MessageSet wire - // format. You should not use this for any other reason: It's less - // efficient, has fewer features, and is more complicated. - // - // The message must be defined exactly as follows: - // message Foo { - // option message_set_wire_format = true; - // extensions 4 to max; - // } - // Note that the message cannot have any defined fields; MessageSets only - // have extensions. - // - // All extensions of your type must be singular messages; e.g. they cannot - // be int32s, enums, or repeated messages. - // - // Because this is an option, the above two restrictions are not enforced by - // the protocol compiler. - optional bool message_set_wire_format = 1 [default=false]; -} - -message FieldOptions { - // The ctype option instructs the C++ code generator to use a different - // representation of the field than it normally would. See the specific - // options below. This option is not yet implemented in the open source - // release -- sorry, we'll try to include it in a future version! - optional CType ctype = 1; - enum CType { - CORD = 1; - - STRING_PIECE = 2; - } - - // EXPERIMENTAL. DO NOT USE. - // For "map" fields, the name of the field in the enclosed type that - // is the key for this map. For example, suppose we have: - // message Item { - // required string name = 1; - // required string value = 2; - // } - // message Config { - // repeated Item items = 1 [experimental_map_key="name"]; - // } - // In this situation, the map key for Item will be set to "name". - // TODO: Fully-implement this, then remove the "experimental_" prefix. - optional string experimental_map_key = 9; -} - -message EnumOptions { -} - -message EnumValueOptions { -} - -message ServiceOptions { - - // Note: Field numbers 1 through 32 are reserved for Google's internal RPC - // framework. We apologize for hoarding these numbers to ourselves, but - // we were already using them long before we decided to release Protocol - // Buffers. -} - -message MethodOptions { - - // Note: Field numbers 1 through 32 are reserved for Google's internal RPC - // framework. We apologize for hoarding these numbers to ourselves, but - // we were already using them long before we decided to release Protocol - // Buffers. -} diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc deleted file mode 100644 index 944280c0..00000000 --- a/src/google/protobuf/descriptor_database.cc +++ /dev/null @@ -1,291 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/stl_util-inl.h> -#include <google/protobuf/stubs/map-util.h> - -namespace google { -namespace protobuf { - -DescriptorDatabase::~DescriptorDatabase() {} - -// =================================================================== - -SimpleDescriptorDatabase::SimpleDescriptorDatabase() {} -SimpleDescriptorDatabase::~SimpleDescriptorDatabase() { - STLDeleteElements(&files_to_delete_); -} - -void SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) { - FileDescriptorProto* new_file = new FileDescriptorProto; - new_file->CopyFrom(file); - AddAndOwn(new_file); -} - -void SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) { - files_to_delete_.push_back(file); - InsertOrUpdate(&files_by_name_, file->name(), file); - - string path = file->package(); - if (!path.empty()) path += '.'; - - for (int i = 0; i < file->message_type_size(); i++) { - AddMessage(path, file->message_type(i), file); - } - for (int i = 0; i < file->enum_type_size(); i++) { - AddEnum(path, file->enum_type(i), file); - } - for (int i = 0; i < file->extension_size(); i++) { - AddField(path, file->extension(i), file); - } - for (int i = 0; i < file->service_size(); i++) { - AddService(path, file->service(i), file); - } -} - -void SimpleDescriptorDatabase::AddMessage( - const string& path, - const DescriptorProto& message_type, - const FileDescriptorProto* file) { - string full_name = path + message_type.name(); - InsertOrUpdate(&files_by_symbol_, full_name, file); - - string sub_path = full_name + '.'; - for (int i = 0; i < message_type.nested_type_size(); i++) { - AddMessage(sub_path, message_type.nested_type(i), file); - } - for (int i = 0; i < message_type.enum_type_size(); i++) { - AddEnum(sub_path, message_type.enum_type(i), file); - } - for (int i = 0; i < message_type.field_size(); i++) { - AddField(sub_path, message_type.field(i), file); - } - for (int i = 0; i < message_type.extension_size(); i++) { - AddField(sub_path, message_type.extension(i), file); - } -} - -void SimpleDescriptorDatabase::AddField( - const string& path, - const FieldDescriptorProto& field, - const FileDescriptorProto* file) { - string full_name = path + field.name(); - InsertOrUpdate(&files_by_symbol_, full_name, file); - - if (field.has_extendee()) { - // This field is an extension. - if (!field.extendee().empty() && field.extendee()[0] == '.') { - // The extension is fully-qualified. We can use it as a lookup key in - // the files_by_symbol_ table. - InsertOrUpdate(&files_by_extension_, - make_pair(field.extendee().substr(1), field.number()), - file); - } else { - // Not fully-qualified. We can't really do anything here, unfortunately. - } - } -} - -void SimpleDescriptorDatabase::AddEnum( - const string& path, - const EnumDescriptorProto& enum_type, - const FileDescriptorProto* file) { - string full_name = path + enum_type.name(); - InsertOrUpdate(&files_by_symbol_, full_name, file); - - string sub_path = full_name + '.'; - for (int i = 0; i < enum_type.value_size(); i++) { - InsertOrUpdate(&files_by_symbol_, - sub_path + enum_type.value(i).name(), - file); - } -} - -void SimpleDescriptorDatabase::AddService( - const string& path, - const ServiceDescriptorProto& service, - const FileDescriptorProto* file) { - string full_name = path + service.name(); - InsertOrUpdate(&files_by_symbol_, full_name, file); - - string sub_path = full_name + '.'; - for (int i = 0; i < service.method_size(); i++) { - InsertOrUpdate(&files_by_symbol_, - sub_path + service.method(i).name(), - file); - } -} - -bool SimpleDescriptorDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - const FileDescriptorProto* result = FindPtrOrNull(files_by_name_, filename); - if (result == NULL) { - return false; - } else { - output->CopyFrom(*result); - return true; - } -} - -bool SimpleDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - const FileDescriptorProto* result = - FindPtrOrNull(files_by_symbol_, symbol_name); - if (result == NULL) { - return false; - } else { - output->CopyFrom(*result); - return true; - } -} - -bool SimpleDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - const FileDescriptorProto* result = - FindPtrOrNull(files_by_extension_, - make_pair(containing_type, field_number)); - if (result == NULL) { - return false; - } else { - output->CopyFrom(*result); - return true; - } -} - -// =================================================================== - -DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool) - : pool_(pool) {} -DescriptorPoolDatabase::~DescriptorPoolDatabase() {} - -bool DescriptorPoolDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - const FileDescriptor* file = pool_.FindFileByName(filename); - if (file == NULL) return false; - output->Clear(); - file->CopyTo(output); - return true; -} - -bool DescriptorPoolDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name); - if (file == NULL) return false; - output->Clear(); - file->CopyTo(output); - return true; -} - -bool DescriptorPoolDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type); - if (extendee == NULL) return false; - - const FieldDescriptor* extension = - pool_.FindExtensionByNumber(extendee, field_number); - if (extension == NULL) return false; - - output->Clear(); - extension->file()->CopyTo(output); - return true; -} - -// =================================================================== - -MergedDescriptorDatabase::MergedDescriptorDatabase( - DescriptorDatabase* source1, - DescriptorDatabase* source2) { - sources_.push_back(source1); - sources_.push_back(source2); -} -MergedDescriptorDatabase::MergedDescriptorDatabase( - const vector<DescriptorDatabase*>& sources) - : sources_(sources) {} -MergedDescriptorDatabase::~MergedDescriptorDatabase() {} - -bool MergedDescriptorDatabase::FindFileByName( - const string& filename, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileByName(filename, output)) { - return true; - } - } - return false; -} - -bool MergedDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { - // The symbol was found in source i. However, if one of the previous - // sources defines a file with the same name (which presumably doesn't - // contain the symbol, since it wasn't found in that source), then we - // must hide it from the caller. - FileDescriptorProto temp; - for (int j = 0; j < i; j++) { - if (sources_[j]->FindFileByName(output->name(), &temp)) { - // Found conflicting file in a previous source. - return false; - } - } - return true; - } - } - return false; -} - -bool MergedDescriptorDatabase::FindFileContainingExtension( - const string& containing_type, - int field_number, - FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileContainingExtension( - containing_type, field_number, output)) { - // The symbol was found in source i. However, if one of the previous - // sources defines a file with the same name (which presumably doesn't - // contain the symbol, since it wasn't found in that source), then we - // must hide it from the caller. - FileDescriptorProto temp; - for (int j = 0; j < i; j++) { - if (sources_[j]->FindFileByName(output->name(), &temp)) { - // Found conflicting file in a previous source. - return false; - } - } - return true; - } - } - return false; -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h deleted file mode 100644 index d629da4c..00000000 --- a/src/google/protobuf/descriptor_database.h +++ /dev/null @@ -1,183 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Interface for manipulating databases of descriptors. - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ -#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ - -#include <map> -#include <string> -#include <utility> -#include <vector> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - -// Abstract interface for a database of descriptors. -// -// This is useful if you want to create a DescriptorPool which loads -// descriptors on-demand from some sort of large database. If the database -// is large, it may be inefficient to enumerate every .proto file inside it -// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool -// can be created which wraps a DescriptorDatabase and only builds particular -// descriptors when they are needed. -class LIBPROTOBUF_EXPORT DescriptorDatabase { - public: - inline DescriptorDatabase() {} - virtual ~DescriptorDatabase(); - - // Find a file by file name. Fills in in *output and returns true if found. - // Otherwise, returns false, leaving the contents of *output undefined. - virtual bool FindFileByName(const string& filename, - FileDescriptorProto* output) = 0; - - // Find the file that declares the given fully-qualified symbol name. - // If found, fills in *output and returns true, otherwise returns false - // and leaves *output undefined. - virtual bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) = 0; - - // Find the file which defines an extension extending the given message type - // with the given field number. If found, fills in *output and returns true, - // otherwise returns false and leaves *output undefined. containing_type - // must be a fully-qualified type name. - virtual bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); -}; - -// A DescriptorDatabase into which you can insert files manually. -// -// FindFileContainingSymbol() is fully-implemented. When you add a file, its -// symbols will be indexed for this purpose. -// -// FindFileContainingExtension() is mostly-implemented. It works if and only -// if the original FieldDescriptorProto defining the extension has a -// fully-qualified type name in its "extendee" field (i.e. starts with a '.'). -// If the extendee is a relative name, SimpleDescriptorDatabase will not -// attempt to resolve the type, so it will not know what type the extension is -// extending. Therefore, calling FindFileContainingExtension() with the -// extension's containing type will never actually find that extension. Note -// that this is an unlikely problem, as all FileDescriptorProtos created by the -// protocol compiler (as well as ones created by calling -// FileDescriptor::CopyTo()) will always use fully-qualified names for all -// types. You only need to worry if you are constructing FileDescriptorProtos -// yourself, or are calling compiler::Parser directly. -class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { - public: - SimpleDescriptorDatabase(); - ~SimpleDescriptorDatabase(); - - // Adds the FileDescriptorProto to the database, making a copy. The object - // can be deleted after Add() returns. - void Add(const FileDescriptorProto& file); - - // Adds the FileDescriptorProto to the database and takes ownership of it. - void AddAndOwn(const FileDescriptorProto* file); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - - private: - // Helpers to recursively add particular descriptors and all their contents - // to the by-symbol and by-extension tables. - void AddMessage(const string& path, - const DescriptorProto& message_type, - const FileDescriptorProto* file); - void AddField(const string& path, - const FieldDescriptorProto& field, - const FileDescriptorProto* file); - void AddEnum(const string& path, - const EnumDescriptorProto& enum_type, - const FileDescriptorProto* file); - void AddService(const string& path, - const ServiceDescriptorProto& service, - const FileDescriptorProto* file); - - vector<const FileDescriptorProto*> files_to_delete_; - map<string, const FileDescriptorProto*> files_by_name_; - map<string, const FileDescriptorProto*> files_by_symbol_; - map<pair<string, int>, const FileDescriptorProto*> files_by_extension_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase); -}; - -// A DescriptorDatabase that fetches files from a given pool. -class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { - public: - DescriptorPoolDatabase(const DescriptorPool& pool); - ~DescriptorPoolDatabase(); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - - private: - const DescriptorPool& pool_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase); -}; - -// A DescriptorDatabase that wraps two or more others. It first searches the -// first database and, if that fails, tries the second, and so on. -class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { - public: - // Merge just two databases. The sources remain property of the caller. - MergedDescriptorDatabase(DescriptorDatabase* source1, - DescriptorDatabase* source2); - // Merge more than two databases. The sources remain property of the caller. - // The vector may be deleted after the constructor returns but the - // DescriptorDatabases need to stick around. - MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources); - ~MergedDescriptorDatabase(); - - // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output); - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output); - - private: - vector<DescriptorDatabase*> sources_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__ diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc deleted file mode 100644 index cbbf5927..00000000 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ /dev/null @@ -1,601 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file makes extensive use of RFC 3092. :) - -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/stubs/strutil.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace { - -static bool AddToPool(DescriptorPool* pool, const char* file_text) { - FileDescriptorProto file_proto; - if (!TextFormat::ParseFromString(file_text, &file_proto)) return false; - if (pool->BuildFile(file_proto) == NULL) return false; - return true; -} - -static void AddToDatabase(SimpleDescriptorDatabase* database, - const char* file_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - database->Add(file_proto); -} - -static void ExpectContainsType(const FileDescriptorProto& proto, - const string& type_name) { - for (int i = 0; i < proto.message_type_size(); i++) { - if (proto.message_type(i).name() == type_name) return; - } - ADD_FAILURE() << "\"" << proto.name() - << "\" did not contain expected type \"" - << type_name << "\"."; -} - -// =================================================================== - -TEST(SimpleDescriptorDatabaseTest, FindFileByName) { - SimpleDescriptorDatabase database; - AddToDatabase(&database, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" }"); - AddToDatabase(&database, - "name: \"bar.proto\" " - "message_type { name:\"Bar\" }"); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileByName("foo.proto", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileByName("bar.proto", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // Fails to find undefined files. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileByName("baz.proto", &file)); - } -} - -TEST(SimpleDescriptorDatabaseTest, FindFileContainingSymbol) { - SimpleDescriptorDatabase database; - AddToDatabase(&database, - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " field { name:\"qux\" }" - " nested_type { name: \"Grault\" } " - " enum_type { name: \"Garply\" } " - "} " - "enum_type { " - " name: \"Waldo\" " - " value { name:\"FRED\" } " - "} " - "extension { name: \"plugh\" } " - "service { " - " name: \"Xyzzy\" " - " method { name: \"Thud\" } " - "}" - ); - AddToDatabase(&database, - "name: \"bar.proto\" " - "package: \"corge\" " - "message_type { name: \"Bar\" }"); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find fields. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo.qux", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find nested types. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo.Grault", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find nested enums. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo.Garply", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find enum types. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Waldo", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find enum values. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Waldo.FRED", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find extensions. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("plugh", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find services. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Xyzzy", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find methods. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Xyzzy.Thud", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find things in packages. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("corge.Bar", &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Fails to find undefined symbols. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingSymbol("Baz", &file)); - } - - { - // Names must be fully-qualified. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingSymbol("Bar", &file)); - } -} - -TEST(SimpleDescriptorDatabaseTest, FindFileContainingExtension) { - SimpleDescriptorDatabase database; - AddToDatabase(&database, - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " extension_range { start: 1 end: 1000 } " - " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \".Foo\" }" - "}"); - AddToDatabase(&database, - "name: \"bar.proto\" " - "package: \"corge\" " - "dependency: \"foo.proto\" " - "message_type { " - " name: \"Bar\" " - " extension_range { start: 1 end: 1000 } " - "} " - "extension { name:\"grault\" extendee: \".Foo\" number:32 } " - "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } " - "extension { name:\"waldo\" extendee: \"Bar\" number:56 } "); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("Foo", 5, &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("Foo", 32, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can find extensions for qualified type names. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("corge.Bar", 70, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can't find extensions whose extendee was not fully-qualified in the - // FileDescriptorProto. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("Bar", 56, &file)); - EXPECT_FALSE(database.FindFileContainingExtension("corge.Bar", 56, &file)); - } - - { - // Can't find non-existent extension numbers. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("Foo", 12, &file)); - } - - { - // Can't find extensions for non-existent types. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("NoSuchType", 5, &file)); - } - - { - // Can't find extensions for unqualified type names. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("Bar", 70, &file)); - } -} - -// =================================================================== - -TEST(DescriptorPoolDatabaseTest, FindFileByName) { - DescriptorPool pool; - ASSERT_TRUE(AddToPool(&pool, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" }")); - ASSERT_TRUE(AddToPool(&pool, - "name: \"bar.proto\" " - "message_type { name:\"Bar\" }")); - - DescriptorPoolDatabase database(pool); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileByName("foo.proto", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileByName("bar.proto", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // Fails to find undefined files. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileByName("baz.proto", &file)); - } -} - -TEST(DescriptorPoolDatabaseTest, FindFileContainingSymbol) { - DescriptorPool pool; - ASSERT_TRUE(AddToPool(&pool, - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " field { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "}")); - ASSERT_TRUE(AddToPool(&pool, - "name: \"bar.proto\" " - "package: \"corge\" " - "message_type { name: \"Bar\" }")); - - DescriptorPoolDatabase database(pool); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find fields. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("Foo.qux", &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - // Can find things in packages. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingSymbol("corge.Bar", &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Fails to find undefined symbols. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingSymbol("Baz", &file)); - } - - { - // Names must be fully-qualified. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingSymbol("Bar", &file)); - } -} - -TEST(DescriptorPoolDatabaseTest, FindFileContainingExtension) { - DescriptorPool pool; - ASSERT_TRUE(AddToPool(&pool, - "name: \"foo.proto\" " - "message_type { " - " name: \"Foo\" " - " extension_range { start: 1 end: 1000 } " - " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 " - " extendee: \"Foo\" }" - "}")); - ASSERT_TRUE(AddToPool(&pool, - "name: \"bar.proto\" " - "package: \"corge\" " - "dependency: \"foo.proto\" " - "message_type { " - " name: \"Bar\" " - " extension_range { start: 1 end: 1000 } " - "} " - "extension { name:\"grault\" label:LABEL_OPTIONAL type:TYPE_BOOL number:32 " - " extendee: \"Foo\" } " - "extension { name:\"garply\" label:LABEL_OPTIONAL type:TYPE_BOOL number:70 " - " extendee: \"Bar\" } ")); - - DescriptorPoolDatabase database(pool); - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("Foo", 5, &file)); - EXPECT_EQ("foo.proto", file.name()); - } - - { - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("Foo", 32, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can find extensions for qualified type names.. - FileDescriptorProto file; - EXPECT_TRUE(database.FindFileContainingExtension("corge.Bar", 70, &file)); - EXPECT_EQ("bar.proto", file.name()); - } - - { - // Can't find non-existent extension numbers. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("Foo", 12, &file)); - } - - { - // Can't find extensions for non-existent types. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("NoSuchType", 5, &file)); - } - - { - // Can't find extensions for unqualified type names. - FileDescriptorProto file; - EXPECT_FALSE(database.FindFileContainingExtension("Bar", 70, &file)); - } -} - -// =================================================================== - -class MergedDescriptorDatabaseTest : public testing::Test { - protected: - MergedDescriptorDatabaseTest() - : forward_merged_(&database1_, &database2_), - reverse_merged_(&database2_, &database1_) {} - - virtual void SetUp() { - AddToDatabase(&database1_, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } " - "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - AddToDatabase(&database2_, - "name: \"bar.proto\" " - "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } " - "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - - // baz.proto exists in both pools, with different definitions. - AddToDatabase(&database1_, - "name: \"baz.proto\" " - "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " - "message_type { name:\"FromPool1\" } " - "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } " - "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - AddToDatabase(&database2_, - "name: \"baz.proto\" " - "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } " - "message_type { name:\"FromPool2\" } " - "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - } - - SimpleDescriptorDatabase database1_; - SimpleDescriptorDatabase database2_; - - MergedDescriptorDatabase forward_merged_; - MergedDescriptorDatabase reverse_merged_; -}; - -TEST_F(MergedDescriptorDatabaseTest, FindFileByName) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // Can't find non-existent file. - FileDescriptorProto file; - EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file)); - } -} - -TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // FromPool1 only shows up in forward_merged_ because it is masked by - // database2_'s baz.proto in reverse_merged_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file)); - EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file)); - } - - { - // Can't find non-existent symbol. - FileDescriptorProto file; - EXPECT_FALSE( - forward_merged_.FindFileContainingSymbol("NoSuchType", &file)); - } -} - -TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) { - { - // Can find file that is only in database1_. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Foo", 3, &file)); - EXPECT_EQ("foo.proto", file.name()); - ExpectContainsType(file, "Foo"); - } - - { - // Can find file that is only in database2_. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Bar", 5, &file)); - EXPECT_EQ("bar.proto", file.name()); - ExpectContainsType(file, "Bar"); - } - - { - // In forward_merged_, database1_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE( - forward_merged_.FindFileContainingExtension("Baz", 12, &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool1"); - } - - { - // In reverse_merged_, database2_'s baz.proto takes precedence. - FileDescriptorProto file; - EXPECT_TRUE( - reverse_merged_.FindFileContainingExtension("Baz", 12, &file)); - EXPECT_EQ("baz.proto", file.name()); - ExpectContainsType(file, "FromPool2"); - } - - { - // Baz's extension 13 only shows up in forward_merged_ because it is - // masked by database2_'s baz.proto in reverse_merged_. - FileDescriptorProto file; - EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file)); - EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file)); - } - - { - // Can't find non-existent extension. - FileDescriptorProto file; - EXPECT_FALSE( - forward_merged_.FindFileContainingExtension("Foo", 6, &file)); - } -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc deleted file mode 100644 index 25d6040d..00000000 --- a/src/google/protobuf/descriptor_unittest.cc +++ /dev/null @@ -1,2661 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file makes extensive use of RFC 3092. :) - -#include <vector> - -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor_database.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -namespace { - -// Some helpers to make assembling descriptors faster. -DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) { - DescriptorProto* result = file->add_message_type(); - result->set_name(name); - return result; -} - -DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) { - DescriptorProto* result = parent->add_nested_type(); - result->set_name(name); - return result; -} - -EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) { - EnumDescriptorProto* result = file->add_enum_type(); - result->set_name(name); - return result; -} - -EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent, - const string& name) { - EnumDescriptorProto* result = parent->add_enum_type(); - result->set_name(name); - return result; -} - -ServiceDescriptorProto* AddService(FileDescriptorProto* file, - const string& name) { - ServiceDescriptorProto* result = file->add_service(); - result->set_name(name); - return result; -} - -FieldDescriptorProto* AddField(DescriptorProto* parent, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = parent->add_field(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - return result; -} - -FieldDescriptorProto* AddExtension(FileDescriptorProto* file, - const string& extendee, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = file->add_extension(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - result->set_extendee(extendee); - return result; -} - -FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent, - const string& extendee, - const string& name, int number, - FieldDescriptorProto::Label label, - FieldDescriptorProto::Type type) { - FieldDescriptorProto* result = parent->add_extension(); - result->set_name(name); - result->set_number(number); - result->set_label(label); - result->set_type(type); - result->set_extendee(extendee); - return result; -} - -DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent, - int start, int end) { - DescriptorProto::ExtensionRange* result = parent->add_extension_range(); - result->set_start(start); - result->set_end(end); - return result; -} - -EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto, - const string& name, int number) { - EnumValueDescriptorProto* result = enum_proto->add_value(); - result->set_name(name); - result->set_number(number); - return result; -} - -MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service, - const string& name, - const string& input_type, - const string& output_type) { - MethodDescriptorProto* result = service->add_method(); - result->set_name(name); - result->set_input_type(input_type); - result->set_output_type(output_type); - return result; -} - -// Empty enums technically aren't allowed. We need to insert a dummy value -// into them. -void AddEmptyEnum(FileDescriptorProto* file, const string& name) { - AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1); -} - -// =================================================================== - -// Test simple files. -class FileDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message FooMessage { extensions 1; } - // enum FooEnum {FOO_ENUM_VALUE = 1;} - // service FooService {} - // extend FooMessage { optional int32 foo_extension = 1; } - // - // // in "bar.proto" - // package bar_package; - // message BarMessage { extensions 1; } - // enum BarEnum {BAR_ENUM_VALUE = 1;} - // service BarService {} - // extend BarMessage { optional int32 bar_extension = 1; } - // - // Also, we have an empty file "baz.proto". This file's purpose is to - // make sure that even though it has the same package as foo.proto, - // searching it for members of foo.proto won't work. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2); - AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1); - AddService(&foo_file, "FooService"); - AddExtension(&foo_file, "FooMessage", "foo_extension", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("bar_package"); - bar_file.add_dependency("foo.proto"); - AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2); - AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1); - AddService(&bar_file, "BarService"); - AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FileDescriptorProto baz_file; - baz_file.set_name("baz.proto"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - baz_file_ = pool_.BuildFile(baz_file); - ASSERT_TRUE(baz_file_ != NULL); - - ASSERT_EQ(1, foo_file_->message_type_count()); - foo_message_ = foo_file_->message_type(0); - ASSERT_EQ(1, foo_file_->enum_type_count()); - foo_enum_ = foo_file_->enum_type(0); - ASSERT_EQ(1, foo_enum_->value_count()); - foo_enum_value_ = foo_enum_->value(0); - ASSERT_EQ(1, foo_file_->service_count()); - foo_service_ = foo_file_->service(0); - ASSERT_EQ(1, foo_file_->extension_count()); - foo_extension_ = foo_file_->extension(0); - - ASSERT_EQ(1, bar_file_->message_type_count()); - bar_message_ = bar_file_->message_type(0); - ASSERT_EQ(1, bar_file_->enum_type_count()); - bar_enum_ = bar_file_->enum_type(0); - ASSERT_EQ(1, bar_enum_->value_count()); - bar_enum_value_ = bar_enum_->value(0); - ASSERT_EQ(1, bar_file_->service_count()); - bar_service_ = bar_file_->service(0); - ASSERT_EQ(1, bar_file_->extension_count()); - bar_extension_ = bar_file_->extension(0); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - const FileDescriptor* baz_file_; - - const Descriptor* foo_message_; - const EnumDescriptor* foo_enum_; - const EnumValueDescriptor* foo_enum_value_; - const ServiceDescriptor* foo_service_; - const FieldDescriptor* foo_extension_; - - const Descriptor* bar_message_; - const EnumDescriptor* bar_enum_; - const EnumValueDescriptor* bar_enum_value_; - const ServiceDescriptor* bar_service_; - const FieldDescriptor* bar_extension_; -}; - -TEST_F(FileDescriptorTest, Name) { - EXPECT_EQ("foo.proto", foo_file_->name()); - EXPECT_EQ("bar.proto", bar_file_->name()); - EXPECT_EQ("baz.proto", baz_file_->name()); -} - -TEST_F(FileDescriptorTest, Package) { - EXPECT_EQ("", foo_file_->package()); - EXPECT_EQ("bar_package", bar_file_->package()); -} - -TEST_F(FileDescriptorTest, Dependencies) { - EXPECT_EQ(0, foo_file_->dependency_count()); - EXPECT_EQ(1, bar_file_->dependency_count()); - EXPECT_EQ(foo_file_, bar_file_->dependency(0)); -} - -TEST_F(FileDescriptorTest, FindMessageTypeByName) { - EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage")); - EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage")); - - EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL); - EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL); - EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL); - - EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL); - EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL); -} - -TEST_F(FileDescriptorTest, FindEnumTypeByName) { - EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum")); - EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum")); - - EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL); - EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL); - EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL); - - EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL); - EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindEnumValueByName) { - EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE")); - EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE")); - - EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL); - EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); - EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL); - - EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindServiceByName) { - EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService")); - EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService")); - - EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL); - EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL); - EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL); - - EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL); - EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindExtensionByName) { - EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension")); - EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension")); - - EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL); - EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL); - EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL); - - EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL); -} - -TEST_F(FileDescriptorTest, FindExtensionByNumber) { - EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1)); - EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1)); - - EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL); -} - -// =================================================================== - -// Test simple flat messages and fields. -class DescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message TestForeign {} - // enum TestEnum {} - // - // message TestMessage { - // required string foo = 1; - // optional TestEnum bar = 6; - // repeated TestForeign baz = 500000000; - // optional group qux = 15 {} - // } - // - // // in "bar.proto" - // package corge.grault; - // message TestMessage2 { - // required string foo = 1; - // required string bar = 2; - // required string quux = 6; - // } - // - // We cheat and use TestForeign as the type for qux rather than create - // an actual nested type. - // - // Since all primitive types (including string) use the same building - // code, there's no need to test each one individually. - // - // TestMessage2 is primarily here to test FindFieldByName and friends. - // All messages created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - AddMessage(&foo_file, "TestForeign"); - AddEmptyEnum(&foo_file, "TestEnum"); - - DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); - AddField(message, "foo", 1, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message, "bar", 6, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_ENUM) - ->set_type_name("TestEnum"); - AddField(message, "baz", 500000000, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_MESSAGE) - ->set_type_name("TestForeign"); - AddField(message, "qux", 15, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_GROUP) - ->set_type_name("TestForeign"); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); - AddField(message2, "foo", 1, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message2, "bar", 2, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - AddField(message2, "quux", 6, - FieldDescriptorProto::LABEL_REQUIRED, - FieldDescriptorProto::TYPE_STRING); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - enum_ = foo_file_->enum_type(0); - - ASSERT_EQ(2, foo_file_->message_type_count()); - foreign_ = foo_file_->message_type(0); - message_ = foo_file_->message_type(1); - - ASSERT_EQ(4, message_->field_count()); - foo_ = message_->field(0); - bar_ = message_->field(1); - baz_ = message_->field(2); - qux_ = message_->field(3); - - ASSERT_EQ(1, bar_file_->message_type_count()); - message2_ = bar_file_->message_type(0); - - ASSERT_EQ(3, message2_->field_count()); - foo2_ = message2_->field(0); - bar2_ = message2_->field(1); - quux2_ = message2_->field(2); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* message_; - const Descriptor* message2_; - const Descriptor* foreign_; - const EnumDescriptor* enum_; - - const FieldDescriptor* foo_; - const FieldDescriptor* bar_; - const FieldDescriptor* baz_; - const FieldDescriptor* qux_; - - const FieldDescriptor* foo2_; - const FieldDescriptor* bar2_; - const FieldDescriptor* quux2_; -}; - -TEST_F(DescriptorTest, Name) { - EXPECT_EQ("TestMessage", message_->name()); - EXPECT_EQ("TestMessage", message_->full_name()); - EXPECT_EQ(foo_file_, message_->file()); - - EXPECT_EQ("TestMessage2", message2_->name()); - EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name()); - EXPECT_EQ(bar_file_, message2_->file()); -} - -TEST_F(DescriptorTest, ContainingType) { - EXPECT_TRUE(message_->containing_type() == NULL); - EXPECT_TRUE(message2_->containing_type() == NULL); -} - -TEST_F(DescriptorTest, FieldsByIndex) { - ASSERT_EQ(4, message_->field_count()); - EXPECT_EQ(foo_, message_->field(0)); - EXPECT_EQ(bar_, message_->field(1)); - EXPECT_EQ(baz_, message_->field(2)); - EXPECT_EQ(qux_, message_->field(3)); -} - -TEST_F(DescriptorTest, FindFieldByName) { - // All messages in the same DescriptorPool share a single lookup table for - // fields. So, in addition to testing that FindFieldByName finds the fields - // of the message, we need to test that it does *not* find the fields of - // *other* messages. - - EXPECT_EQ(foo_, message_->FindFieldByName("foo")); - EXPECT_EQ(bar_, message_->FindFieldByName("bar")); - EXPECT_EQ(baz_, message_->FindFieldByName("baz")); - EXPECT_EQ(qux_, message_->FindFieldByName("qux")); - EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL); - EXPECT_TRUE(message_->FindFieldByName("quux") == NULL); - - EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" )); - EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" )); - EXPECT_EQ(quux2_, message2_->FindFieldByName("quux")); - EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL); - EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL); -} - -TEST_F(DescriptorTest, FindFieldByNumber) { - EXPECT_EQ(foo_, message_->FindFieldByNumber(1)); - EXPECT_EQ(bar_, message_->FindFieldByNumber(6)); - EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000)); - EXPECT_EQ(qux_, message_->FindFieldByNumber(15)); - EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL); - EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL); - - EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1)); - EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2)); - EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6)); - EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL); - EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL); -} - -TEST_F(DescriptorTest, FieldName) { - EXPECT_EQ("foo", foo_->name()); - EXPECT_EQ("bar", bar_->name()); - EXPECT_EQ("baz", baz_->name()); - EXPECT_EQ("qux", qux_->name()); -} - -TEST_F(DescriptorTest, FieldFullName) { - EXPECT_EQ("TestMessage.foo", foo_->full_name()); - EXPECT_EQ("TestMessage.bar", bar_->full_name()); - EXPECT_EQ("TestMessage.baz", baz_->full_name()); - EXPECT_EQ("TestMessage.qux", qux_->full_name()); - - EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name()); -} - -TEST_F(DescriptorTest, FieldFile) { - EXPECT_EQ(foo_file_, foo_->file()); - EXPECT_EQ(foo_file_, bar_->file()); - EXPECT_EQ(foo_file_, baz_->file()); - EXPECT_EQ(foo_file_, qux_->file()); - - EXPECT_EQ(bar_file_, foo2_->file()); - EXPECT_EQ(bar_file_, bar2_->file()); - EXPECT_EQ(bar_file_, quux2_->file()); -} - -TEST_F(DescriptorTest, FieldIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); - EXPECT_EQ(2, baz_->index()); - EXPECT_EQ(3, qux_->index()); -} - -TEST_F(DescriptorTest, FieldNumber) { - EXPECT_EQ( 1, foo_->number()); - EXPECT_EQ( 6, bar_->number()); - EXPECT_EQ(500000000, baz_->number()); - EXPECT_EQ( 15, qux_->number()); -} - -TEST_F(DescriptorTest, FieldType) { - EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_ENUM , bar_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type()); - EXPECT_EQ(FieldDescriptor::TYPE_GROUP , qux_->type()); -} - -TEST_F(DescriptorTest, FieldLabel) { - EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label()); - - EXPECT_TRUE (foo_->is_required()); - EXPECT_FALSE(foo_->is_optional()); - EXPECT_FALSE(foo_->is_repeated()); - - EXPECT_FALSE(bar_->is_required()); - EXPECT_TRUE (bar_->is_optional()); - EXPECT_FALSE(bar_->is_repeated()); - - EXPECT_FALSE(baz_->is_required()); - EXPECT_FALSE(baz_->is_optional()); - EXPECT_TRUE (baz_->is_repeated()); -} - -TEST_F(DescriptorTest, FieldHasDefault) { - EXPECT_FALSE(foo_->has_default_value()); - EXPECT_FALSE(bar_->has_default_value()); - EXPECT_FALSE(baz_->has_default_value()); - EXPECT_FALSE(qux_->has_default_value()); -} - -TEST_F(DescriptorTest, FieldContainingType) { - EXPECT_EQ(message_, foo_->containing_type()); - EXPECT_EQ(message_, bar_->containing_type()); - EXPECT_EQ(message_, baz_->containing_type()); - EXPECT_EQ(message_, qux_->containing_type()); - - EXPECT_EQ(message2_, foo2_ ->containing_type()); - EXPECT_EQ(message2_, bar2_ ->containing_type()); - EXPECT_EQ(message2_, quux2_->containing_type()); -} - -TEST_F(DescriptorTest, FieldMessageType) { - EXPECT_TRUE(foo_->message_type() == NULL); - EXPECT_TRUE(bar_->message_type() == NULL); - - EXPECT_EQ(foreign_, baz_->message_type()); - EXPECT_EQ(foreign_, qux_->message_type()); -} - -TEST_F(DescriptorTest, FieldEnumType) { - EXPECT_TRUE(foo_->enum_type() == NULL); - EXPECT_TRUE(baz_->enum_type() == NULL); - EXPECT_TRUE(qux_->enum_type() == NULL); - - EXPECT_EQ(enum_, bar_->enum_type()); -} - -// =================================================================== - -// Test enum descriptors. -class EnumDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // enum TestEnum { - // FOO = 1; - // BAR = 2; - // } - // - // // in "bar.proto" - // package corge.grault; - // enum TestEnum2 { - // FOO = 1; - // BAZ = 3; - // } - // - // TestEnum2 is primarily here to test FindValueByName and friends. - // All enums created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - - // TestEnum - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum"); - AddEnumValue(enum_proto, "FOO", 1); - AddEnumValue(enum_proto, "BAR", 2); - - // TestEnum2 - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2"); - AddEnumValue(enum2_proto, "FOO", 1); - AddEnumValue(enum2_proto, "BAZ", 3); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - enum_ = foo_file_->enum_type(0); - - ASSERT_EQ(2, enum_->value_count()); - foo_ = enum_->value(0); - bar_ = enum_->value(1); - - ASSERT_EQ(1, bar_file_->enum_type_count()); - enum2_ = bar_file_->enum_type(0); - - ASSERT_EQ(2, enum2_->value_count()); - foo2_ = enum2_->value(0); - baz2_ = enum2_->value(1); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const EnumDescriptor* enum_; - const EnumDescriptor* enum2_; - - const EnumValueDescriptor* foo_; - const EnumValueDescriptor* bar_; - - const EnumValueDescriptor* foo2_; - const EnumValueDescriptor* baz2_; -}; - -TEST_F(EnumDescriptorTest, Name) { - EXPECT_EQ("TestEnum", enum_->name()); - EXPECT_EQ("TestEnum", enum_->full_name()); - EXPECT_EQ(foo_file_, enum_->file()); - - EXPECT_EQ("TestEnum2", enum2_->name()); - EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name()); - EXPECT_EQ(bar_file_, enum2_->file()); -} - -TEST_F(EnumDescriptorTest, ContainingType) { - EXPECT_TRUE(enum_->containing_type() == NULL); - EXPECT_TRUE(enum2_->containing_type() == NULL); -} - -TEST_F(EnumDescriptorTest, ValuesByIndex) { - ASSERT_EQ(2, enum_->value_count()); - EXPECT_EQ(foo_, enum_->value(0)); - EXPECT_EQ(bar_, enum_->value(1)); -} - -TEST_F(EnumDescriptorTest, FindValueByName) { - EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO")); - EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR")); - EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO")); - EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ")); - - EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(enum_ ->FindValueByName("BAZ" ) == NULL); - EXPECT_TRUE(enum2_->FindValueByName("BAR" ) == NULL); -} - -TEST_F(EnumDescriptorTest, FindValueByNumber) { - EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1)); - EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2)); - EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1)); - EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3)); - - EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL); - EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL); - EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL); -} - -TEST_F(EnumDescriptorTest, ValueName) { - EXPECT_EQ("FOO", foo_->name()); - EXPECT_EQ("BAR", bar_->name()); -} - -TEST_F(EnumDescriptorTest, ValueFullName) { - EXPECT_EQ("FOO", foo_->full_name()); - EXPECT_EQ("BAR", bar_->full_name()); - EXPECT_EQ("corge.grault.FOO", foo2_->full_name()); - EXPECT_EQ("corge.grault.BAZ", baz2_->full_name()); -} - -TEST_F(EnumDescriptorTest, ValueIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); -} - -TEST_F(EnumDescriptorTest, ValueNumber) { - EXPECT_EQ(1, foo_->number()); - EXPECT_EQ(2, bar_->number()); -} - -TEST_F(EnumDescriptorTest, ValueType) { - EXPECT_EQ(enum_ , foo_ ->type()); - EXPECT_EQ(enum_ , bar_ ->type()); - EXPECT_EQ(enum2_, foo2_->type()); - EXPECT_EQ(enum2_, baz2_->type()); -} - -// =================================================================== - -// Test service descriptors. -class ServiceDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following messages and service: - // // in "foo.proto" - // message FooRequest {} - // message FooResponse {} - // message BarRequest {} - // message BarResponse {} - // message BazRequest {} - // message BazResponse {} - // - // service TestService { - // rpc Foo(FooRequest) returns (FooResponse); - // rpc Bar(BarRequest) returns (BarResponse); - // } - // - // // in "bar.proto" - // package corge.grault - // service TestService2 { - // rpc Foo(FooRequest) returns (FooResponse); - // rpc Baz(BazRequest) returns (BazResponse); - // } - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - AddMessage(&foo_file, "FooRequest"); - AddMessage(&foo_file, "FooResponse"); - AddMessage(&foo_file, "BarRequest"); - AddMessage(&foo_file, "BarResponse"); - AddMessage(&foo_file, "BazRequest"); - AddMessage(&foo_file, "BazResponse"); - - ServiceDescriptorProto* service = AddService(&foo_file, "TestService"); - AddMethod(service, "Foo", "FooRequest", "FooResponse"); - AddMethod(service, "Bar", "BarRequest", "BarResponse"); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - bar_file.add_dependency("foo.proto"); - - ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2"); - AddMethod(service2, "Foo", "FooRequest", "FooResponse"); - AddMethod(service2, "Baz", "BazRequest", "BazResponse"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(6, foo_file_->message_type_count()); - foo_request_ = foo_file_->message_type(0); - foo_response_ = foo_file_->message_type(1); - bar_request_ = foo_file_->message_type(2); - bar_response_ = foo_file_->message_type(3); - baz_request_ = foo_file_->message_type(4); - baz_response_ = foo_file_->message_type(5); - - ASSERT_EQ(1, foo_file_->service_count()); - service_ = foo_file_->service(0); - - ASSERT_EQ(2, service_->method_count()); - foo_ = service_->method(0); - bar_ = service_->method(1); - - ASSERT_EQ(1, bar_file_->service_count()); - service2_ = bar_file_->service(0); - - ASSERT_EQ(2, service2_->method_count()); - foo2_ = service2_->method(0); - baz2_ = service2_->method(1); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* foo_request_; - const Descriptor* foo_response_; - const Descriptor* bar_request_; - const Descriptor* bar_response_; - const Descriptor* baz_request_; - const Descriptor* baz_response_; - - const ServiceDescriptor* service_; - const ServiceDescriptor* service2_; - - const MethodDescriptor* foo_; - const MethodDescriptor* bar_; - - const MethodDescriptor* foo2_; - const MethodDescriptor* baz2_; -}; - -TEST_F(ServiceDescriptorTest, Name) { - EXPECT_EQ("TestService", service_->name()); - EXPECT_EQ("TestService", service_->full_name()); - EXPECT_EQ(foo_file_, service_->file()); - - EXPECT_EQ("TestService2", service2_->name()); - EXPECT_EQ("corge.grault.TestService2", service2_->full_name()); - EXPECT_EQ(bar_file_, service2_->file()); -} - -TEST_F(ServiceDescriptorTest, MethodsByIndex) { - ASSERT_EQ(2, service_->method_count()); - EXPECT_EQ(foo_, service_->method(0)); - EXPECT_EQ(bar_, service_->method(1)); -} - -TEST_F(ServiceDescriptorTest, FindMethodByName) { - EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo")); - EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar")); - EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo")); - EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz")); - - EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL); - EXPECT_TRUE(service_ ->FindMethodByName("Baz" ) == NULL); - EXPECT_TRUE(service2_->FindMethodByName("Bar" ) == NULL); -} - -TEST_F(ServiceDescriptorTest, MethodName) { - EXPECT_EQ("Foo", foo_->name()); - EXPECT_EQ("Bar", bar_->name()); -} - -TEST_F(ServiceDescriptorTest, MethodFullName) { - EXPECT_EQ("TestService.Foo", foo_->full_name()); - EXPECT_EQ("TestService.Bar", bar_->full_name()); - EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name()); -} - -TEST_F(ServiceDescriptorTest, MethodIndex) { - EXPECT_EQ(0, foo_->index()); - EXPECT_EQ(1, bar_->index()); -} - -TEST_F(ServiceDescriptorTest, MethodParent) { - EXPECT_EQ(service_, foo_->service()); - EXPECT_EQ(service_, bar_->service()); -} - -TEST_F(ServiceDescriptorTest, MethodInputType) { - EXPECT_EQ(foo_request_, foo_->input_type()); - EXPECT_EQ(bar_request_, bar_->input_type()); -} - -TEST_F(ServiceDescriptorTest, MethodOutputType) { - EXPECT_EQ(foo_response_, foo_->output_type()); - EXPECT_EQ(bar_response_, bar_->output_type()); -} - -// =================================================================== - -// Test nested types. -class NestedDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // // in "foo.proto" - // message TestMessage { - // message Foo {} - // message Bar {} - // enum Baz { A = 1; } - // enum Qux { B = 1; } - // } - // - // // in "bar.proto" - // package corge.grault; - // message TestMessage2 { - // message Foo {} - // message Baz {} - // enum Qux { A = 1; } - // enum Quux { C = 1; } - // } - // - // TestMessage2 is primarily here to test FindNestedTypeByName and friends. - // All messages created from the same DescriptorPool share the same lookup - // table, so we need to insure that they don't interfere. - // - // We add enum values to the enums in order to test searching for enum - // values across a message's scope. - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - DescriptorProto* message = AddMessage(&foo_file, "TestMessage"); - AddNestedMessage(message, "Foo"); - AddNestedMessage(message, "Bar"); - EnumDescriptorProto* baz = AddNestedEnum(message, "Baz"); - AddEnumValue(baz, "A", 1); - EnumDescriptorProto* qux = AddNestedEnum(message, "Qux"); - AddEnumValue(qux, "B", 1); - - FileDescriptorProto bar_file; - bar_file.set_name("bar.proto"); - bar_file.set_package("corge.grault"); - - DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2"); - AddNestedMessage(message2, "Foo"); - AddNestedMessage(message2, "Baz"); - EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux"); - AddEnumValue(qux2, "A", 1); - EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux"); - AddEnumValue(quux2, "C", 1); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - bar_file_ = pool_.BuildFile(bar_file); - ASSERT_TRUE(bar_file_ != NULL); - - ASSERT_EQ(1, foo_file_->message_type_count()); - message_ = foo_file_->message_type(0); - - ASSERT_EQ(2, message_->nested_type_count()); - foo_ = message_->nested_type(0); - bar_ = message_->nested_type(1); - - ASSERT_EQ(2, message_->enum_type_count()); - baz_ = message_->enum_type(0); - qux_ = message_->enum_type(1); - - ASSERT_EQ(1, baz_->value_count()); - a_ = baz_->value(0); - ASSERT_EQ(1, qux_->value_count()); - b_ = qux_->value(0); - - ASSERT_EQ(1, bar_file_->message_type_count()); - message2_ = bar_file_->message_type(0); - - ASSERT_EQ(2, message2_->nested_type_count()); - foo2_ = message2_->nested_type(0); - baz2_ = message2_->nested_type(1); - - ASSERT_EQ(2, message2_->enum_type_count()); - qux2_ = message2_->enum_type(0); - quux2_ = message2_->enum_type(1); - - ASSERT_EQ(1, qux2_->value_count()); - a2_ = qux2_->value(0); - ASSERT_EQ(1, quux2_->value_count()); - c2_ = quux2_->value(0); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - const FileDescriptor* bar_file_; - - const Descriptor* message_; - const Descriptor* message2_; - - const Descriptor* foo_; - const Descriptor* bar_; - const EnumDescriptor* baz_; - const EnumDescriptor* qux_; - const EnumValueDescriptor* a_; - const EnumValueDescriptor* b_; - - const Descriptor* foo2_; - const Descriptor* baz2_; - const EnumDescriptor* qux2_; - const EnumDescriptor* quux2_; - const EnumValueDescriptor* a2_; - const EnumValueDescriptor* c2_; -}; - -TEST_F(NestedDescriptorTest, MessageName) { - EXPECT_EQ("Foo", foo_ ->name()); - EXPECT_EQ("Bar", bar_ ->name()); - EXPECT_EQ("Foo", foo2_->name()); - EXPECT_EQ("Baz", baz2_->name()); - - EXPECT_EQ("TestMessage.Foo", foo_->full_name()); - EXPECT_EQ("TestMessage.Bar", bar_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name()); -} - -TEST_F(NestedDescriptorTest, MessageContainingType) { - EXPECT_EQ(message_ , foo_ ->containing_type()); - EXPECT_EQ(message_ , bar_ ->containing_type()); - EXPECT_EQ(message2_, foo2_->containing_type()); - EXPECT_EQ(message2_, baz2_->containing_type()); -} - -TEST_F(NestedDescriptorTest, NestedMessagesByIndex) { - ASSERT_EQ(2, message_->nested_type_count()); - EXPECT_EQ(foo_, message_->nested_type(0)); - EXPECT_EQ(bar_, message_->nested_type(1)); -} - -TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) { - EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL); - EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL); - EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL); - EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL); -} - -TEST_F(NestedDescriptorTest, FindNestedTypeByName) { - EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo")); - EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar")); - EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo")); - EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz")); - - EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL); - EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz" ) == NULL); - EXPECT_TRUE(message2_->FindNestedTypeByName("Bar" ) == NULL); - - EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL); -} - -TEST_F(NestedDescriptorTest, EnumName) { - EXPECT_EQ("Baz" , baz_ ->name()); - EXPECT_EQ("Qux" , qux_ ->name()); - EXPECT_EQ("Qux" , qux2_->name()); - EXPECT_EQ("Quux", quux2_->name()); - - EXPECT_EQ("TestMessage.Baz", baz_->full_name()); - EXPECT_EQ("TestMessage.Qux", qux_->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name()); - EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name()); -} - -TEST_F(NestedDescriptorTest, EnumContainingType) { - EXPECT_EQ(message_ , baz_ ->containing_type()); - EXPECT_EQ(message_ , qux_ ->containing_type()); - EXPECT_EQ(message2_, qux2_ ->containing_type()); - EXPECT_EQ(message2_, quux2_->containing_type()); -} - -TEST_F(NestedDescriptorTest, NestedEnumsByIndex) { - ASSERT_EQ(2, message_->nested_type_count()); - EXPECT_EQ(foo_, message_->nested_type(0)); - EXPECT_EQ(bar_, message_->nested_type(1)); -} - -TEST_F(NestedDescriptorTest, FindEnumTypeByName) { - EXPECT_EQ(baz_ , message_ ->FindEnumTypeByName("Baz" )); - EXPECT_EQ(qux_ , message_ ->FindEnumTypeByName("Qux" )); - EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" )); - EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux")); - - EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL); - EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux" ) == NULL); - EXPECT_TRUE(message2_->FindEnumTypeByName("Baz" ) == NULL); - - EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL); -} - -TEST_F(NestedDescriptorTest, FindEnumValueByName) { - EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A")); - EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B")); - EXPECT_EQ(a2_, message2_->FindEnumValueByName("A")); - EXPECT_EQ(c2_, message2_->FindEnumValueByName("C")); - - EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(message_ ->FindEnumValueByName("C" ) == NULL); - EXPECT_TRUE(message2_->FindEnumValueByName("B" ) == NULL); - - EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL); -} - -// =================================================================== - -// Test extensions. -class ExtensionDescriptorTest : public testing::Test { - protected: - virtual void SetUp() { - // Build descriptors for the following definitions: - // - // enum Baz {} - // message Qux {} - // - // message Foo { - // extensions 10 to 19; - // extensions 30 to 39; - // } - // extends Foo with optional int32 foo_int32 = 10; - // extends Foo with repeated TestEnum foo_enum = 19; - // message Bar { - // extends Foo with optional Qux foo_message = 30; - // // (using Qux as the group type) - // extends Foo with repeated group foo_group = 39; - // } - - FileDescriptorProto foo_file; - foo_file.set_name("foo.proto"); - - AddEmptyEnum(&foo_file, "Baz"); - AddMessage(&foo_file, "Qux"); - - DescriptorProto* foo = AddMessage(&foo_file, "Foo"); - AddExtensionRange(foo, 10, 20); - AddExtensionRange(foo, 30, 40); - - AddExtension(&foo_file, "Foo", "foo_int32", 10, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - AddExtension(&foo_file, "Foo", "foo_enum", 19, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_ENUM) - ->set_type_name("Baz"); - - DescriptorProto* bar = AddMessage(&foo_file, "Bar"); - AddNestedExtension(bar, "Foo", "foo_message", 30, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_MESSAGE) - ->set_type_name("Qux"); - AddNestedExtension(bar, "Foo", "foo_group", 39, - FieldDescriptorProto::LABEL_REPEATED, - FieldDescriptorProto::TYPE_GROUP) - ->set_type_name("Qux"); - - // Build the descriptors and get the pointers. - foo_file_ = pool_.BuildFile(foo_file); - ASSERT_TRUE(foo_file_ != NULL); - - ASSERT_EQ(1, foo_file_->enum_type_count()); - baz_ = foo_file_->enum_type(0); - - ASSERT_EQ(3, foo_file_->message_type_count()); - qux_ = foo_file_->message_type(0); - foo_ = foo_file_->message_type(1); - bar_ = foo_file_->message_type(2); - } - - DescriptorPool pool_; - - const FileDescriptor* foo_file_; - - const Descriptor* foo_; - const Descriptor* bar_; - const EnumDescriptor* baz_; - const Descriptor* qux_; -}; - -TEST_F(ExtensionDescriptorTest, ExtensionRanges) { - EXPECT_EQ(0, bar_->extension_range_count()); - ASSERT_EQ(2, foo_->extension_range_count()); - - EXPECT_EQ(10, foo_->extension_range(0)->start); - EXPECT_EQ(30, foo_->extension_range(1)->start); - - EXPECT_EQ(20, foo_->extension_range(0)->end); - EXPECT_EQ(40, foo_->extension_range(1)->end); -}; - -TEST_F(ExtensionDescriptorTest, Extensions) { - EXPECT_EQ(0, foo_->extension_count()); - ASSERT_EQ(2, foo_file_->extension_count()); - ASSERT_EQ(2, bar_->extension_count()); - - EXPECT_TRUE(foo_file_->extension(0)->is_extension()); - EXPECT_TRUE(foo_file_->extension(1)->is_extension()); - EXPECT_TRUE(bar_->extension(0)->is_extension()); - EXPECT_TRUE(bar_->extension(1)->is_extension()); - - EXPECT_EQ("foo_int32" , foo_file_->extension(0)->name()); - EXPECT_EQ("foo_enum" , foo_file_->extension(1)->name()); - EXPECT_EQ("foo_message", bar_->extension(0)->name()); - EXPECT_EQ("foo_group" , bar_->extension(1)->name()); - - EXPECT_EQ(10, foo_file_->extension(0)->number()); - EXPECT_EQ(19, foo_file_->extension(1)->number()); - EXPECT_EQ(30, bar_->extension(0)->number()); - EXPECT_EQ(39, bar_->extension(1)->number()); - - EXPECT_EQ(FieldDescriptor::TYPE_INT32 , foo_file_->extension(0)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_ENUM , foo_file_->extension(1)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type()); - EXPECT_EQ(FieldDescriptor::TYPE_GROUP , bar_->extension(1)->type()); - - EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type()); - EXPECT_EQ(qux_, bar_->extension(0)->message_type()); - EXPECT_EQ(qux_, bar_->extension(1)->message_type()); - - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label()); - EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label()); - - EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type()); - EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type()); - EXPECT_EQ(foo_, bar_->extension(0)->containing_type()); - EXPECT_EQ(foo_, bar_->extension(1)->containing_type()); - - EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL); - EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL); - EXPECT_EQ(bar_, bar_->extension(0)->extension_scope()); - EXPECT_EQ(bar_, bar_->extension(1)->extension_scope()); -}; - -TEST_F(ExtensionDescriptorTest, IsExtensionNumber) { - EXPECT_FALSE(foo_->IsExtensionNumber( 9)); - EXPECT_TRUE (foo_->IsExtensionNumber(10)); - EXPECT_TRUE (foo_->IsExtensionNumber(19)); - EXPECT_FALSE(foo_->IsExtensionNumber(20)); - EXPECT_FALSE(foo_->IsExtensionNumber(29)); - EXPECT_TRUE (foo_->IsExtensionNumber(30)); - EXPECT_TRUE (foo_->IsExtensionNumber(39)); - EXPECT_FALSE(foo_->IsExtensionNumber(40)); -} - -TEST_F(ExtensionDescriptorTest, FindExtensionByName) { - // Note that FileDescriptor::FindExtensionByName() is tested by - // FileDescriptorTest. - ASSERT_EQ(2, bar_->extension_count()); - - EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message")); - EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" )); - - EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL); - EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL); -} - -// =================================================================== - -class MiscTest : public testing::Test { - protected: - // Function which makes a field of the given type just to find out what its - // cpp_type is. - FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) { - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - AddEmptyEnum(&file_proto, "DummyEnum"); - - DescriptorProto* message = AddMessage(&file_proto, "TestMessage"); - FieldDescriptorProto* field = - AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL, - static_cast<FieldDescriptorProto::Type>(type)); - - if (type == FieldDescriptor::TYPE_MESSAGE || - type == FieldDescriptor::TYPE_GROUP) { - field->set_type_name("TestMessage"); - } else if (type == FieldDescriptor::TYPE_ENUM) { - field->set_type_name("DummyEnum"); - } - - // Build the descriptors and get the pointers. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - - if (file != NULL && - file->message_type_count() == 1 && - file->message_type(0)->field_count() == 1) { - return file->message_type(0)->field(0)->cpp_type(); - } else { - return static_cast<FieldDescriptor::CppType>(0); - } - } -}; - -TEST_F(MiscTest, CppTypes) { - // Test that CPP types are assigned correctly. - - typedef FieldDescriptor FD; // avoid ugly line wrapping - - EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE )); - EXPECT_EQ(FD::CPPTYPE_FLOAT , GetCppTypeForFieldType(FD::TYPE_FLOAT )); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_INT64 )); - EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64 )); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_INT32 )); - EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 )); - EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 )); - EXPECT_EQ(FD::CPPTYPE_BOOL , GetCppTypeForFieldType(FD::TYPE_BOOL )); - EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING )); - EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP )); - EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE )); - EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES )); - EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32 )); - EXPECT_EQ(FD::CPPTYPE_ENUM , GetCppTypeForFieldType(FD::TYPE_ENUM )); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SFIXED32)); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SFIXED64)); - EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SINT32 )); - EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 )); -} - -TEST_F(MiscTest, DefaultValues) { - // Test that setting default values works. - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - - EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum"); - AddEnumValue(enum_type_proto, "A", 1); - AddEnumValue(enum_type_proto, "B", 2); - - DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); - - typedef FieldDescriptorProto FD; // avoid ugly line wrapping - const FD::Label label = FD::LABEL_OPTIONAL; - - // Create fields of every CPP type with default values. - AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 ) - ->set_default_value("-1"); - AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 ) - ->set_default_value("-1000000000000"); - AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32) - ->set_default_value("42"); - AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64) - ->set_default_value("2000000000000"); - AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT ) - ->set_default_value("4.5"); - AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE) - ->set_default_value("10e100"); - AddField(message_proto, "bool" , 7, label, FD::TYPE_BOOL ) - ->set_default_value("true"); - AddField(message_proto, "string", 8, label, FD::TYPE_STRING) - ->set_default_value("hello"); - AddField(message_proto, "data" , 9, label, FD::TYPE_BYTES ) - ->set_default_value("\\001\\002\\003"); - - FieldDescriptorProto* enum_field = - AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM); - enum_field->set_type_name("DummyEnum"); - enum_field->set_default_value("B"); - - // Strings are allowed to have empty defaults. (At one point, due to - // a bug, empty defaults for strings were rejected. Oops.) - AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING) - ->set_default_value(""); - - // Add a second set of fields with implicit defalut values. - AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 ); - AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 ); - AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32); - AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64); - AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT ); - AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE); - AddField(message_proto, "implicit_bool" , 27, label, FD::TYPE_BOOL ); - AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING); - AddField(message_proto, "implicit_data" , 29, label, FD::TYPE_BYTES ); - AddField(message_proto, "implicit_enum" , 30, label, FD::TYPE_ENUM) - ->set_type_name("DummyEnum"); - - // Build it. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->enum_type_count()); - const EnumDescriptor* enum_type = file->enum_type(0); - ASSERT_EQ(2, enum_type->value_count()); - const EnumValueDescriptor* enum_value_a = enum_type->value(0); - const EnumValueDescriptor* enum_value_b = enum_type->value(1); - - ASSERT_EQ(1, file->message_type_count()); - const Descriptor* message = file->message_type(0); - - ASSERT_EQ(21, message->field_count()); - - // Check the default values. - ASSERT_TRUE(message->field(0)->has_default_value()); - ASSERT_TRUE(message->field(1)->has_default_value()); - ASSERT_TRUE(message->field(2)->has_default_value()); - ASSERT_TRUE(message->field(3)->has_default_value()); - ASSERT_TRUE(message->field(4)->has_default_value()); - ASSERT_TRUE(message->field(5)->has_default_value()); - ASSERT_TRUE(message->field(6)->has_default_value()); - ASSERT_TRUE(message->field(7)->has_default_value()); - ASSERT_TRUE(message->field(8)->has_default_value()); - ASSERT_TRUE(message->field(9)->has_default_value()); - ASSERT_TRUE(message->field(10)->has_default_value()); - - EXPECT_EQ(-1 , message->field(0)->default_value_int32 ()); - EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000), - message->field(1)->default_value_int64 ()); - EXPECT_EQ(42 , message->field(2)->default_value_uint32()); - EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000), - message->field(3)->default_value_uint64()); - EXPECT_EQ(4.5 , message->field(4)->default_value_float ()); - EXPECT_EQ(10e100 , message->field(5)->default_value_double()); - EXPECT_EQ(true , message->field(6)->default_value_bool ()); - EXPECT_EQ("hello" , message->field(7)->default_value_string()); - EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string()); - EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ()); - EXPECT_EQ("" , message->field(10)->default_value_string()); - - ASSERT_FALSE(message->field(11)->has_default_value()); - ASSERT_FALSE(message->field(12)->has_default_value()); - ASSERT_FALSE(message->field(13)->has_default_value()); - ASSERT_FALSE(message->field(14)->has_default_value()); - ASSERT_FALSE(message->field(15)->has_default_value()); - ASSERT_FALSE(message->field(16)->has_default_value()); - ASSERT_FALSE(message->field(17)->has_default_value()); - ASSERT_FALSE(message->field(18)->has_default_value()); - ASSERT_FALSE(message->field(19)->has_default_value()); - ASSERT_FALSE(message->field(20)->has_default_value()); - - EXPECT_EQ(0 , message->field(11)->default_value_int32 ()); - EXPECT_EQ(0 , message->field(12)->default_value_int64 ()); - EXPECT_EQ(0 , message->field(13)->default_value_uint32()); - EXPECT_EQ(0 , message->field(14)->default_value_uint64()); - EXPECT_EQ(0.0f , message->field(15)->default_value_float ()); - EXPECT_EQ(0.0 , message->field(16)->default_value_double()); - EXPECT_EQ(false, message->field(17)->default_value_bool ()); - EXPECT_EQ("" , message->field(18)->default_value_string()); - EXPECT_EQ("" , message->field(19)->default_value_string()); - EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum()); -} - -TEST_F(MiscTest, FieldOptions) { - // Try setting field options. - - FileDescriptorProto file_proto; - file_proto.set_name("foo.proto"); - - DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage"); - AddField(message_proto, "foo", 1, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - FieldDescriptorProto* bar_proto = - AddField(message_proto, "bar", 2, - FieldDescriptorProto::LABEL_OPTIONAL, - FieldDescriptorProto::TYPE_INT32); - - FieldOptions* options = bar_proto->mutable_options(); - options->set_ctype(FieldOptions::CORD); - - // Build the descriptors and get the pointers. - DescriptorPool pool; - const FileDescriptor* file = pool.BuildFile(file_proto); - ASSERT_TRUE(file != NULL); - - ASSERT_EQ(1, file->message_type_count()); - const Descriptor* message = file->message_type(0); - - ASSERT_EQ(2, message->field_count()); - const FieldDescriptor* foo = message->field(0); - const FieldDescriptor* bar = message->field(1); - - // "foo" had no options set, so it should return the default options. - EXPECT_EQ(&FieldOptions::default_instance(), &foo->options()); - - // "bar" had options set. - EXPECT_NE(&FieldOptions::default_instance(), options); - EXPECT_TRUE(bar->options().has_ctype()); - EXPECT_EQ(FieldOptions::CORD, bar->options().ctype()); -} - -// =================================================================== - -// The tests below trigger every unique call to AddError() in descriptor.cc, -// in the order in which they appear in that file. I'm using TextFormat here -// to specify the input descriptors because building them using code would -// be too bulky. - -class MockErrorCollector : public DescriptorPool::ErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, - const string& element_name, const Message* descriptor, - ErrorLocation location, const string& message) { - const char* location_name = NULL; - switch (location) { - case NAME : location_name = "NAME" ; break; - case NUMBER : location_name = "NUMBER" ; break; - case TYPE : location_name = "TYPE" ; break; - case EXTENDEE : location_name = "EXTENDEE" ; break; - case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break; - case INPUT_TYPE : location_name = "INPUT_TYPE" ; break; - case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break; - case OTHER : location_name = "OTHER" ; break; - } - - strings::SubstituteAndAppend( - &text_, "$0: $1: $2: $3\n", - filename, element_name, location_name, message); - } -}; - -class ValidationErrorTest : public testing::Test { - protected: - // Parse file_text as a FileDescriptorProto in text format and add it - // to the DescriptorPool. Expect no errors. - void BuildFile(const string& file_text) { - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); - } - - // Parse file_text as a FileDescriptorProto in text format and add it - // to the DescriptorPool. Expect errors to be produced which match the - // given error text. - void BuildFileWithErrors(const string& file_text, - const string& expected_errors) { - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - - MockErrorCollector error_collector; - EXPECT_TRUE( - pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL); - EXPECT_EQ(expected_errors, error_collector.text_); - } - - DescriptorPool pool_; -}; - -TEST_F(ValidationErrorTest, AlreadyDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", - - "foo.proto: Foo: NAME: \"Foo\" is already defined.\n"); -} - -TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.bar\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", - - "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in " - "\"foo.bar\".\n"); -} - -TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); - - BuildFileWithErrors( - "name: \"bar.proto\" " - "message_type { name: \"Foo\" }", - - "bar.proto: Foo: NAME: \"Foo\" is already defined in file " - "\"foo.proto\".\n"); -} - -TEST_F(ValidationErrorTest, PackageAlreadyDefined) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"foo\" }"); - BuildFileWithErrors( - "name: \"bar.proto\" " - "package: \"foo.bar\"", - - "bar.proto: foo: NAME: \"foo\" is already defined (as something other " - "than a package) in file \"foo.proto\".\n"); -} - -TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", - - "foo.proto: FOO: NAME: \"FOO\" is already defined.\n" - "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, " - "meaning that enum values are siblings of their type, not children of " - "it. Therefore, \"FOO\" must be unique within the global scope, not " - "just within \"Bar\".\n"); -} - -TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", - - "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n" - "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, " - "meaning that enum values are siblings of their type, not children of " - "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within " - "\"Bar\".\n"); -} - -TEST_F(ValidationErrorTest, MissingName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { }", - - "foo.proto: : NAME: Missing name.\n"); -} - -TEST_F(ValidationErrorTest, InvalidName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"$\" }", - - "foo.proto: $: NAME: \"$\" is not a valid identifier.\n"); -} - -TEST_F(ValidationErrorTest, InvalidPackageName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.$\"", - - "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n"); -} - -TEST_F(ValidationErrorTest, MissingFileName) { - BuildFileWithErrors( - "", - - ": : OTHER: Missing field: FileDescriptorProto.name.\n"); -} - -TEST_F(ValidationErrorTest, DupeDependency) { - BuildFile("name: \"foo.proto\""); - BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "dependency: \"foo.proto\" ", - - "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n"); -} - -TEST_F(ValidationErrorTest, UnknownDependency) { - BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" ", - - "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n"); -} - -TEST_F(ValidationErrorTest, DupeFile) { - BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); - // Note: We should *not* get redundant errors about "Foo" already being - // defined. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }", - - "foo.proto: foo.proto: OTHER: A file with this name is already in the " - "pool.\n"); -} - -TEST_F(ValidationErrorTest, FieldInExtensionRange) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " extension_range { start: 10 end: 20 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field " - "\"bar\" (10).\n" - "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field " - "\"baz\" (19).\n"); -} - -TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - " extension_range { start: 20 end: 30 }" - " extension_range { start: 19 end: 21 }" - "}", - - "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " - "already-defined range 10 to 19.\n" - "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " - "already-defined range 20 to 29.\n"); -} - -TEST_F(ValidationErrorTest, InvalidDefaults) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - - // Invalid number. - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"abc\" }" - - // Empty default value. - " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"\" }" - - // Invalid boolean. - " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL" - " default_value: \"abc\" }" - - // Messages can't have defaults. - " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE" - " default_value: \"abc\" type_name: \"Foo\" }" - - // Same thing, but we don't know that this field has message type until - // we look up the type name. - " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL" - " default_value: \"abc\" type_name: \"Foo\" }" - "}", - - "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n" - "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n" - "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or " - "false.\n" - "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n" - "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default " - "values.\n"); -} - -TEST_F(ValidationErrorTest, NegativeFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n"); -} - -TEST_F(ValidationErrorTest, HugeFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 0x70000000 " - " label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than " - "536870911.\n"); -} - -TEST_F(ValidationErrorTest, ReservedFieldNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are " - "reserved for the protocol buffer library implementation.\n" - "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are " - "reserved for the protocol buffer library implementation.\n"); -} - -TEST_F(ValidationErrorTest, ExtensionMissingExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for " - "extension field.\n"); -} - -TEST_F(ValidationErrorTest, NonExtensionWithExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " extension_range { start: 1 end: 2 }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for " - "non-extension field.\n"); -} - -TEST_F(ValidationErrorTest, FieldNumberConflict) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in " - "\"Foo\" by field \"foo\".\n"); -} - -TEST_F(ValidationErrorTest, BadMessageSetExtensionType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"MessageSet\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " - "messages.\n"); -} - -TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE" - " type_name: \"Foo\" extendee: \"MessageSet\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " - "messages.\n"); -} - -TEST_F(ValidationErrorTest, FieldInMessageSet) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " options { message_set_wire_format: true }" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only " - "extensions.\n"); -} - -TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: -10 end: -1 }" - "}", - - "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n"); -} - -TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 1 end: 0x70000000 }" - "}", - - "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than " - "536870911.\n"); -} - -TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 10 }" - " extension_range { start: 10 end: 5 }" - "}", - - "foo.proto: Foo: NUMBER: Extension range end number must be greater than " - "start number.\n" - "foo.proto: Foo: NUMBER: Extension range end number must be greater than " - "start number.\n"); -} - -TEST_F(ValidationErrorTest, EmptyEnum) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" }" - // Also use the empty enum in a message to make sure there are no crashes - // during validation (possible if the code attempts to derive a default - // value for the field). - "message_type {" - " name: \"Bar\"" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }" - " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" " - " default_value: \"NO_SUCH_VALUE\" }" - "}", - - "foo.proto: Foo: NAME: Enums must contain at least one value.\n" - "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named " - "\"NO_SUCH_VALUE\".\n"); -} - -TEST_F(ValidationErrorTest, UndefinedExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, NonMessageExtendee) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, NotAnExtensionNumber) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", - - "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension " - "number.\n"); -} - -TEST_F(ValidationErrorTest, UndefinedFieldType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) { - BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" } "); - - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", - "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " - "which is not imported by \"foo.proto\". To use it here, please add the " - "necessary import.\n"); -} - -TEST_F(ValidationErrorTest, SearchMostLocalFirst) { - // The following should produce an error that Bar.Baz is not defined: - // message Bar { message Baz {} } - // message Foo { - // message Bar { - // // Placing "message Baz{}" here, or removing Foo.Bar altogether, - // // would fix the error. - // } - // optional Bar.Baz baz = 1; - // } - // An one point the lookup code incorrectly did not produce an error in this - // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first, - // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually - // refer to the inner Bar, not the outer one. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " nested_type { name: \"Baz\" }" - "}" - "message_type {" - " name: \"Foo\"" - " nested_type { name: \"Bar\" }" - " field { name:\"baz\" number:1 label:LABEL_OPTIONAL" - " type_name:\"Bar.Baz\" }" - "}", - - "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) { - // Imagine we have the following: - // - // foo.proto: - // package foo.bar; - // bar.proto: - // package foo.bar; - // import "foo.proto"; - // message Bar {} - // baz.proto: - // package foo; - // import "bar.proto" - // message Baz { optional bar.Bar qux = 1; } - // - // When validating baz.proto, we will look up "bar.Bar". As part of this - // lookup, we first lookup "bar" then try to find "Bar" within it. "bar" - // should resolve to "foo.bar". Note, though, that "foo.bar" was originally - // defined in foo.proto, which is not a direct dependency of baz.proto. The - // implementation of FindSymbol() normally only returns symbols in direct - // dependencies, not indirect ones. This test insures that this does not - // prevent it from finding "foo.bar". - - BuildFile( - "name: \"foo.proto\" " - "package: \"foo.bar\" "); - BuildFile( - "name: \"bar.proto\" " - "package: \"foo.bar\" " - "dependency: \"foo.proto\" " - "message_type { name: \"Bar\" }"); - BuildFile( - "name: \"baz.proto\" " - "package: \"foo\" " - "dependency: \"bar.proto\" " - "message_type { " - " name: \"Baz\" " - " field { name:\"qux\" number:1 label:LABEL_OPTIONAL " - " type_name:\"bar.Bar\" }" - "}"); -} - -TEST_F(ValidationErrorTest, FieldTypeNotAType) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"bar\" }" - " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", - - "foo.proto: Foo.foo: TYPE: \"bar\" is not a type.\n"); -} - -TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Bar\" } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM" - " type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n"); -} - -TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE" - " type_name:\"Bar\" }" - "}", - - "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, BadEnumDefaultValue) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\"" - " default_value:\"NO_SUCH_VALUE\" }" - "}", - - "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named " - "\"NO_SUCH_VALUE\".\n"); -} - -TEST_F(ValidationErrorTest, PrimitiveWithTypeName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " type_name:\"Foo\" }" - "}", - - "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n"); -} - -TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }" - "}", - - "foo.proto: Foo.foo: TYPE: Field with message or enum type missing " - "type_name.\n"); -} - -TEST_F(ValidationErrorTest, InputTypeNotDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", - - "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, InputTypeNotAMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", - - "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, OutputTypeNotDefined) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", - - "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"); -} - -TEST_F(ValidationErrorTest, OutputTypeNotAMessage) { - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", - - "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"); -} - -TEST_F(ValidationErrorTest, RollbackAfterError) { - // Build a file which contains every kind of construct but references an - // undefined type. All these constructs will be added to the symbol table - // before the undefined type error is noticed. The DescriptorPool will then - // have to roll everything back. - BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method {" - " name: \"Baz\"" - " input_type: \"NoSuchType\"" // error - " output_type: \"TestMessage\"" - " }" - "}", - - "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"); - - // Make sure that if we build the same file again with the error fixed, - // it works. If the above rollback was incomplete, then some symbols will - // be left defined, and this second attempt will fail since it tries to - // re-define the same symbols. - BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method { name:\"Baz\"" - " input_type:\"TestMessage\"" - " output_type:\"TestMessage\" }" - "}"); -} - -TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { - // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is - // provided. - - FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "message_type { name: \"Foo\" } ", - &file_proto)); - - vector<string> errors; - - { - ScopedMemoryLog log; - EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(2, errors.size()); - - EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]); - EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]); -} - -// =================================================================== -// DescriptorDatabase - -static void AddToDatabase(SimpleDescriptorDatabase* database, - const char* file_text) { - FileDescriptorProto file_proto; - EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - database->Add(file_proto); -} - -class DatabaseBackedPoolTest : public testing::Test { - protected: - DatabaseBackedPoolTest() {} - - SimpleDescriptorDatabase database_; - - virtual void SetUp() { - AddToDatabase(&database_, - "name: \"foo.proto\" " - "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } " - "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } " - "service { name:\"TestService\" } "); - AddToDatabase(&database_, - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "message_type { name:\"Bar\" } " - "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); - } - - // We can't inject a file containing errors into a DescriptorPool, so we - // need an actual mock DescriptorDatabase to test errors. - class ErrorDescriptorDatabase : public DescriptorDatabase { - public: - ErrorDescriptorDatabase() {} - ~ErrorDescriptorDatabase() {} - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - // error.proto and error2.proto cyclically import each other. - if (filename == "error.proto") { - output->Clear(); - output->set_name("error.proto"); - output->add_dependency("error2.proto"); - return true; - } else if (filename == "error2.proto") { - output->Clear(); - output->set_name("error2.proto"); - output->add_dependency("error.proto"); - return true; - } else { - return false; - } - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - return false; - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return false; - } - }; - - // A DescriptorDatabase that counts how many times each method has been - // called and forwards to some other DescriptorDatabase. - class CallCountingDatabase : public DescriptorDatabase { - public: - CallCountingDatabase(DescriptorDatabase* wrapped_db) - : wrapped_db_(wrapped_db) { - Clear(); - } - ~CallCountingDatabase() {} - - DescriptorDatabase* wrapped_db_; - - int call_count_; - - void Clear() { - call_count_ = 0; - } - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileByName(filename, output); - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileContainingSymbol(symbol_name, output); - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - ++call_count_; - return wrapped_db_->FindFileContainingExtension( - containing_type, field_number, output); - } - }; - - // A DescriptorDatabase which falsely always returns foo.proto when searching - // for any symbol or extension number. This shouldn't cause the - // DescriptorPool to reload foo.proto if it is already loaded. - class FalsePositiveDatabase : public DescriptorDatabase { - public: - FalsePositiveDatabase(DescriptorDatabase* wrapped_db) - : wrapped_db_(wrapped_db) {} - ~FalsePositiveDatabase() {} - - DescriptorDatabase* wrapped_db_; - - // implements DescriptorDatabase --------------------------------- - bool FindFileByName(const string& filename, - FileDescriptorProto* output) { - return wrapped_db_->FindFileByName(filename, output); - } - bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output) { - return FindFileByName("foo.proto", output); - } - bool FindFileContainingExtension(const string& containing_type, - int field_number, - FileDescriptorProto* output) { - return FindFileByName("foo.proto", output); - } - }; -}; - -TEST_F(DatabaseBackedPoolTest, FindFileByName) { - DescriptorPool pool(&database_); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - EXPECT_EQ("Foo", foo->message_type(0)->name()); - - EXPECT_EQ(foo, pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) { - DescriptorPool pool(&database_); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - EXPECT_EQ("Foo", foo->message_type(0)->name()); - - const FileDescriptor* bar = pool.FindFileByName("bar.proto"); - ASSERT_TRUE(bar != NULL); - EXPECT_EQ("bar.proto", bar->name()); - ASSERT_EQ(1, bar->message_type_count()); - EXPECT_EQ("Bar", bar->message_type(0)->name()); - - ASSERT_EQ(1, bar->dependency_count()); - EXPECT_EQ(foo, bar->dependency(0)); -} - -TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) { - DescriptorPool pool(&database_); - - const FileDescriptor* bar = pool.FindFileByName("bar.proto"); - ASSERT_TRUE(bar != NULL); - EXPECT_EQ("bar.proto", bar->name()); - ASSERT_EQ(1, bar->message_type_count()); - ASSERT_EQ("Bar", bar->message_type(0)->name()); - - const FileDescriptor* foo = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(foo != NULL); - EXPECT_EQ("foo.proto", foo->name()); - ASSERT_EQ(1, foo->message_type_count()); - ASSERT_EQ("Foo", foo->message_type(0)->name()); - - ASSERT_EQ(1, bar->dependency_count()); - EXPECT_EQ(foo, bar->dependency(0)); -} - -TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) { - DescriptorPool pool(&database_); - - const FileDescriptor* file = pool.FindFileContainingSymbol("Foo"); - ASSERT_TRUE(file != NULL); - EXPECT_EQ("foo.proto", file->name()); - EXPECT_EQ(file, pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) { - DescriptorPool pool(&database_); - - const Descriptor* type = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(type != NULL); - EXPECT_EQ("Foo", type->name()); - EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto")); - - EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL); -} - -TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) { - DescriptorPool pool(&database_); - - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - - const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5); - ASSERT_TRUE(extension != NULL); - EXPECT_EQ("foo_ext", extension->name()); - EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto")); - - EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL); -} - -TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) { - ErrorDescriptorDatabase error_database; - DescriptorPool pool(&error_database); - - vector<string> errors; - - { - ScopedMemoryLog log; - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - errors = log.GetMessages(ERROR); - } - - EXPECT_FALSE(errors.empty()); -} - -TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) { - ErrorDescriptorDatabase error_database; - MockErrorCollector error_collector; - DescriptorPool pool(&error_database, &error_collector); - - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - EXPECT_EQ( - "error.proto: error.proto: OTHER: File recursively imports itself: " - "error.proto -> error2.proto -> error.proto\n" - "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not " - "found or had errors.\n" - "error.proto: error.proto: OTHER: Import \"error2.proto\" was not " - "found or had errors.\n", - error_collector.text_); -} - -TEST_F(DatabaseBackedPoolTest, UnittestProto) { - // Try to load all of unittest.proto from a DescriptorDatabase. This should - // thoroughly test all paths through DescriptorBuilder to insure that there - // are no deadlocking problems when pool_->mutex_ is non-NULL. - const FileDescriptor* original_file = - protobuf_unittest::TestAllTypes::descriptor()->file(); - - DescriptorPoolDatabase database(*DescriptorPool::generated_pool()); - DescriptorPool pool(&database); - const FileDescriptor* file_from_database = - pool.FindFileByName(original_file->name()); - - ASSERT_TRUE(file_from_database != NULL); - - FileDescriptorProto original_file_proto; - original_file->CopyTo(&original_file_proto); - - FileDescriptorProto file_from_database_proto; - file_from_database->CopyTo(&file_from_database_proto); - - EXPECT_EQ(original_file_proto.DebugString(), - file_from_database_proto.DebugString()); -} - -TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) { - // Searching for a child of an existing descriptor should never fall back - // to the DescriptorDatabase even if it isn't found, because we know all - // children are already loaded. - CallCountingDatabase call_counter(&database_); - DescriptorPool pool(&call_counter); - - const FileDescriptor* file = pool.FindFileByName("foo.proto"); - ASSERT_TRUE(file != NULL); - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum"); - ASSERT_TRUE(test_enum != NULL); - const ServiceDescriptor* test_service = pool.FindServiceByName("TestService"); - ASSERT_TRUE(test_service != NULL); - - EXPECT_NE(0, call_counter.call_count_); - call_counter.Clear(); - - EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL); - EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL); - EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL); - EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL); - EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL); - - EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL); - EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL); - EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL); - EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL); - EXPECT_EQ(0, call_counter.call_count_); -} - -TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) { - // If FindFileContainingSymbol() or FindFileContainingExtension() return a - // file that is already in the DescriptorPool, it should not attempt to - // reload the file. - FalsePositiveDatabase false_positive_database(&database_); - MockErrorCollector error_collector; - DescriptorPool pool(&false_positive_database, &error_collector); - - // First make sure foo.proto is loaded. - const Descriptor* foo = pool.FindMessageTypeByName("Foo"); - ASSERT_TRUE(foo != NULL); - - // Try inducing false positives. - EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL); - EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL); - - // No errors should have been reported. (If foo.proto was incorrectly - // loaded multiple times, errors would have been reported.) - EXPECT_EQ("", error_collector.text_); -} - -TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) { - ErrorDescriptorDatabase error_database; - MockErrorCollector error_collector; - DescriptorPool pool(&error_database, &error_collector); - - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - error_collector.text_.clear(); - EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL); - EXPECT_EQ("", error_collector.text_); -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc deleted file mode 100644 index c355bf5f..00000000 --- a/src/google/protobuf/dynamic_message.cc +++ /dev/null @@ -1,532 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// DynamicMessage is implemented by constructing a data structure which -// has roughly the same memory layout as a generated message would have. -// Then, we use GeneratedMessageReflection to implement our reflection -// interface. All the other operations we need to implement (e.g. -// parsing, copying, etc.) are already implemented in terms of -// Reflection, so the rest is easy. -// -// The up side of this strategy is that it's very efficient. We don't -// need to use hash_maps or generic representations of fields. The -// down side is that this is a low-level memory management hack which -// can be tricky to get right. -// -// As mentioned in the header, we only expose a DynamicMessageFactory -// publicly, not the DynamicMessage class itself. This is because -// GenericMessageReflection wants to have a pointer to a "default" -// copy of the class, with all fields initialized to their default -// values. We only want to construct one of these per message type, -// so DynamicMessageFactory stores a cache of default messages for -// each type it sees (each unique Descriptor pointer). The code -// refers to the "default" copy of the class as the "prototype". -// -// Note on memory allocation: This module often calls "operator new()" -// to allocate untyped memory, rather than calling something like -// "new uint8[]". This is because "operator new()" means "Give me some -// space which I can use as I please." while "new uint8[]" means "Give -// me an array of 8-bit integers.". In practice, the later may return -// a pointer that is not aligned correctly for general use. I believe -// Item 8 of "More Effective C++" discusses this in more detail, though -// I don't have the book on me right now so I'm not sure. - -#include <algorithm> -#include <google/protobuf/stubs/hash.h> - -#include <google/protobuf/stubs/common.h> - -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/repeated_field.h> -#include <google/protobuf/extension_set.h> -#include <google/protobuf/wire_format.h> - -namespace google { -namespace protobuf { - -using internal::WireFormat; -using internal::ExtensionSet; -using internal::GeneratedMessageReflection; -using internal::GenericRepeatedField; - - -// =================================================================== -// Some helper tables and functions... - -namespace { - -// Compute the byte size of the in-memory representation of the field. -int FieldSpaceUsed(const FieldDescriptor* field) { - typedef FieldDescriptor FD; // avoid line wrapping - if (field->label() == FD::LABEL_REPEATED) { - switch (field->cpp_type()) { - case FD::CPPTYPE_INT32 : return sizeof(RepeatedField<int32 >); - case FD::CPPTYPE_INT64 : return sizeof(RepeatedField<int64 >); - case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField<uint32 >); - case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField<uint64 >); - case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField<double >); - case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField<float >); - case FD::CPPTYPE_BOOL : return sizeof(RepeatedField<bool >); - case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >); - case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>); - - case FD::CPPTYPE_STRING: - return sizeof(RepeatedPtrField<string>); - break; - } - } else { - switch (field->cpp_type()) { - case FD::CPPTYPE_INT32 : return sizeof(int32 ); - case FD::CPPTYPE_INT64 : return sizeof(int64 ); - case FD::CPPTYPE_UINT32 : return sizeof(uint32 ); - case FD::CPPTYPE_UINT64 : return sizeof(uint64 ); - case FD::CPPTYPE_DOUBLE : return sizeof(double ); - case FD::CPPTYPE_FLOAT : return sizeof(float ); - case FD::CPPTYPE_BOOL : return sizeof(bool ); - case FD::CPPTYPE_ENUM : return sizeof(int ); - case FD::CPPTYPE_MESSAGE: return sizeof(Message*); - - case FD::CPPTYPE_STRING: - return sizeof(string*); - break; - } - } - - GOOGLE_LOG(DFATAL) << "Can't get here."; - return 0; -} - -struct DescendingFieldSizeOrder { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) { - // All repeated fields come first. - if (a->is_repeated()) { - if (b->is_repeated()) { - // Repeated fields and are not ordered with respect to each other. - return false; - } else { - return true; - } - } else if (b->is_repeated()) { - return false; - } else { - // Remaining fields in descending order by size. - return FieldSpaceUsed(a) > FieldSpaceUsed(b); - } - } -}; - -inline int DivideRoundingUp(int i, int j) { - return (i + (j - 1)) / j; -} - -static const int kSafeAlignment = sizeof(uint64); - -// Rounds the given byte offset up to the next offset aligned such that any -// type may be stored at it. -inline int AlignOffset(int offset) { - return DivideRoundingUp(offset, kSafeAlignment) * kSafeAlignment; -} - -#define bitsizeof(T) (sizeof(T) * 8) - -} // namespace - -// =================================================================== - -class DynamicMessage : public Message { - public: - struct TypeInfo { - int size; - int has_bits_offset; - int unknown_fields_offset; - int extensions_offset; - - // Not owned by the TypeInfo. - DynamicMessageFactory* factory; // The factory that created this object. - const DescriptorPool* pool; // The factory's DescriptorPool. - const Descriptor* type; // Type of this DynamicMessage. - - // Warning: The order in which the following pointers are defined is - // important (the prototype must be deleted *before* the offsets). - scoped_array<int> offsets; - scoped_ptr<const GeneratedMessageReflection> reflection; - scoped_ptr<const DynamicMessage> prototype; - }; - - DynamicMessage(const TypeInfo* type_info); - ~DynamicMessage(); - - // Called on the prototype after construction to initialize message fields. - void CrossLinkPrototypes(); - - // implements Message ---------------------------------------------- - - Message* New() const; - - int GetCachedSize() const; - void SetCachedSize(int size) const; - - const Descriptor* GetDescriptor() const; - const Reflection* GetReflection() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); - - inline bool is_prototype() const { - return type_info_->prototype == this || - // If type_info_->prototype is NULL, then we must be constructing - // the prototype now, which means we must be the prototype. - type_info_->prototype == NULL; - } - - inline void* OffsetToPointer(int offset) { - return reinterpret_cast<uint8*>(this) + offset; - } - inline const void* OffsetToPointer(int offset) const { - return reinterpret_cast<const uint8*>(this) + offset; - } - - const TypeInfo* type_info_; - - // TODO(kenton): Make this an atomic<int> when C++ supports it. - mutable int cached_byte_size_; -}; - -DynamicMessage::DynamicMessage(const TypeInfo* type_info) - : type_info_(type_info), - cached_byte_size_(0) { - // We need to call constructors for various fields manually and set - // default values where appropriate. We use placement new to call - // constructors. If you haven't heard of placement new, I suggest Googling - // it now. We use placement new even for primitive types that don't have - // constructors for consistency. (In theory, placement new should be used - // any time you are trying to convert untyped memory to typed memory, though - // in practice that's not strictly necessary for types that don't have a - // constructor.) - - const Descriptor* descriptor = type_info_->type; - - new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet; - - if (type_info_->extensions_offset != -1) { - new(OffsetToPointer(type_info_->extensions_offset)) - ExtensionSet(&type_info_->type, type_info_->pool, type_info_->factory); - } - - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - if (!field->is_repeated()) { \ - new(field_ptr) TYPE(field->default_value_##TYPE()); \ - } else { \ - new(field_ptr) RepeatedField<TYPE>(); \ - } \ - break; - - HANDLE_TYPE(INT32 , int32 ); - HANDLE_TYPE(INT64 , int64 ); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE(FLOAT , float ); - HANDLE_TYPE(BOOL , bool ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_ENUM: - if (!field->is_repeated()) { - new(field_ptr) int(field->default_value_enum()->number()); - } else { - new(field_ptr) RepeatedField<int>(); - } - break; - - case FieldDescriptor::CPPTYPE_STRING: - if (!field->is_repeated()) { - if (is_prototype()) { - new(field_ptr) const string*(&field->default_value_string()); - } else { - string* default_value = - *reinterpret_cast<string* const*>( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])); - new(field_ptr) string*(default_value); - } - } else { - new(field_ptr) RepeatedPtrField<string>(); - } - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: { - // If this object is the prototype, its CPPTYPE_MESSAGE fields - // must be initialized later, in CrossLinkPrototypes(), so we don't - // initialize them here. - if (!is_prototype()) { - if (!field->is_repeated()) { - new(field_ptr) Message*(NULL); - } else { - const RepeatedPtrField<Message>* prototype_field = - reinterpret_cast<const RepeatedPtrField<Message>*>( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])); - new(field_ptr) RepeatedPtrField<Message>( - prototype_field->prototype()); - } - } - break; - } - } - } -} - -DynamicMessage::~DynamicMessage() { - const Descriptor* descriptor = type_info_->type; - - reinterpret_cast<UnknownFieldSet*>( - OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet(); - - if (type_info_->extensions_offset != -1) { - reinterpret_cast<ExtensionSet*>( - OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet(); - } - - // We need to manually run the destructors for repeated fields and strings, - // just as we ran their constructors in the the DynamicMessage constructor. - // Additionally, if any singular embedded messages have been allocated, we - // need to delete them, UNLESS we are the prototype message of this type, - // in which case any embedded messages are other prototypes and shouldn't - // be touched. - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - - if (field->is_repeated()) { - GenericRepeatedField* field = - reinterpret_cast<GenericRepeatedField*>(field_ptr); - field->~GenericRepeatedField(); - - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - string* ptr = *reinterpret_cast<string**>(field_ptr); - if (ptr != &field->default_value_string()) { - delete ptr; - } - } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) && - !is_prototype()) { - Message* message = *reinterpret_cast<Message**>(field_ptr); - if (message != NULL) { - delete message; - } - } - } -} - -void DynamicMessage::CrossLinkPrototypes() { - // This should only be called on the prototype message. - GOOGLE_CHECK(is_prototype()); - - DynamicMessageFactory* factory = type_info_->factory; - const Descriptor* descriptor = type_info_->type; - - // Cross-link default messages. - for (int i = 0; i < descriptor->field_count(); i++) { - const FieldDescriptor* field = descriptor->field(i); - void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - // For fields with message types, we need to cross-link with the - // prototype for the field's type. - const Message* field_prototype = - factory->GetPrototype(field->message_type()); - - if (field->is_repeated()) { - // For repeated fields, we actually construct the RepeatedPtrField - // here, but only for fields with message types. All other repeated - // fields are constructed in DynamicMessage's constructor. - new(field_ptr) RepeatedPtrField<Message>(field_prototype); - } else { - // For singular fields, the field is just a pointer which should - // point to the prototype. (OK to const_cast here because the - // prototype itself will only be available const to the outside - // world.) - new(field_ptr) Message*(const_cast<Message*>(field_prototype)); - } - } - } -} - -Message* DynamicMessage::New() const { - void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size)); - memset(new_base, 0, type_info_->size); - return new(new_base) DynamicMessage(type_info_); -} - -int DynamicMessage::GetCachedSize() const { - return cached_byte_size_; -} - -void DynamicMessage::SetCachedSize(int size) const { - // This is theoretically not thread-compatible, but in practice it works - // because if multiple threads write this simultaneously, they will be - // writing the exact same value. - cached_byte_size_ = size; -} - -const Descriptor* DynamicMessage::GetDescriptor() const { - return type_info_->type; -} - -const Reflection* DynamicMessage::GetReflection() const { - return type_info_->reflection.get(); -} - -// =================================================================== - -struct DynamicMessageFactory::PrototypeMap { - typedef hash_map<const Descriptor*, const DynamicMessage::TypeInfo*> Map; - Map map_; -}; - -DynamicMessageFactory::DynamicMessageFactory() - : pool_(NULL), prototypes_(new PrototypeMap) { -} - -DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool) - : pool_(pool), prototypes_(new PrototypeMap) { -} - -DynamicMessageFactory::~DynamicMessageFactory() { - for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin(); - iter != prototypes_->map_.end(); ++iter) { - delete iter->second; - } -} - - -const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) { - const DynamicMessage::TypeInfo** target = &prototypes_->map_[type]; - if (*target != NULL) { - // Already exists. - return (*target)->prototype.get(); - } - - DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo; - *target = type_info; - - type_info->type = type; - type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_; - type_info->factory = this; - - // We need to construct all the structures passed to - // GeneratedMessageReflection's constructor. This includes: - // - A block of memory that contains space for all the message's fields. - // - An array of integers indicating the byte offset of each field within - // this block. - // - A big bitfield containing a bit for each field indicating whether - // or not that field is set. - - // Compute size and offsets. - int* offsets = new int[type->field_count()]; - type_info->offsets.reset(offsets); - - // Sort the fields of this message in descending order by size. We - // assume that if we then pack the fields tightly in this order, all fields - // will end up properly-aligned, since all field sizes are powers of two or - // are multiples of the system word size. - scoped_array<const FieldDescriptor*> ordered_fields( - new const FieldDescriptor*[type->field_count()]); - for (int i = 0; i < type->field_count(); i++) { - ordered_fields[i] = type->field(i); - } - stable_sort(&ordered_fields[0], &ordered_fields[type->field_count()], - DescendingFieldSizeOrder()); - - // Decide all field offsets by packing in order. - // We place the DynamicMessage object itself at the beginning of the allocated - // space. - int size = sizeof(DynamicMessage); - size = AlignOffset(size); - - // Next the has_bits, which is an array of uint32s. - type_info->has_bits_offset = size; - int has_bits_array_size = - DivideRoundingUp(type->field_count(), bitsizeof(uint32)); - size += has_bits_array_size * sizeof(uint32); - size = AlignOffset(size); - - // The ExtensionSet, if any. - if (type->extension_range_count() > 0) { - type_info->extensions_offset = size; - size += sizeof(ExtensionSet); - size = AlignOffset(size); - } else { - // No extensions. - type_info->extensions_offset = -1; - } - - // All the fields. We don't need to align after each field because they are - // sorted in descending size order, and the size of a type is always a - // multiple of its alignment. - for (int i = 0; i < type->field_count(); i++) { - offsets[ordered_fields[i]->index()] = size; - size += FieldSpaceUsed(ordered_fields[i]); - } - - // Add the UnknownFieldSet to the end. - size = AlignOffset(size); - type_info->unknown_fields_offset = size; - size += sizeof(UnknownFieldSet); - - // Align the final size to make sure no clever allocators think that - // alignment is not necessary. - size = AlignOffset(size); - type_info->size = size; - - // Allocate the prototype. - void* base = operator new(size); - memset(base, 0, size); - DynamicMessage* prototype = new(base) DynamicMessage(type_info); - type_info->prototype.reset(prototype); - - // Construct the reflection object. - type_info->reflection.reset( - new GeneratedMessageReflection( - type_info->type, - type_info->prototype.get(), - type_info->offsets.get(), - type_info->has_bits_offset, - type_info->unknown_fields_offset, - type_info->extensions_offset, - type_info->pool)); - - // Cross link prototypes. - prototype->CrossLinkPrototypes(); - - return prototype; -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h deleted file mode 100644 index e5a9f908..00000000 --- a/src/google/protobuf/dynamic_message.h +++ /dev/null @@ -1,105 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Defines an implementation of Message which can emulate types which are not -// known at compile-time. - -#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ -#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ - -#include <google/protobuf/message.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -// Defined in other files. -class Descriptor; // descriptor.h -class DescriptorPool; // descriptor.h - -// Constructs implementations of Message which can emulate types which are not -// known at compile-time. -// -// Sometimes you want to be able to manipulate protocol types that you don't -// know about at compile time. It would be nice to be able to construct -// a Message object which implements the message type given by any arbitrary -// Descriptor. DynamicMessage provides this. -// -// As it turns out, a DynamicMessage needs to construct extra -// information about its type in order to operate. Most of this information -// can be shared between all DynamicMessages of the same type. But, caching -// this information in some sort of global map would be a bad idea, since -// the cached information for a particular descriptor could outlive the -// descriptor itself. To avoid this problem, DynamicMessageFactory -// encapsulates this "cache". All DynamicMessages of the same type created -// from the same factory will share the same support data. Any Descriptors -// used with a particular factory must outlive the factory. -class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { - public: - // Construct a DynamicMessageFactory that will search for extensions in - // the DescriptorPool in which the exendee is defined. - DynamicMessageFactory(); - - // Construct a DynamicMessageFactory that will search for extensions in - // the given DescriptorPool. - DynamicMessageFactory(const DescriptorPool* pool); - ~DynamicMessageFactory(); - - // implements MessageFactory --------------------------------------- - - // Given a Descriptor, constructs the default (prototype) Message of that - // type. You can then call that message's New() method to construct a - // mutable message of that type. - // - // Calling this method twice with the same Descriptor returns the same - // object. The returned object remains property of the factory and will - // be destroyed when the factory is destroyed. Also, any objects created - // by calling the prototype's New() method share some data with the - // prototype, so these must be destoyed before the DynamicMessageFactory - // is destroyed. - // - // The given descriptor must outlive the returned message, and hence must - // outlive the DynamicMessageFactory. - // - // Note that while GetPrototype() is idempotent, it is not const. This - // implies that it is not thread-safe to call GetPrototype() on the same - // DynamicMessageFactory in two different threads simultaneously. However, - // the returned objects are just as thread-safe as any other Message. - const Message* GetPrototype(const Descriptor* type); - - private: - const DescriptorPool* pool_; - - // This struct just contains a hash_map. We can't #include <google/protobuf/stubs/hash.h> from - // this header due to hacks needed for hash_map portability in the open source - // release. Namely, stubs/hash.h, which defines hash_map portably, is not a - // public header (for good reason), but dynamic_message.h is, and public - // headers may only #include other public headers. - struct PrototypeMap; - scoped_ptr<PrototypeMap> prototypes_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__ - diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc deleted file mode 100644 index f7ed51f4..00000000 --- a/src/google/protobuf/dynamic_message_unittest.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Since the reflection interface for DynamicMessage is implemented by -// GenericMessageReflection, the only thing we really have to test is -// that DynamicMessage correctly sets up the information that -// GenericMessageReflection needs to use. So, we focus on that in this -// test. Other tests, such as generic_message_reflection_unittest and -// reflection_ops_unittest, cover the rest of the functionality used by -// DynamicMessage. - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/test_util.h> -#include <google/protobuf/unittest.pb.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -class DynamicMessageTest : public testing::Test { - protected: - DescriptorPool pool_; - DynamicMessageFactory factory_; - const Descriptor* descriptor_; - const Message* prototype_; - const Descriptor* extensions_descriptor_; - const Message* extensions_prototype_; - - DynamicMessageTest(): factory_(&pool_) {} - - virtual void SetUp() { - // We want to make sure that DynamicMessage works (particularly with - // extensions) even if we use descriptors that are *not* from compiled-in - // types, so we make copies of the descriptors for unittest.proto and - // unittest_import.proto. - FileDescriptorProto unittest_file; - FileDescriptorProto unittest_import_file; - - unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file); - unittest_import::ImportMessage::descriptor()->file()->CopyTo( - &unittest_import_file); - - ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL); - ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL); - - descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes"); - ASSERT_TRUE(descriptor_ != NULL); - prototype_ = factory_.GetPrototype(descriptor_); - - extensions_descriptor_ = - pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions"); - ASSERT_TRUE(extensions_descriptor_ != NULL); - extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_); - } -}; - -TEST_F(DynamicMessageTest, Descriptor) { - // Check that the descriptor on the DynamicMessage matches the descriptor - // passed to GetPrototype(). - EXPECT_EQ(prototype_->GetDescriptor(), descriptor_); -} - -TEST_F(DynamicMessageTest, OnePrototype) { - // Check that requesting the same prototype twice produces the same object. - EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_)); -} - -TEST_F(DynamicMessageTest, Defaults) { - // Check that all default values are set correctly in the initial message. - TestUtil::ReflectionTester reflection_tester(descriptor_); - reflection_tester.ExpectClearViaReflection(*prototype_); -} - -TEST_F(DynamicMessageTest, IndependentOffsets) { - // Check that all fields have independent offsets by setting each - // one to a unique value then checking that they all still have those - // unique values (i.e. they don't stomp each other). - scoped_ptr<Message> message(prototype_->New()); - TestUtil::ReflectionTester reflection_tester(descriptor_); - - reflection_tester.SetAllFieldsViaReflection(message.get()); - reflection_tester.ExpectAllFieldsSetViaReflection(*message); -} - -TEST_F(DynamicMessageTest, Extensions) { - // Check that extensions work. - scoped_ptr<Message> message(extensions_prototype_->New()); - TestUtil::ReflectionTester reflection_tester(extensions_descriptor_); - - reflection_tester.SetAllFieldsViaReflection(message.get()); - reflection_tester.ExpectAllFieldsSetViaReflection(*message); -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc deleted file mode 100644 index f679d7ae..00000000 --- a/src/google/protobuf/extension_set.cc +++ /dev/null @@ -1,703 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/extension_set.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/message.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/repeated_field.h> - -namespace google { -namespace protobuf { -namespace internal { - -// ------------------------------------------------------------------- -// Lookup functions - -const FieldDescriptor* -ExtensionSet::FindKnownExtensionOrDie(int number) const { - const FieldDescriptor* descriptor = - descriptor_pool_->FindExtensionByNumber(*extendee_, number); - if (descriptor == NULL) { - // This extension doesn't exist, so we have to crash. However, let's - // try to provide an informative error message. - if (descriptor_pool_ == DescriptorPool::generated_pool() && - message_factory_ == MessageFactory::generated_factory()) { - // This is probably the ExtensionSet for a generated class. - GOOGLE_LOG(FATAL) << ": No extension is registered for \"" - << (*extendee_)->full_name() << "\" with number " - << number << ". Perhaps you were trying to access it via " - "the Reflection interface, but you provided a " - "FieldDescriptor which did not come from a linked-in " - "message type? This is not permitted; linkin-in message " - "types cannot use non-linked-in extensions. Try " - "converting to a DynamicMessage first."; - } else { - // This is probably a DynamicMessage. - GOOGLE_LOG(FATAL) << ": No extension is registered for \"" - << (*extendee_)->full_name() << "\" with number " - << number << ". If you were using a DynamicMessage, " - "remember that you are only allowed to access extensions " - "which are defined in the DescriptorPool which you passed " - "to DynamicMessageFactory's constructor."; - } - } - return descriptor; -} - -const Message* -ExtensionSet::GetPrototype(const Descriptor* message_type) const { - return message_factory_->GetPrototype(message_type); -} - -// =================================================================== -// Constructors and basic methods. - -ExtensionSet::ExtensionSet(const Descriptor* const* extendee, - const DescriptorPool* pool, - MessageFactory* factory) - : extendee_(extendee), - descriptor_pool_(pool), - message_factory_(factory) { -} - -ExtensionSet::~ExtensionSet() { - for (map<int, Extension>::iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - iter->second.Free(); - } -} - -void ExtensionSet::AppendToList(vector<const FieldDescriptor*>* output) const { - for (map<int, Extension>::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - bool has = false; - if (iter->second.descriptor->is_repeated()) { - has = iter->second.GetSize() > 0; - } else { - has = !iter->second.is_cleared; - } - - if (has) { - output->push_back(iter->second.descriptor); - } - } -} - -bool ExtensionSet::Has(int number) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return false; - GOOGLE_DCHECK(!iter->second.descriptor->is_repeated()); - return !iter->second.is_cleared; -} - -int ExtensionSet::ExtensionSize(int number) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return false; - return iter->second.GetSize(); -} - -void ExtensionSet::ClearExtension(int number) { - map<int, Extension>::iterator iter = extensions_.find(number); - if (iter == extensions_.end()) return; - iter->second.Clear(); -} - -// =================================================================== -// Field accessors - -#define GOOGLE_DCHECK_TYPE(DESCRIPTOR, LABEL, CPPTYPE) \ - GOOGLE_DCHECK_EQ(DESCRIPTOR->label(), FieldDescriptor::LABEL_##LABEL); \ - GOOGLE_DCHECK_EQ(DESCRIPTOR->cpp_type(), FieldDescriptor::CPPTYPE_##CPPTYPE) - -// ------------------------------------------------------------------- -// Primitives - -#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \ - \ -LOWERCASE ExtensionSet::Get##CAMELCASE(int number) const { \ - map<int, Extension>::const_iterator iter = extensions_.find(number); \ - if (iter == extensions_.end()) { \ - /* Not present. Return the default value. */ \ - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); \ - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, UPPERCASE); \ - return descriptor->default_value_##LOWERCASE(); \ - } else { \ - GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, UPPERCASE); \ - return iter->second.LOWERCASE##_value; \ - } \ -} \ - \ -void ExtensionSet::Set##CAMELCASE(int number, LOWERCASE value) { \ - Extension* extension = &extensions_[number]; \ - if (extension->descriptor == NULL) { \ - /* Not previoulsy present. Initialize it. */ \ - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); \ - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, UPPERCASE); \ - extension->descriptor = descriptor; \ - extension->LOWERCASE##_value = descriptor->default_value_##LOWERCASE(); \ - } else { \ - GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, UPPERCASE); \ - extension->is_cleared = false; \ - } \ - extension->LOWERCASE##_value = value; \ -} \ - \ -LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \ - map<int, Extension>::const_iterator iter = extensions_.find(number); \ - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, UPPERCASE); \ - return iter->second.repeated_##LOWERCASE##_value->Get(index); \ -} \ - \ -void ExtensionSet::SetRepeated##CAMELCASE( \ - int number, int index, LOWERCASE value) { \ - map<int, Extension>::iterator iter = extensions_.find(number); \ - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \ - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, UPPERCASE); \ - iter->second.repeated_##LOWERCASE##_value->Set(index, value); \ -} \ - \ -void ExtensionSet::Add##CAMELCASE(int number, LOWERCASE value) { \ - Extension* extension = &extensions_[number]; \ - if (extension->descriptor == NULL) { \ - /* Not previoulsy present. Initialize it. */ \ - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); \ - GOOGLE_DCHECK_TYPE(descriptor, REPEATED, UPPERCASE); \ - extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \ - extension->descriptor = descriptor; \ - } else { \ - GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, UPPERCASE); \ - } \ - extension->repeated_##LOWERCASE##_value->Add(value); \ -} - -PRIMITIVE_ACCESSORS( INT32, int32, Int32) -PRIMITIVE_ACCESSORS( INT64, int64, Int64) -PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32) -PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64) -PRIMITIVE_ACCESSORS( FLOAT, float, Float) -PRIMITIVE_ACCESSORS(DOUBLE, double, Double) -PRIMITIVE_ACCESSORS( BOOL, bool, Bool) - -#undef PRIMITIVE_ACCESSORS - -// ------------------------------------------------------------------- -// Enums - -int ExtensionSet::GetEnum(int number) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) { - // Not present. Return the default value. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, ENUM); - return descriptor->default_value_enum()->number(); - } else { - GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, ENUM); - return iter->second.enum_value; - } -} - -void ExtensionSet::SetEnum(int number, int value) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, ENUM); - extension->descriptor = descriptor; - extension->enum_value = descriptor->default_value_enum()->number(); - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, ENUM); - extension->is_cleared = false; - } - GOOGLE_DCHECK(extension->descriptor->enum_type()->FindValueByNumber(value) != NULL); - extension->enum_value = value; -} - -int ExtensionSet::GetRepeatedEnum(int number, int index) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, ENUM); - return iter->second.repeated_enum_value->Get(index); -} - -void ExtensionSet::SetRepeatedEnum(int number, int index, int value) { - map<int, Extension>::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, ENUM); - GOOGLE_DCHECK(iter->second.descriptor->enum_type() - ->FindValueByNumber(value) != NULL); - iter->second.repeated_enum_value->Set(index, value); -} - -void ExtensionSet::AddEnum(int number, int value) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, REPEATED, ENUM); - extension->repeated_enum_value = new RepeatedField<int>(); - extension->descriptor = descriptor; - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, ENUM); - } - GOOGLE_DCHECK(extension->descriptor->enum_type()->FindValueByNumber(value) != NULL); - extension->repeated_enum_value->Add(value); -} - -// ------------------------------------------------------------------- -// Strings - -const string& ExtensionSet::GetString(int number) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) { - // Not present. Return the default value. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, STRING); - return descriptor->default_value_string(); - } else { - GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, STRING); - return *iter->second.string_value; - } -} - -string* ExtensionSet::MutableString(int number) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, STRING); - extension->descriptor = descriptor; - extension->string_value = new string; - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, STRING); - extension->is_cleared = false; - } - return extension->string_value; -} - -const string& ExtensionSet::GetRepeatedString(int number, int index) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, STRING); - return iter->second.repeated_string_value->Get(index); -} - -string* ExtensionSet::MutableRepeatedString(int number, int index) { - map<int, Extension>::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, STRING); - return iter->second.repeated_string_value->Mutable(index); -} - -string* ExtensionSet::AddString(int number) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, REPEATED, STRING); - extension->repeated_string_value = new RepeatedPtrField<string>(); - extension->descriptor = descriptor; - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, STRING); - } - return extension->repeated_string_value->Add(); -} - -// ------------------------------------------------------------------- -// Messages - -const Message& ExtensionSet::GetMessage(int number) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - if (iter == extensions_.end()) { - // Not present. Return the default value. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, MESSAGE); - return *GetPrototype(descriptor->message_type()); - } else { - GOOGLE_DCHECK_TYPE(iter->second.descriptor, OPTIONAL, MESSAGE); - return *iter->second.message_value; - } -} - -Message* ExtensionSet::MutableMessage(int number) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, OPTIONAL, MESSAGE); - extension->descriptor = descriptor; - extension->message_value = GetPrototype(descriptor->message_type())->New(); - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, OPTIONAL, MESSAGE); - extension->is_cleared = false; - } - return extension->message_value; -} - -const Message& ExtensionSet::GetRepeatedMessage(int number, int index) const { - map<int, Extension>::const_iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, MESSAGE); - return iter->second.repeated_message_value->Get(index); -} - -Message* ExtensionSet::MutableRepeatedMessage(int number, int index) { - map<int, Extension>::iterator iter = extensions_.find(number); - GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; - GOOGLE_DCHECK_TYPE(iter->second.descriptor, REPEATED, MESSAGE); - return iter->second.repeated_message_value->Mutable(index); -} - -Message* ExtensionSet::AddMessage(int number) { - Extension* extension = &extensions_[number]; - if (extension->descriptor == NULL) { - // Not previoulsy present. Initialize it. - const FieldDescriptor* descriptor = FindKnownExtensionOrDie(number); - GOOGLE_DCHECK_TYPE(descriptor, REPEATED, MESSAGE); - extension->repeated_message_value = - new RepeatedPtrField<Message>(GetPrototype(descriptor->message_type())); - extension->descriptor = descriptor; - } else { - GOOGLE_DCHECK_TYPE(extension->descriptor, REPEATED, MESSAGE); - } - return extension->repeated_message_value->Add(); -} - -#undef GOOGLE_DCHECK_TYPE - -// =================================================================== - -void ExtensionSet::Clear() { - for (map<int, Extension>::iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - iter->second.Clear(); - } -} - -namespace { - -// A helper function for merging RepeatedFields... -// TODO(kenton): Implement this as a method of RepeatedField? Make generated -// MergeFrom methods use it? - -template <typename Type> -void MergeRepeatedFields(const RepeatedField<Type>& source, - RepeatedField<Type>* destination) { - destination->Reserve(destination->size() + source.size()); - for (int i = 0; i < source.size(); i++) { - destination->Add(source.Get(i)); - } -} - -void MergeRepeatedFields(const RepeatedPtrField<string>& source, - RepeatedPtrField<string>* destination) { - destination->Reserve(destination->size() + source.size()); - for (int i = 0; i < source.size(); i++) { - destination->Add()->assign(source.Get(i)); - } -} - -void MergeRepeatedFields(const RepeatedPtrField<Message>& source, - RepeatedPtrField<Message>* destination) { - destination->Reserve(destination->size() + source.size()); - for (int i = 0; i < source.size(); i++) { - destination->Add()->MergeFrom(source.Get(i)); - } -} - -} // namespace - -void ExtensionSet::MergeFrom(const ExtensionSet& other) { - GOOGLE_DCHECK_EQ(*extendee_, *other.extendee_); - - for (map<int, Extension>::const_iterator iter = other.extensions_.begin(); - iter != other.extensions_.end(); ++iter) { - const FieldDescriptor* field = iter->second.descriptor; - if (field->is_repeated()) { - const Extension& other_extension = iter->second; - Extension* extension = &extensions_[iter->first]; - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - if (extension->descriptor == NULL) { \ - extension->descriptor = field; \ - extension->repeated_##LOWERCASE##_value = \ - new REPEATED_TYPE; \ - } \ - MergeRepeatedFields( \ - *other_extension.repeated_##LOWERCASE##_value, \ - extension->repeated_##LOWERCASE##_value); \ - break; - - HANDLE_TYPE( INT32, int32, RepeatedField < int32>); - HANDLE_TYPE( INT64, int64, RepeatedField < int64>); - HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>); - HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>); - HANDLE_TYPE( FLOAT, float, RepeatedField < float>); - HANDLE_TYPE( DOUBLE, double, RepeatedField < double>); - HANDLE_TYPE( BOOL, bool, RepeatedField < bool>); - HANDLE_TYPE( ENUM, enum, RepeatedField < int>); - HANDLE_TYPE( STRING, string, RepeatedPtrField< string>); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - if (extension->descriptor == NULL) { - extension->descriptor = field; - extension->repeated_message_value = new RepeatedPtrField<Message>( - other_extension.repeated_message_value->prototype()); - } - MergeRepeatedFields( - *other_extension.repeated_message_value, - extension->repeated_message_value); - break; - } - } else { - if (!iter->second.is_cleared) { - switch (field->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - Set##CAMELCASE(iter->first, iter->second.LOWERCASE##_value); \ - break; - - HANDLE_TYPE( INT32, int32, Int32); - HANDLE_TYPE( INT64, int64, Int64); - HANDLE_TYPE(UINT32, uint32, UInt32); - HANDLE_TYPE(UINT64, uint64, UInt64); - HANDLE_TYPE( FLOAT, float, Float); - HANDLE_TYPE(DOUBLE, double, Double); - HANDLE_TYPE( BOOL, bool, Bool); - HANDLE_TYPE( ENUM, enum, Enum); -#undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_STRING: - SetString(iter->first, *iter->second.string_value); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - MutableMessage(iter->first)->MergeFrom(*iter->second.message_value); - break; - } - } - } - } -} - -bool ExtensionSet::IsInitialized() const { - // Extensions are never requried. However, we need to check that all - // embedded messages are initialized. - for (map<int, Extension>::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - const Extension& extension = iter->second; - if (extension.descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (extension.descriptor->is_repeated()) { - for (int i = 0; i < extension.repeated_message_value->size(); i++) { - if (!extension.repeated_message_value->Get(i).IsInitialized()) { - return false; - } - } - } else { - if (!extension.is_cleared) { - if (!extension.message_value->IsInitialized()) return false; - } - } - } - } - - return true; -} - -bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, - Message* message) { - const FieldDescriptor* field = - message->GetReflection() - ->FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag)); - - return WireFormat::ParseAndMergeField(tag, field, message, input); -} - -bool ExtensionSet::SerializeWithCachedSizes( - int start_field_number, int end_field_number, - const Message& message, - io::CodedOutputStream* output) const { - map<int, Extension>::const_iterator iter; - for (iter = extensions_.lower_bound(start_field_number); - iter != extensions_.end() && iter->first < end_field_number; - ++iter) { - if (!iter->second.SerializeFieldWithCachedSizes(message, output)) { - return false; - } - } - - return true; -} - -int ExtensionSet::ByteSize(const Message& message) const { - int total_size = 0; - - for (map<int, Extension>::const_iterator iter = extensions_.begin(); - iter != extensions_.end(); ++iter) { - total_size += iter->second.ByteSize(message); - } - - return total_size; -} - -// =================================================================== -// Methods of ExtensionSet::Extension - -void ExtensionSet::Extension::Clear() { - if (descriptor->is_repeated()) { - switch (descriptor->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - repeated_##LOWERCASE##_value->Clear(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - } else { - if (!is_cleared) { - switch (descriptor->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - LOWERCASE##_value = descriptor->default_value_##LOWERCASE(); \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE(UINT32, uint32); - HANDLE_TYPE(UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE(DOUBLE, double); - HANDLE_TYPE( BOOL, bool); -#undef HANDLE_TYPE - case FieldDescriptor::CPPTYPE_ENUM: - enum_value = descriptor->default_value_enum()->number(); - break; - case FieldDescriptor::CPPTYPE_STRING: - if (descriptor->has_default_value()) { - string_value->assign(descriptor->default_value_string()); - } else { - string_value->clear(); - } - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - message_value->Clear(); - break; - } - - is_cleared = true; - } - } -} - -bool ExtensionSet::Extension::SerializeFieldWithCachedSizes( - const Message& message, - io::CodedOutputStream* output) const { - if (descriptor->is_repeated() || !is_cleared) { - return WireFormat::SerializeFieldWithCachedSizes( - descriptor, message, output); - } else { - return true; - } -} - -int64 ExtensionSet::Extension::ByteSize(const Message& message) const { - if (descriptor->is_repeated() || !is_cleared) { - return WireFormat::FieldByteSize(descriptor, message); - } else { - // Cleared, non-repeated field. - return 0; - } -} - -int ExtensionSet::Extension::GetSize() const { - GOOGLE_DCHECK(descriptor->is_repeated()); - switch (descriptor->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - return repeated_##LOWERCASE##_value->size() - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; -} - -void ExtensionSet::Extension::Free() { - if (descriptor->is_repeated()) { - switch (descriptor->cpp_type()) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - delete repeated_##LOWERCASE##_value; \ - break - - HANDLE_TYPE( INT32, int32); - HANDLE_TYPE( INT64, int64); - HANDLE_TYPE( UINT32, uint32); - HANDLE_TYPE( UINT64, uint64); - HANDLE_TYPE( FLOAT, float); - HANDLE_TYPE( DOUBLE, double); - HANDLE_TYPE( BOOL, bool); - HANDLE_TYPE( ENUM, enum); - HANDLE_TYPE( STRING, string); - HANDLE_TYPE(MESSAGE, message); -#undef HANDLE_TYPE - } - } else { - switch (descriptor->cpp_type()) { - case FieldDescriptor::CPPTYPE_STRING: - delete string_value; - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - delete message_value; - break; - default: - break; - } - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h deleted file mode 100644 index c8e124f8..00000000 --- a/src/google/protobuf/extension_set.h +++ /dev/null @@ -1,556 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__ -#define GOOGLE_PROTOBUF_EXTENSION_SET_H__ - -#include <vector> -#include <stack> -#include <map> -#include <utility> -#include <string> - -#include <google/protobuf/message.h> - -namespace google { -namespace protobuf { - class Descriptor; // descriptor.h - class FieldDescriptor; // descriptor.h - class DescriptorPool; // descriptor.h - class Message; // message.h - class MessageFactory; // message.h - namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h - } - template <typename Element> class RepeatedField; // repeated_field.h - template <typename Element> class RepeatedPtrField; // repeated_field.h -} - -namespace protobuf { -namespace internal { - -// This is an internal helper class intended for use within the protocol buffer -// library and generated classes. Clients should not use it directly. Instead, -// use the generated accessors such as GetExtension() of the class being -// extended. -// -// This class manages extensions for a protocol message object. The -// message's HasExtension(), GetExtension(), MutableExtension(), and -// ClearExtension() methods are just thin wrappers around the embedded -// ExtensionSet. When parsing, if a tag number is encountered which is -// inside one of the message type's extension ranges, the tag is passed -// off to the ExtensionSet for parsing. Etc. -class LIBPROTOBUF_EXPORT ExtensionSet { - public: - // Construct an ExtensionSet. - // extendee: Descriptor for the type being extended. We pass in a pointer - // to a pointer to the extendee to get around an initialization - // problem: when we create the ExtensionSet for a message type, - // its descriptor may not exist yet. But we know where that - // descriptor pointer will be placed, and by the time it's used - // by this ExtensionSet it will be fully initialized, so passing - // a pointer to that location works. Note that this problem - // will only occur for messages defined in descriptor.proto. - // pool: DescriptorPool to search for extension definitions. - // factory: MessageFactory used to construct implementations of messages - // for extensions with message type. This factory must be able - // to construct any message type found in "pool". - // All three objects remain property of the caller and must outlive the - // ExtensionSet. - ExtensionSet(const Descriptor* const* extendee, - const DescriptorPool* pool, - MessageFactory* factory); - - ~ExtensionSet(); - - // Add all fields which are currently present to the given vector. This - // is useful to implement Reflection::ListFields(). - void AppendToList(vector<const FieldDescriptor*>* output) const; - - // ================================================================= - // Accessors - // - // Generated message classes include type-safe templated wrappers around - // these methods. Generally you should use those rather than call these - // directly, unless you are doing low-level memory management. - // - // When calling any of these accessors, the extension number requested - // MUST exist in the DescriptorPool provided to the constructor. Otheriwse, - // the method will fail an assert. Normally, though, you would not call - // these directly; you would either call the generated accessors of your - // message class (e.g. GetExtension()) or you would call the accessors - // of the reflection interface. In both cases, it is impossible to - // trigger this assert failure: the generated accessors only accept - // linked-in extension types as parameters, while the Reflection interface - // requires you to provide the FieldDescriptor describing the extension. - // - // When calling any of these accessors, a protocol-compiler-generated - // implementation of the extension corresponding to the number MUST - // be linked in, and the FieldDescriptor used to refer to it MUST be - // the one generated by that linked-in code. Otherwise, the method will - // die on an assert failure. The message objects returned by the message - // accessors are guaranteed to be of the correct linked-in type. - // - // These methods pretty much match Reflection except that: - // - They're not virtual. - // - They identify fields by number rather than FieldDescriptors. - // - They identify enum values using integers rather than descriptors. - // - Strings provide Mutable() in addition to Set() accessors. - - bool Has(int number) const; - int ExtensionSize(int number) const; // Size of a repeated extension. - void ClearExtension(int number); - - // singular fields ------------------------------------------------- - - int32 GetInt32 (int number) const; - int64 GetInt64 (int number) const; - uint32 GetUInt32(int number) const; - uint64 GetUInt64(int number) const; - float GetFloat (int number) const; - double GetDouble(int number) const; - bool GetBool (int number) const; - int GetEnum (int number) const; - const string & GetString (int number) const; - const Message& GetMessage(int number) const; - - void SetInt32 (int number, int32 value); - void SetInt64 (int number, int64 value); - void SetUInt32(int number, uint32 value); - void SetUInt64(int number, uint64 value); - void SetFloat (int number, float value); - void SetDouble(int number, double value); - void SetBool (int number, bool value); - void SetEnum (int number, int value); - void SetString(int number, const string& value); - string * MutableString (int number); - Message* MutableMessage(int number); - - // repeated fields ------------------------------------------------- - - int32 GetRepeatedInt32 (int number, int index) const; - int64 GetRepeatedInt64 (int number, int index) const; - uint32 GetRepeatedUInt32(int number, int index) const; - uint64 GetRepeatedUInt64(int number, int index) const; - float GetRepeatedFloat (int number, int index) const; - double GetRepeatedDouble(int number, int index) const; - bool GetRepeatedBool (int number, int index) const; - int GetRepeatedEnum (int number, int index) const; - const string & GetRepeatedString (int number, int index) const; - const Message& GetRepeatedMessage(int number, int index) const; - - void SetRepeatedInt32 (int number, int index, int32 value); - void SetRepeatedInt64 (int number, int index, int64 value); - void SetRepeatedUInt32(int number, int index, uint32 value); - void SetRepeatedUInt64(int number, int index, uint64 value); - void SetRepeatedFloat (int number, int index, float value); - void SetRepeatedDouble(int number, int index, double value); - void SetRepeatedBool (int number, int index, bool value); - void SetRepeatedEnum (int number, int index, int value); - void SetRepeatedString(int number, int index, const string& value); - string * MutableRepeatedString (int number, int index); - Message* MutableRepeatedMessage(int number, int index); - - void AddInt32 (int number, int32 value); - void AddInt64 (int number, int64 value); - void AddUInt32(int number, uint32 value); - void AddUInt64(int number, uint64 value); - void AddFloat (int number, float value); - void AddDouble(int number, double value); - void AddBool (int number, bool value); - void AddEnum (int number, int value); - void AddString(int number, const string& value); - string * AddString (int number); - Message* AddMessage(int number); - - // ----------------------------------------------------------------- - // TODO(kenton): Hardcore memory management accessors - - // ================================================================= - // convenience methods for implementing methods of Message - // - // These could all be implemented in terms of the other methods of this - // class, but providing them here helps keep the generated code size down. - - void Clear(); - void MergeFrom(const ExtensionSet& other); - bool IsInitialized() const; - - // These parsing and serialization functions all want a pointer to the - // message object because they hand off the actual work to WireFormat, - // which works in terms of a reflection interface. Yes, this means there - // are some redundant virtual function calls that end up being made, but - // it probably doesn't matter much in practice, and the alternative would - // involve reproducing a lot of WireFormat's functionality. - - // Parses a single extension from the input. The input should start out - // positioned immediately after the tag. - bool ParseField(uint32 tag, io::CodedInputStream* input, Message* message); - - // Write all extension fields with field numbers in the range - // [start_field_number, end_field_number) - // to the output stream, using the cached sizes computed when ByteSize() was - // last called. Note that the range bounds are inclusive-exclusive. - bool SerializeWithCachedSizes(int start_field_number, - int end_field_number, - const Message& message, - io::CodedOutputStream* output) const; - - // Returns the total serialized size of all the extensions. - int ByteSize(const Message& message) const; - - private: - // Like FindKnownExtension(), but GOOGLE_CHECK-fail if not found. - const FieldDescriptor* FindKnownExtensionOrDie(int number) const; - - // Get the prototype for the message. - const Message* GetPrototype(const Descriptor* message_type) const; - - struct Extension { - union { - int32 int32_value; - int64 int64_value; - uint32 uint32_value; - uint64 uint64_value; - float float_value; - double double_value; - bool bool_value; - int enum_value; - string* string_value; - Message* message_value; - - RepeatedField <int32 >* repeated_int32_value; - RepeatedField <int64 >* repeated_int64_value; - RepeatedField <uint32 >* repeated_uint32_value; - RepeatedField <uint64 >* repeated_uint64_value; - RepeatedField <float >* repeated_float_value; - RepeatedField <double >* repeated_double_value; - RepeatedField <bool >* repeated_bool_value; - RepeatedField <int >* repeated_enum_value; - RepeatedPtrField<string >* repeated_string_value; - RepeatedPtrField<Message>* repeated_message_value; - }; - - const FieldDescriptor* descriptor; - - // For singular types, indicates if the extension is "cleared". This - // happens when an extension is set and then later cleared by the caller. - // We want to keep the Extension object around for reuse, so instead of - // removing it from the map, we just set is_cleared = true. This has no - // meaning for repeated types; for those, the size of the RepeatedField - // simply becomes zero when cleared. - bool is_cleared; - - Extension(): descriptor(NULL), is_cleared(false) {} - - // Some helper methods for operations on a single Extension. - bool SerializeFieldWithCachedSizes( - const Message& message, - io::CodedOutputStream* output) const; - int64 ByteSize(const Message& message) const; - void Clear(); - int GetSize() const; - void Free(); - }; - - // The Extension struct is small enough to be passed by value, so we use it - // directly as the value type in the map rather than use pointers. We use - // a map rather than hash_map here because we expect most ExtensionSets will - // only contain a small number of extensions whereas hash_map is optimized - // for 100 elements or more. Also, we want AppendToList() to order fields - // by field number. - map<int, Extension> extensions_; - const Descriptor* const* extendee_; - const DescriptorPool* descriptor_pool_; - MessageFactory* message_factory_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); -}; - -// These are just for convenience... -inline void ExtensionSet::SetString(int number, const string& value) { - MutableString(number)->assign(value); -} -inline void ExtensionSet::SetRepeatedString(int number, int index, - const string& value) { - MutableRepeatedString(number, index)->assign(value); -} -inline void ExtensionSet::AddString(int number, const string& value) { - AddString(number)->assign(value); -} - -// =================================================================== -// Implementation details -// -// DO NOT DEPEND ON ANYTHING BELOW THIS POINT. This is for use from -// generated code only. - -// ------------------------------------------------------------------- -// Template magic - -// First we have a set of classes representing "type traits" for different -// field types. A type traits class knows how to implement basic accessors -// for extensions of a particular type given an ExtensionSet. The signature -// for a type traits class looks like this: -// -// class TypeTraits { -// public: -// typedef ? ConstType; -// typedef ? MutableType; -// -// static inline ConstType Get(int number, const ExtensionSet& set); -// static inline void Set(int number, ConstType value, ExtensionSet* set); -// static inline MutableType Mutable(int number, ExtensionSet* set); -// -// // Variants for repeated fields. -// static inline ConstType Get(int number, const ExtensionSet& set, -// int index); -// static inline void Set(int number, int index, -// ConstType value, ExtensionSet* set); -// static inline MutableType Mutable(int number, int index, -// ExtensionSet* set); -// static inline void Add(int number, ConstType value, ExtensionSet* set); -// static inline MutableType Add(int number, ExtensionSet* set); -// }; -// -// Not all of these methods make sense for all field types. For example, the -// "Mutable" methods only make sense for strings and messages, and the -// repeated methods only make sense for repeated types. So, each type -// traits class implements only the set of methods from this signature that it -// actually supports. This will cause a compiler error if the user tries to -// access an extension using a method that doesn't make sense for its type. -// For example, if "foo" is an extension of type "optional int32", then if you -// try to write code like: -// my_message.MutableExtension(foo) -// you will get a compile error because PrimitiveTypeTraits<int32> does not -// have a "Mutable()" method. - -// ------------------------------------------------------------------- -// PrimitiveTypeTraits - -// Since the ExtensionSet has different methods for each primitive type, -// we must explicitly define the methods of the type traits class for each -// known type. -template <typename Type> -class PrimitiveTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set); - static inline void Set(int number, ConstType value, ExtensionSet* set); -}; - -template <typename Type> -class RepeatedPrimitiveTypeTraits { - public: - typedef Type ConstType; - - static inline Type Get(int number, const ExtensionSet& set, int index); - static inline void Set(int number, int index, Type value, ExtensionSet* set); - static inline void Add(int number, Type value, ExtensionSet* set); -}; - -#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ -template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \ - int number, const ExtensionSet& set) { \ - return set.Get##METHOD(number); \ -} \ -template<> inline void PrimitiveTypeTraits<TYPE>::Set( \ - int number, ConstType value, ExtensionSet* set) { \ - set->Set##METHOD(number, value); \ -} \ - \ -template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \ - int number, const ExtensionSet& set, int index) { \ - return set.GetRepeated##METHOD(number, index); \ -} \ -template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \ - int number, int index, ConstType value, ExtensionSet* set) { \ - set->SetRepeated##METHOD(number, index, value); \ -} \ -template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \ - int number, ConstType value, ExtensionSet* set) { \ - set->Add##METHOD(number, value); \ -} - -PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float) -PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double) -PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool) - -#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE - -// ------------------------------------------------------------------- -// StringTypeTraits - -// Strings support both Set() and Mutable(). -class LIBPROTOBUF_EXPORT StringTypeTraits { - public: - typedef const string& ConstType; - typedef string* MutableType; - - static inline const string& Get(int number, const ExtensionSet& set) { - return set.GetString(number); - } - static inline void Set(int number, const string& value, ExtensionSet* set) { - set->SetString(number, value); - } - static inline string* Mutable(int number, ExtensionSet* set) { - return set->MutableString(number); - } -}; - -class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { - public: - typedef const string& ConstType; - typedef string* MutableType; - - static inline const string& Get(int number, const ExtensionSet& set, - int index) { - return set.GetRepeatedString(number, index); - } - static inline void Set(int number, int index, - const string& value, ExtensionSet* set) { - set->SetRepeatedString(number, index, value); - } - static inline string* Mutable(int number, int index, ExtensionSet* set) { - return set->MutableRepeatedString(number, index); - } - static inline void Add(int number, const string& value, ExtensionSet* set) { - set->AddString(number, value); - } - static inline string* Add(int number, ExtensionSet* set) { - return set->AddString(number); - } -}; - -// ------------------------------------------------------------------- -// EnumTypeTraits - -// ExtensionSet represents enums using integers internally, so we have to -// static_cast around. -template <typename Type> -class EnumTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set) { - return static_cast<Type>(set.GetEnum(number)); - } - static inline void Set(int number, ConstType value, ExtensionSet* set) { - set->SetEnum(number, value); - } -}; - -template <typename Type> -class RepeatedEnumTypeTraits { - public: - typedef Type ConstType; - - static inline ConstType Get(int number, const ExtensionSet& set, int index) { - return static_cast<Type>(set.GetRepeatedEnum(number, index)); - } - static inline void Set(int number, int index, - ConstType value, ExtensionSet* set) { - set->SetRepeatedEnum(number, index, value); - } - static inline void Add(int number, ConstType value, ExtensionSet* set) { - set->AddEnum(number, value); - } -}; - -// ------------------------------------------------------------------- -// MessageTypeTraits - -// ExtensionSet guarantees that when manipulating extensions with message -// types, the implementation used will be the compiled-in class representing -// that type. So, we can static_cast down to the exact type we expect. -template <typename Type> -class MessageTypeTraits { - public: - typedef const Type& ConstType; - typedef Type* MutableType; - - static inline ConstType Get(int number, const ExtensionSet& set) { - return static_cast<const Type&>(set.GetMessage(number)); - } - static inline MutableType Mutable(int number, ExtensionSet* set) { - return static_cast<Type*>(set->MutableMessage(number)); - } -}; - -template <typename Type> -class RepeatedMessageTypeTraits { - public: - typedef const Type& ConstType; - typedef Type* MutableType; - - static inline ConstType Get(int number, const ExtensionSet& set, int index) { - return static_cast<const Type&>(set.GetRepeatedMessage(number, index)); - } - static inline MutableType Mutable(int number, int index, ExtensionSet* set) { - return static_cast<Type*>(set->MutableRepeatedMessage(number, index)); - } - static inline MutableType Add(int number, ExtensionSet* set) { - return static_cast<Type*>(set->AddMessage(number)); - } -}; - -// ------------------------------------------------------------------- -// ExtensionIdentifier - -// This is the type of actual extension objects. E.g. if you have: -// extends Foo with optional int32 bar = 1234; -// then "bar" will be defined in C++ as: -// ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>> bar(1234); -// -// Note that we could, in theory, supply the field number as a template -// parameter, and thus make an instance of ExtensionIdentifier have no -// actual contents. However, if we did that, then using at extension -// identifier would not necessarily cause the compiler to output any sort -// of reference to any simple defined in the extension's .pb.o file. Some -// linkers will actually drop object files that are not explicitly referenced, -// but that would be bad because it would cause this extension to not be -// registered at static initialization, and therefore using it would crash. - -template <typename ExtendeeType, typename TypeTraitsType> -class ExtensionIdentifier { - public: - typedef TypeTraitsType TypeTraits; - typedef ExtendeeType Extendee; - - ExtensionIdentifier(int number): number_(number) {} - inline int number() const { return number_; } - private: - const int number_; -}; - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__ diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc deleted file mode 100644 index c10f8900..00000000 --- a/src/google/protobuf/extension_set_unittest.cc +++ /dev/null @@ -1,195 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/extension_set.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc -// except that it uses extensions rather than regular fields. - -TEST(ExtensionSetTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllExtensions message; - - TestUtil::ExpectExtensionsClear(message); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); -} - -TEST(ExtensionSetTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - TestUtil::ExpectAllExtensionsSet(message); - - TestUtil::ModifyRepeatedExtensions(&message); - TestUtil::ExpectRepeatedExtensionsModified(message); -} - -TEST(ExtensionSetTest, Clear) { - // Set every field to a unique value, clear the message, then check that - // it is cleared. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - message.Clear(); - TestUtil::ExpectExtensionsClear(message); - - // Unlike with the defaults test, we do NOT expect that requesting embedded - // messages will return a pointer to the default instance. Instead, they - // should return the objects that were created when mutable_blah() was - // called. - EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); -} - -TEST(ExtensionSetTest, ClearOneField) { - // Set every field to a unique value, then clear one value and insure that - // only that one value is cleared. - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - int64 original_value = - message.GetExtension(unittest::optional_int64_extension); - - // Clear the field and make sure it shows up as cleared. - message.ClearExtension(unittest::optional_int64_extension); - EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension)); - EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension)); - - // Other adjacent fields should not be cleared. - EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension)); - - // Make sure if we set it again, then all fields are set. - message.SetExtension(unittest::optional_int64_extension, original_value); - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ExtensionSetTest, CopyFrom) { - unittest::TestAllExtensions message1, message2; - string data; - - TestUtil::SetAllExtensions(&message1); - message2.CopyFrom(message1); - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(ExtensionSetTest, Serialization) { - // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire - // compatibility of extensions. - unittest::TestAllExtensions source; - unittest::TestAllTypes destination; - string data; - - TestUtil::SetAllExtensions(&source); - source.SerializeToString(&data); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(destination); -} - -TEST(ExtensionSetTest, Parsing) { - // Serialize as TestAllTypes and parse as TestAllExtensions. - unittest::TestAllTypes source; - unittest::TestAllExtensions destination; - string data; - - TestUtil::SetAllFields(&source); - source.SerializeToString(&data); - EXPECT_TRUE(destination.ParseFromString(data)); - TestUtil::ExpectAllExtensionsSet(destination); -} - -TEST(ExtensionSetTest, IsInitialized) { - // Test that IsInitialized() returns false if required fields in nested - // extensions are missing. - unittest::TestAllExtensions message; - - EXPECT_TRUE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::single); - EXPECT_FALSE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::single)->set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::single)->set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::single)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); - - message.AddExtension(unittest::TestRequired::multi); - EXPECT_FALSE(message.IsInitialized()); - - message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(ExtensionSetTest, MutableString) { - // Test the mutable string accessors. - unittest::TestAllExtensions message; - - message.MutableExtension(unittest::optional_string_extension)->assign("foo"); - EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension)); - EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension)); - - message.AddExtension(unittest::repeated_string_extension)->assign("bar"); - ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension)); - EXPECT_EQ("bar", - message.GetExtension(unittest::repeated_string_extension, 0)); -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc deleted file mode 100644 index 65530c7e..00000000 --- a/src/google/protobuf/generated_message_reflection.cc +++ /dev/null @@ -1,756 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <algorithm> -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/repeated_field.h> -#include <google/protobuf/extension_set.h> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace internal { - -namespace { const string kEmptyString; } - -// =================================================================== -// Helpers for reporting usage errors (e.g. trying to use GetInt32() on -// a string field). - -namespace { - -void ReportReflectionUsageError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, const char* description) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : " << description; -} - -const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = { - "INVALID_CPPTYPE", - "CPPTYPE_INT32", - "CPPTYPE_INT64", - "CPPTYPE_UINT32", - "CPPTYPE_UINT64", - "CPPTYPE_DOUBLE", - "CPPTYPE_FLOAT", - "CPPTYPE_BOOL", - "CPPTYPE_ENUM", - "CPPTYPE_STRING", - "CPPTYPE_MESSAGE" -}; - -static void ReportReflectionUsageTypeError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, - FieldDescriptor::CppType expected_type) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : Field is not the right type for this message:\n" - " Expected : " << cpptype_names_[expected_type] << "\n" - " Field type: " << cpptype_names_[field->cpp_type()]; -} - -static void ReportReflectionUsageEnumTypeError( - const Descriptor* descriptor, const FieldDescriptor* field, - const char* method, const EnumValueDescriptor* value) { - GOOGLE_LOG(FATAL) - << "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::" << method << "\n" - " Message type: " << descriptor->full_name() << "\n" - " Field : " << field->full_name() << "\n" - " Problem : Enum value did not match field type:\n" - " Expected : " << field->enum_type()->full_name() << "\n" - " Actual : " << value->full_name(); -} - -#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ - if (!(CONDITION)) \ - ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) -#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \ - USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION) -#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \ - USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION) - -#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \ - if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \ - ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \ - FieldDescriptor::CPPTYPE_##CPPTYPE) - -#define USAGE_CHECK_ENUM_VALUE(METHOD) \ - if (value->type() != field->enum_type()) \ - ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value) - -#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \ - USAGE_CHECK_EQ(field->containing_type(), descriptor_, \ - METHOD, "Field does not match message type."); -#define USAGE_CHECK_SINGULAR(METHOD) \ - USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ - "Field is repeated; the method requires a singular field.") -#define USAGE_CHECK_REPEATED(METHOD) \ - USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \ - "Field is singular; the method requires a repeated field.") - -#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \ - USAGE_CHECK_MESSAGE_TYPE(METHOD); \ - USAGE_CHECK_##LABEL(METHOD); \ - USAGE_CHECK_TYPE(METHOD, CPPTYPE) - -} // namespace - -// =================================================================== - -GeneratedMessageReflection::GeneratedMessageReflection( - const Descriptor* descriptor, - const Message* default_instance, - const int offsets[], - int has_bits_offset, - int unknown_fields_offset, - int extensions_offset, - const DescriptorPool* descriptor_pool) - : descriptor_ (descriptor), - default_instance_ (default_instance), - offsets_ (offsets), - has_bits_offset_ (has_bits_offset), - unknown_fields_offset_(unknown_fields_offset), - extensions_offset_(extensions_offset), - descriptor_pool_ ((descriptor_pool == NULL) ? - DescriptorPool::generated_pool() : - descriptor_pool) { -} - -GeneratedMessageReflection::~GeneratedMessageReflection() {} - -const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields( - const Message& message) const { - const void* ptr = reinterpret_cast<const uint8*>(&message) + - unknown_fields_offset_; - return *reinterpret_cast<const UnknownFieldSet*>(ptr); -} -UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( - Message* message) const { - void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_; - return reinterpret_cast<UnknownFieldSet*>(ptr); -} - -// ------------------------------------------------------------------- - -bool GeneratedMessageReflection::HasField(const Message& message, - const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(HasField); - USAGE_CHECK_SINGULAR(HasField); - - if (field->is_extension()) { - return GetExtensionSet(message).Has(field->number()); - } else { - return HasBit(message, field); - } -} - -int GeneratedMessageReflection::FieldSize(const Message& message, - const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(HasField); - USAGE_CHECK_REPEATED(HasField); - - if (field->is_extension()) { - return GetExtensionSet(message).ExtensionSize(field->number()); - } else { - return GetRaw<GenericRepeatedField>(message, field).GenericSize(); - } -} - -void GeneratedMessageReflection::ClearField( - Message* message, const FieldDescriptor* field) const { - USAGE_CHECK_MESSAGE_TYPE(ClearField); - - if (field->is_extension()) { - MutableExtensionSet(message)->ClearExtension(field->number()); - } else if (!field->is_repeated()) { - if (HasBit(*message, field)) { - ClearBit(message, field); - - // We need to set the field back to its default value. - switch (field->cpp_type()) { -#define CLEAR_TYPE(CPPTYPE, TYPE) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - *MutableRaw<TYPE>(message, field) = \ - field->default_value_##TYPE(); \ - break; - - CLEAR_TYPE(INT32 , int32 ); - CLEAR_TYPE(INT64 , int64 ); - CLEAR_TYPE(UINT32, uint32); - CLEAR_TYPE(UINT64, uint64); - CLEAR_TYPE(FLOAT , float ); - CLEAR_TYPE(DOUBLE, double); - CLEAR_TYPE(BOOL , bool ); -#undef CLEAR_TYPE - - case FieldDescriptor::CPPTYPE_ENUM: - *MutableRaw<int>(message, field) = - field->default_value_enum()->number(); - break; - - case FieldDescriptor::CPPTYPE_STRING: { - const string* default_ptr = DefaultRaw<const string*>(field); - string** value = MutableRaw<string*>(message, field); - if (*value != default_ptr) { - if (field->has_default_value()) { - (*value)->assign(field->default_value_string()); - } else { - (*value)->clear(); - } - } - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: - (*MutableRaw<Message*>(message, field))->Clear(); - break; - } - } - } else { - MutableRaw<GenericRepeatedField>(message, field)->GenericClear(); - } -} - -namespace { -// Comparison functor for sorting FieldDescriptors by field number. -struct FieldNumberSorter { - bool operator()(const FieldDescriptor* left, - const FieldDescriptor* right) const { - return left->number() < right->number(); - } -}; -} // namespace - -void GeneratedMessageReflection::ListFields( - const Message& message, - vector<const FieldDescriptor*>* output) const { - output->clear(); - - // Optimization: The default instance never has any fields set. - if (&message == default_instance_) return; - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (field->is_repeated()) { - if (GetRaw<GenericRepeatedField>(message, field).GenericSize() > 0) { - output->push_back(field); - } - } else { - if (HasBit(message, field)) { - output->push_back(field); - } - } - } - - if (extensions_offset_ != -1) { - GetExtensionSet(message).AppendToList(output); - } - - // ListFields() must sort output by field number. - sort(output->begin(), output->end(), FieldNumberSorter()); -} - -// ------------------------------------------------------------------- - -#undef DEFINE_PRIMITIVE_ACCESSORS -#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \ - PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \ - const Message& message, const FieldDescriptor* field) const { \ - USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \ - if (field->is_extension()) { \ - return GetExtensionSet(message).Get##TYPENAME(field->number()); \ - } else { \ - return GetField<TYPE>(message, field); \ - } \ - } \ - \ - void GeneratedMessageReflection::Set##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - PASSTYPE value) const { \ - USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \ - if (field->is_extension()) { \ - return MutableExtensionSet(message)->Set##TYPENAME( \ - field->number(), value); \ - } else { \ - SetField<TYPE>(message, field, value); \ - } \ - } \ - \ - PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \ - const Message& message, \ - const FieldDescriptor* field, int index) const { \ - USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - return GetExtensionSet(message).GetRepeated##TYPENAME( \ - field->number(), index); \ - } else { \ - return GetRepeatedField<TYPE>(message, field, index); \ - } \ - } \ - \ - void GeneratedMessageReflection::SetRepeated##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - int index, PASSTYPE value) const { \ - USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - MutableExtensionSet(message)->SetRepeated##TYPENAME( \ - field->number(), index, value); \ - } else { \ - SetRepeatedField<TYPE>(message, field, index, value); \ - } \ - } \ - \ - void GeneratedMessageReflection::Add##TYPENAME( \ - Message* message, const FieldDescriptor* field, \ - PASSTYPE value) const { \ - USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \ - if (field->is_extension()) { \ - MutableExtensionSet(message)->Add##TYPENAME(field->number(), value); \ - } else { \ - AddField<TYPE>(message, field, value); \ - } \ - } - -DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 ) -DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 ) -DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32) -DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64) -DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT ) -DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE) -DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL ) -#undef DEFINE_PRIMITIVE_ACCESSORS - -// ------------------------------------------------------------------- - -string GeneratedMessageReflection::GetString( - const Message& message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(GetString, SINGULAR, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetString(field->number()); - } else { - return *GetField<const string*>(message, field); - } -} - -const string& GeneratedMessageReflection::GetStringReference( - const Message& message, - const FieldDescriptor* field, string* scratch) const { - USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetString(field->number()); - } else { - return *GetField<const string*>(message, field); - } -} - - -void GeneratedMessageReflection::SetString( - Message* message, const FieldDescriptor* field, - const string& value) const { - USAGE_CHECK_ALL(SetString, SINGULAR, STRING); - if (field->is_extension()) { - return MutableExtensionSet(message)->SetString(field->number(), value); - } else { - string** ptr = MutableField<string*>(message, field); - if (*ptr == DefaultRaw<const string*>(field)) { - *ptr = new string(value); - } else { - (*ptr)->assign(value); - } - } -} - - -string GeneratedMessageReflection::GetRepeatedString( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedString(field->number(), index); - } else { - return GetRepeatedField<string>(message, field, index); - } -} - -const string& GeneratedMessageReflection::GetRepeatedStringReference( - const Message& message, const FieldDescriptor* field, - int index, string* scratch) const { - USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING); - if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedString(field->number(), index); - } else { - return GetRepeatedField<string>(message, field, index); - } -} - - -void GeneratedMessageReflection::SetRepeatedString( - Message* message, const FieldDescriptor* field, - int index, const string& value) const { - USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING); - if (field->is_extension()) { - MutableExtensionSet(message)->SetRepeatedString( - field->number(), index, value); - } else { - SetRepeatedField<string>(message, field, index, value); - } -} - - -void GeneratedMessageReflection::AddString( - Message* message, const FieldDescriptor* field, - const string& value) const { - USAGE_CHECK_ALL(AddString, REPEATED, STRING); - if (field->is_extension()) { - MutableExtensionSet(message)->AddString(field->number(), value); - } else { - AddField<string>(message, field, value); - } -} - - -// ------------------------------------------------------------------- - -const EnumValueDescriptor* GeneratedMessageReflection::GetEnum( - const Message& message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM); - - int value; - if (field->is_extension()) { - value = GetExtensionSet(message).GetEnum(field->number()); - } else { - value = GetField<int>(message, field); - } - const EnumValueDescriptor* result = - field->enum_type()->FindValueByNumber(value); - GOOGLE_CHECK(result != NULL); - return result; -} - -void GeneratedMessageReflection::SetEnum( - Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM); - USAGE_CHECK_ENUM_VALUE(SetEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->SetEnum(field->number(), value->number()); - } else { - SetField<int>(message, field, value->number()); - } -} - -const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM); - - int value; - if (field->is_extension()) { - value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index); - } else { - value = GetRepeatedField<int>(message, field, index); - } - const EnumValueDescriptor* result = - field->enum_type()->FindValueByNumber(value); - GOOGLE_CHECK(result != NULL); - return result; -} - -void GeneratedMessageReflection::SetRepeatedEnum( - Message* message, - const FieldDescriptor* field, int index, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); - USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->SetRepeatedEnum( - field->number(), index, value->number()); - } else { - SetRepeatedField<int>(message, field, index, value->number()); - } -} - -void GeneratedMessageReflection::AddEnum( - Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const { - USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); - USAGE_CHECK_ENUM_VALUE(AddEnum); - - if (field->is_extension()) { - MutableExtensionSet(message)->AddEnum(field->number(), value->number()); - } else { - AddField<int>(message, field, value->number()); - } -} - -// ------------------------------------------------------------------- - -const Message& GeneratedMessageReflection::GetMessage( - const Message& message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); - - if (field->is_extension()) { - return GetExtensionSet(message).GetMessage(field->number()); - } else { - const Message* result = GetRaw<const Message*>(message, field); - if (result == NULL) { - result = DefaultRaw<const Message*>(field); - } - return *result; - } -} - -Message* GeneratedMessageReflection::MutableMessage( - Message* message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); - - if (field->is_extension()) { - return MutableExtensionSet(message)->MutableMessage(field->number()); - } else { - Message** result = MutableField<Message*>(message, field); - if (*result == NULL) { - const Message* default_message = DefaultRaw<const Message*>(field); - *result = default_message->New(); - (*result)->CopyFrom(*default_message); - } - return *result; - } -} - -const Message& GeneratedMessageReflection::GetRepeatedMessage( - const Message& message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); - - if (field->is_extension()) { - return GetExtensionSet(message).GetRepeatedMessage(field->number(), index); - } else { - return GetRepeatedField<Message>(message, field, index); - } -} - -Message* GeneratedMessageReflection::MutableRepeatedMessage( - Message* message, const FieldDescriptor* field, int index) const { - USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); - - if (field->is_extension()) { - return MutableExtensionSet(message)->MutableRepeatedMessage( - field->number(), index); - } else { - return MutableRepeatedField<Message>(message, field, index); - } -} - -Message* GeneratedMessageReflection::AddMessage( - Message* message, const FieldDescriptor* field) const { - USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); - - if (field->is_extension()) { - return MutableExtensionSet(message)->AddMessage(field->number()); - } else { - return AddField<Message>(message, field); - } -} - -// ------------------------------------------------------------------- - -const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName( - const string& name) const { - if (extensions_offset_ == -1) return NULL; - - const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name); - if (result != NULL && result->containing_type() == descriptor_) { - return result; - } - - if (descriptor_->options().message_set_wire_format()) { - // MessageSet extensions may be identified by type name. - const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name); - if (type != NULL) { - // Look for a matching extension in the foreign type's scope. - for (int i = 0; i < type->extension_count(); i++) { - const FieldDescriptor* extension = type->extension(i); - if (extension->containing_type() == descriptor_ && - extension->type() == FieldDescriptor::TYPE_MESSAGE && - extension->is_optional() && - extension->message_type() == type) { - // Found it. - return extension; - } - } - } - } - - return NULL; -} - -const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber( - int number) const { - if (extensions_offset_ == -1) return NULL; - return descriptor_pool_->FindExtensionByNumber(descriptor_, number); -} - -// =================================================================== -// Some private helpers. - -// These simple template accessors obtain pointers (or references) to -// the given field. -template <typename Type> -inline const Type& GeneratedMessageReflection::GetRaw( - const Message& message, const FieldDescriptor* field) const { - const void* ptr = reinterpret_cast<const uint8*>(&message) + - offsets_[field->index()]; - return *reinterpret_cast<const Type*>(ptr); -} - -template <typename Type> -inline Type* GeneratedMessageReflection::MutableRaw( - Message* message, const FieldDescriptor* field) const { - void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()]; - return reinterpret_cast<Type*>(ptr); -} - -template <typename Type> -inline const Type& GeneratedMessageReflection::DefaultRaw( - const FieldDescriptor* field) const { - const void* ptr = reinterpret_cast<const uint8*>(default_instance_) + - offsets_[field->index()]; - return *reinterpret_cast<const Type*>(ptr); -} - -inline const uint32* GeneratedMessageReflection::GetHasBits( - const Message& message) const { - const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_; - return reinterpret_cast<const uint32*>(ptr); -} -inline uint32* GeneratedMessageReflection::MutableHasBits( - Message* message) const { - void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_; - return reinterpret_cast<uint32*>(ptr); -} - -inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet( - const Message& message) const { - GOOGLE_DCHECK_NE(extensions_offset_, -1); - const void* ptr = reinterpret_cast<const uint8*>(&message) + - extensions_offset_; - return *reinterpret_cast<const ExtensionSet*>(ptr); -} -inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet( - Message* message) const { - GOOGLE_DCHECK_NE(extensions_offset_, -1); - void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_; - return reinterpret_cast<ExtensionSet*>(ptr); -} - -// Simple accessors for manipulating has_bits_. -inline bool GeneratedMessageReflection::HasBit( - const Message& message, const FieldDescriptor* field) const { - return GetHasBits(message)[field->index() / 32] & - (1 << (field->index() % 32)); -} - -inline void GeneratedMessageReflection::SetBit( - Message* message, const FieldDescriptor* field) const { - MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32)); -} - -inline void GeneratedMessageReflection::ClearBit( - Message* message, const FieldDescriptor* field) const { - MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32)); -} - -// Template implementations of basic accessors. Inline because each -// template instance is only called from one location. These are -// used for all types except messages. -template <typename Type> -inline const Type& GeneratedMessageReflection::GetField( - const Message& message, const FieldDescriptor* field) const { - return GetRaw<Type>(message, field); -} - -template <typename Type> -inline void GeneratedMessageReflection::SetField( - Message* message, const FieldDescriptor* field, const Type& value) const { - *MutableRaw<Type>(message, field) = value; - SetBit(message, field); -} - -template <typename Type> -inline Type* GeneratedMessageReflection::MutableField( - Message* message, const FieldDescriptor* field) const { - SetBit(message, field); - return MutableRaw<Type>(message, field); -} - -template <typename Type> -inline const Type& GeneratedMessageReflection::GetRepeatedField( - const Message& message, const FieldDescriptor* field, int index) const { - return *reinterpret_cast<const Type*>( - GetRaw<GenericRepeatedField>(message, field).GenericGet(index)); -} - -template <typename Type> -inline void GeneratedMessageReflection::SetRepeatedField( - Message* message, const FieldDescriptor* field, - int index, const Type& value) const { - GenericRepeatedField* repeated = - MutableRaw<GenericRepeatedField>(message, field); - *reinterpret_cast<Type*>(repeated->GenericMutable(index)) = value; -} - -template <typename Type> -inline Type* GeneratedMessageReflection::MutableRepeatedField( - Message* message, const FieldDescriptor* field, int index) const { - GenericRepeatedField* repeated = - MutableRaw<GenericRepeatedField>(message, field); - return reinterpret_cast<Type*>(repeated->GenericMutable(index)); -} - -template <typename Type> -inline void GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field, const Type& value) const { - GenericRepeatedField* repeated = - MutableRaw<GenericRepeatedField>(message, field); - *reinterpret_cast<Type*>(repeated->GenericAdd()) = value; -} - -template <typename Type> -inline Type* GeneratedMessageReflection::AddField( - Message* message, const FieldDescriptor* field) const { - GenericRepeatedField* repeated = - MutableRaw<GenericRepeatedField>(message, field); - return reinterpret_cast<Type*>(repeated->GenericAdd()); -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h deleted file mode 100644 index 48df8dc1..00000000 --- a/src/google/protobuf/generated_message_reflection.h +++ /dev/null @@ -1,367 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ - -#include <string> -#include <vector> -#include <google/protobuf/message.h> -#include <google/protobuf/unknown_field_set.h> - - -namespace google { -namespace protobuf { - class DescriptorPool; - // Generated code needs this to have been forward-declared. Easier to do it - // here than to print it inside every .pb.h file. - class EnumDescriptor; -} - -namespace protobuf { -namespace internal { - -// Defined in this file. -class GeneratedMessageReflection; - -// Defined in other files. -class ExtensionSet; // extension_set.h - -// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use -// by generated code. This class is just a big hack that reduces code -// size. -// -// A GeneratedMessageReflection is an implementation of Reflection -// which expects all fields to be backed by simple variables located in -// memory. The locations are given using a base pointer and a set of -// offsets. -// -// It is required that the user represents fields of each type in a standard -// way, so that GeneratedMessageReflection can cast the void* pointer to -// the appropriate type. For primitive fields and string fields, each field -// should be represented using the obvious C++ primitive type. Enums and -// Messages are different: -// - Singular Message fields are stored as a pointer to a Message. These -// should start out NULL, except for in the default instance where they -// should start out pointing to other default instances. -// - Enum fields are stored as an int. This int must always contain -// a valid value, such that EnumDescriptor::FindValueByNumber() would -// not return NULL. -// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields -// of whatever type the individual field would be. Strings and -// Messages use RepeatedPtrFields while everything else uses -// RepeatedFields. -class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection { - public: - // Constructs a GeneratedMessageReflection. - // Parameters: - // descriptor: The descriptor for the message type being implemented. - // default_instance: The default instance of the message. This is only - // used to obtain pointers to default instances of embedded - // messages, which GetMessage() will return if the particular - // sub-message has not been initialized yet. (Thus, all - // embedded message fields *must* have non-NULL pointers - // in the default instance.) - // offsets: An array of ints giving the byte offsets, relative to - // the start of the message object, of each field. These can - // be computed at compile time using the - // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined - // below. - // has_bits_offset: Offset in the message of an array of uint32s of size - // descriptor->field_count()/32, rounded up. This is a - // bitfield where each bit indicates whether or not the - // corresponding field of the message has been initialized. - // The bit for field index i is obtained by the expression: - // has_bits[i / 32] & (1 << (i % 32)) - // unknown_fields_offset: Offset in the message of the UnknownFieldSet for - // the message. - // extensions_offset: Offset in the message of the ExtensionSet for the - // message, or -1 if the message type has no extension - // ranges. - // pool: DescriptorPool to search for extension definitions. Only - // used by FindKnownExtensionByName() and - // FindKnownExtensionByNumber(). - GeneratedMessageReflection(const Descriptor* descriptor, - const Message* default_instance, - const int offsets[], - int has_bits_offset, - int unknown_fields_offset, - int extensions_offset, - const DescriptorPool* pool); - ~GeneratedMessageReflection(); - - // implements Reflection ------------------------------------------- - - const UnknownFieldSet& GetUnknownFields(const Message& message) const; - UnknownFieldSet* MutableUnknownFields(Message* message) const; - - bool HasField(const Message& message, const FieldDescriptor* field) const; - int FieldSize(const Message& message, const FieldDescriptor* field) const; - void ClearField(Message* message, const FieldDescriptor* field) const; - void ListFields(const Message& message, - vector<const FieldDescriptor*>* output) const; - - int32 GetInt32 (const Message& message, - const FieldDescriptor* field) const; - int64 GetInt64 (const Message& message, - const FieldDescriptor* field) const; - uint32 GetUInt32(const Message& message, - const FieldDescriptor* field) const; - uint64 GetUInt64(const Message& message, - const FieldDescriptor* field) const; - float GetFloat (const Message& message, - const FieldDescriptor* field) const; - double GetDouble(const Message& message, - const FieldDescriptor* field) const; - bool GetBool (const Message& message, - const FieldDescriptor* field) const; - string GetString(const Message& message, - const FieldDescriptor* field) const; - const string& GetStringReference(const Message& message, - const FieldDescriptor* field, - string* scratch) const; - const EnumValueDescriptor* GetEnum(const Message& message, - const FieldDescriptor* field) const; - const Message& GetMessage(const Message& message, - const FieldDescriptor* field) const; - - void SetInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; - void SetInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; - void SetUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; - void SetUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; - void SetFloat (Message* message, - const FieldDescriptor* field, float value) const; - void SetDouble(Message* message, - const FieldDescriptor* field, double value) const; - void SetBool (Message* message, - const FieldDescriptor* field, bool value) const; - void SetString(Message* message, - const FieldDescriptor* field, - const string& value) const; - void SetEnum (Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const; - Message* MutableMessage(Message* message, const FieldDescriptor* field) const; - - int32 GetRepeatedInt32 (const Message& message, - const FieldDescriptor* field, int index) const; - int64 GetRepeatedInt64 (const Message& message, - const FieldDescriptor* field, int index) const; - uint32 GetRepeatedUInt32(const Message& message, - const FieldDescriptor* field, int index) const; - uint64 GetRepeatedUInt64(const Message& message, - const FieldDescriptor* field, int index) const; - float GetRepeatedFloat (const Message& message, - const FieldDescriptor* field, int index) const; - double GetRepeatedDouble(const Message& message, - const FieldDescriptor* field, int index) const; - bool GetRepeatedBool (const Message& message, - const FieldDescriptor* field, int index) const; - string GetRepeatedString(const Message& message, - const FieldDescriptor* field, int index) const; - const string& GetRepeatedStringReference(const Message& message, - const FieldDescriptor* field, - int index, string* scratch) const; - const EnumValueDescriptor* GetRepeatedEnum(const Message& message, - const FieldDescriptor* field, - int index) const; - const Message& GetRepeatedMessage(const Message& message, - const FieldDescriptor* field, - int index) const; - - // Set the value of a field. - void SetRepeatedInt32 (Message* message, - const FieldDescriptor* field, int index, int32 value) const; - void SetRepeatedInt64 (Message* message, - const FieldDescriptor* field, int index, int64 value) const; - void SetRepeatedUInt32(Message* message, - const FieldDescriptor* field, int index, uint32 value) const; - void SetRepeatedUInt64(Message* message, - const FieldDescriptor* field, int index, uint64 value) const; - void SetRepeatedFloat (Message* message, - const FieldDescriptor* field, int index, float value) const; - void SetRepeatedDouble(Message* message, - const FieldDescriptor* field, int index, double value) const; - void SetRepeatedBool (Message* message, - const FieldDescriptor* field, int index, bool value) const; - void SetRepeatedString(Message* message, - const FieldDescriptor* field, int index, - const string& value) const; - void SetRepeatedEnum(Message* message, const FieldDescriptor* field, - int index, const EnumValueDescriptor* value) const; - // Get a mutable pointer to a field with a message type. - Message* MutableRepeatedMessage(Message* message, - const FieldDescriptor* field, - int index) const; - - void AddInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; - void AddInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; - void AddUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; - void AddUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; - void AddFloat (Message* message, - const FieldDescriptor* field, float value) const; - void AddDouble(Message* message, - const FieldDescriptor* field, double value) const; - void AddBool (Message* message, - const FieldDescriptor* field, bool value) const; - void AddString(Message* message, - const FieldDescriptor* field, const string& value) const; - void AddEnum(Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const; - Message* AddMessage(Message* message, const FieldDescriptor* field) const; - - const FieldDescriptor* FindKnownExtensionByName(const string& name) const; - const FieldDescriptor* FindKnownExtensionByNumber(int number) const; - - private: - friend class GeneratedMessage; - - const Descriptor* descriptor_; - const Message* default_instance_; - const int* offsets_; - - int has_bits_offset_; - int unknown_fields_offset_; - int extensions_offset_; - - const DescriptorPool* descriptor_pool_; - - template <typename Type> - inline const Type& GetRaw(const Message& message, - const FieldDescriptor* field) const; - template <typename Type> - inline Type* MutableRaw(Message* message, - const FieldDescriptor* field) const; - template <typename Type> - inline const Type& DefaultRaw(const FieldDescriptor* field) const; - inline const Message* GetMessagePrototype(const FieldDescriptor* field) const; - - inline const uint32* GetHasBits(const Message& message) const; - inline uint32* MutableHasBits(Message* message) const; - inline const ExtensionSet& GetExtensionSet(const Message& message) const; - inline ExtensionSet* MutableExtensionSet(Message* message) const; - - inline bool HasBit(const Message& message, - const FieldDescriptor* field) const; - inline void SetBit(Message* message, - const FieldDescriptor* field) const; - inline void ClearBit(Message* message, - const FieldDescriptor* field) const; - - template <typename Type> - inline const Type& GetField(const Message& message, - const FieldDescriptor* field) const; - template <typename Type> - inline void SetField(Message* message, - const FieldDescriptor* field, const Type& value) const; - template <typename Type> - inline Type* MutableField(Message* message, - const FieldDescriptor* field) const; - template <typename Type> - inline const Type& GetRepeatedField(const Message& message, - const FieldDescriptor* field, - int index) const; - template <typename Type> - inline void SetRepeatedField(Message* message, - const FieldDescriptor* field, int index, - const Type& value) const; - template <typename Type> - inline Type* MutableRepeatedField(Message* message, - const FieldDescriptor* field, - int index) const; - template <typename Type> - inline void AddField(Message* message, - const FieldDescriptor* field, const Type& value) const; - template <typename Type> - inline Type* AddField(Message* message, - const FieldDescriptor* field) const; - - int GetExtensionNumberOrDie(const Descriptor* type) const; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); -}; - -// Returns the offset of the given field within the given aggregate type. -// This is equivalent to the ANSI C offsetof() macro. However, according -// to the C++ standard, offsetof() only works on POD types, and GCC -// enforces this requirement with a warning. In practice, this rule is -// unnecessarily strict; there is probably no compiler or platform on -// which the offsets of the direct fields of a class are non-constant. -// Fields inherited from superclasses *can* have non-constant offsets, -// but that's not what this macro will be used for. -// -// Note that we calculate relative to the pointer value 16 here since if we -// just use zero, GCC complains about dereferencing a NULL pointer. We -// choose 16 rather than some other number just in case the compiler would -// be confused by an unaligned pointer. -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ - (reinterpret_cast<const char*>( \ - &reinterpret_cast<const TYPE*>(16)->FIELD) - \ - reinterpret_cast<const char*>(16)) - -// There are some places in proto2 where dynamic_cast would be useful as an -// optimization. For example, take Message::MergeFrom(const Message& other). -// For a given generated message FooMessage, we generate these two methods: -// void MergeFrom(const FooMessage& other); -// void MergeFrom(const Message& other); -// The former method can be implemented directly in terms of FooMessage's -// inline accessors, but the latter method must work with the reflection -// interface. However, if the parameter to the latter method is actually of -// type FooMessage, then we'd like to be able to just call the other method -// as an optimization. So, we use dynamic_cast to check this. -// -// That said, dynamic_cast requires RTTI, which many people like to disable -// for performance and code size reasons. When RTTI is not available, we -// still need to produce correct results. So, in this case we have to fall -// back to using reflection, which is what we would have done anyway if the -// objects were not of the exact same class. -// -// dynamic_cast_if_available() implements this logic. If RTTI is -// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns -// NULL. -// -// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI. -// On MSVC, this should be detected automatically. -template<typename To, typename From> -inline To dynamic_cast_if_available(From from) { -#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI)) - return NULL; -#else - return dynamic_cast<To>(from); -#endif -} - - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc deleted file mode 100644 index d0e96bd8..00000000 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ /dev/null @@ -1,254 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// To test GeneratedMessageReflection, we actually let the protocol compiler -// generate a full protocol message implementation and then test its -// reflection interface. This is much easier and more maintainable than -// trying to create our own Message class for GeneratedMessageReflection -// to wrap. -// -// The tests here closely mirror some of the tests in -// compiler/cpp/unittest, except using the reflection interface -// rather than generated accessors. - -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/test_util.h> -#include <google/protobuf/unittest.pb.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -namespace { - -// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. -const FieldDescriptor* F(const string& name) { - const FieldDescriptor* result = - unittest::TestAllTypes::descriptor()->FindFieldByName(name); - GOOGLE_CHECK(result != NULL); - return result; -} - -TEST(GeneratedMessageReflectionTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - reflection_tester.ExpectClearViaReflection(message); - - const Reflection* reflection = message.GetReflection(); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &reflection->GetMessage(message, F("optionalgroup"))); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &reflection->GetMessage(message, F("optional_nested_message"))); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &reflection->GetMessage(message, F("optional_foreign_message"))); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &reflection->GetMessage(message, F("optional_import_message"))); -} - -TEST(GeneratedMessageReflectionTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - reflection_tester.SetAllFieldsViaReflection(&message); - TestUtil::ExpectAllFieldsSet(message); - reflection_tester.ExpectAllFieldsSetViaReflection(message); - - reflection_tester.ModifyRepeatedFieldsViaReflection(&message); - TestUtil::ExpectRepeatedFieldsModified(message); -} - -TEST(GeneratedMessageReflectionTest, GetStringReference) { - // Test that GetStringReference() returns the underlying string when it is - // a normal string field. - unittest::TestAllTypes message; - message.set_optional_string("foo"); - message.add_repeated_string("foo"); - - const Reflection* reflection = message.GetReflection(); - string scratch; - - EXPECT_EQ(&message.optional_string(), - &reflection->GetStringReference(message, F("optional_string"), &scratch)) - << "For simple string fields, GetStringReference() should return a " - "reference to the underlying string."; - EXPECT_EQ(&message.repeated_string(0), - &reflection->GetRepeatedStringReference(message, F("repeated_string"), - 0, &scratch)) - << "For simple string fields, GetRepeatedStringReference() should return " - "a reference to the underlying string."; -} - - -TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) { - // Check that after setting all fields and then clearing, getting an - // embedded message does NOT return the default instance. - unittest::TestAllTypes message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - - TestUtil::SetAllFields(&message); - message.Clear(); - - const Reflection* reflection = message.GetReflection(); - - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &reflection->GetMessage(message, F("optionalgroup"))); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &reflection->GetMessage(message, F("optional_nested_message"))); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &reflection->GetMessage(message, F("optional_foreign_message"))); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &reflection->GetMessage(message, F("optional_import_message"))); -} - -TEST(GeneratedMessageReflectionTest, Extensions) { - // Set every extension to a unique value then go back and check all those - // values. - unittest::TestAllExtensions message; - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllExtensions::descriptor()); - - reflection_tester.SetAllFieldsViaReflection(&message); - TestUtil::ExpectAllExtensionsSet(message); - reflection_tester.ExpectAllFieldsSetViaReflection(message); - - reflection_tester.ModifyRepeatedFieldsViaReflection(&message); - TestUtil::ExpectRepeatedExtensionsModified(message); -} - -TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) { - const Reflection* reflection = - unittest::TestAllExtensions::default_instance().GetReflection(); - - const FieldDescriptor* extension1 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "optional_int32_extension"); - const FieldDescriptor* extension2 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "repeated_string_extension"); - - EXPECT_EQ(extension1, - reflection->FindKnownExtensionByNumber(extension1->number())); - EXPECT_EQ(extension2, - reflection->FindKnownExtensionByNumber(extension2->number())); - - // Non-existent extension. - EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL); - - // Extensions of TestAllExtensions should not show up as extensions of - // other types. - EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> - FindKnownExtensionByNumber(extension1->number()) == NULL); -} - -TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { - const Reflection* reflection = - unittest::TestAllExtensions::default_instance().GetReflection(); - - const FieldDescriptor* extension1 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "optional_int32_extension"); - const FieldDescriptor* extension2 = - unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName( - "repeated_string_extension"); - - EXPECT_EQ(extension1, - reflection->FindKnownExtensionByName(extension1->full_name())); - EXPECT_EQ(extension2, - reflection->FindKnownExtensionByName(extension2->full_name())); - - // Non-existent extension. - EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL); - - // Extensions of TestAllExtensions should not show up as extensions of - // other types. - EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()-> - FindKnownExtensionByName(extension1->full_name()) == NULL); -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(GeneratedMessageReflectionTest, UsageErrors) { - unittest::TestAllTypes message; - const Reflection* reflection = message.GetReflection(); - const Descriptor* descriptor = message.GetDescriptor(); - -#define f(NAME) descriptor->FindFieldByName(NAME) - - // Testing every single failure mode would be too much work. Let's just - // check a few. - EXPECT_DEATH( - reflection->GetInt32( - message, descriptor->FindFieldByName("optional_int64")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest\\.TestAllTypes\n" - " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n" - " Problem : Field is not the right type for this message:\n" - " Expected : CPPTYPE_INT32\n" - " Field type: CPPTYPE_INT64"); - EXPECT_DEATH( - reflection->GetInt32( - message, descriptor->FindFieldByName("repeated_int32")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.TestAllTypes.repeated_int32\n" - " Problem : Field is repeated; the method requires a singular field."); - EXPECT_DEATH( - reflection->GetInt32( - message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::GetInt32\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.ForeignMessage.c\n" - " Problem : Field does not match message type."); - EXPECT_DEATH( - reflection->HasField( - message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")), - "Protocol Buffer reflection usage error:\n" - " Method : google::protobuf::Reflection::HasField\n" - " Message type: protobuf_unittest.TestAllTypes\n" - " Field : protobuf_unittest.ForeignMessage.c\n" - " Problem : Field does not match message type."); - -#undef f -} - -#endif // GTEST_HAS_DEATH_TEST - - -} // namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc deleted file mode 100644 index 58c44dc1..00000000 --- a/src/google/protobuf/io/coded_stream.cc +++ /dev/null @@ -1,757 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This implementation is heavily optimized to make reads and writes -// of small values (especially varints) as fast as possible. In -// particular, we optimize for the common case that a read or a write -// will not cross the end of the buffer, since we can avoid a lot -// of branching in this case. - -#include <stack> -#include <limits.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/stl_util-inl.h> - - -namespace google { -namespace protobuf { -namespace io { - -namespace { - -static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB - -static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB -static const int kDefaultRecursionLimit = 64; - -static const int kMaxVarintBytes = 10; -static const int kMaxVarint32Bytes = 5; - - -} // namespace - -// CodedInputStream ================================================== - -CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) - : input_(input), - buffer_(NULL), - buffer_size_(0), - total_bytes_read_(0), - overflow_bytes_(0), - - last_tag_(0), - legitimate_message_end_(false), - - aliasing_enabled_(false), - - current_limit_(INT_MAX), - buffer_size_after_limit_(0), - - total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), - - recursion_depth_(0), - recursion_limit_(kDefaultRecursionLimit) { -} - -CodedInputStream::~CodedInputStream() { - int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_; - if (backup_bytes > 0) { - // We still have bytes left over from the last buffer. Back up over - // them. - input_->BackUp(backup_bytes); - } -} - - -inline void CodedInputStream::RecomputeBufferLimits() { - buffer_size_ += buffer_size_after_limit_; - int closest_limit = min(current_limit_, total_bytes_limit_); - if (closest_limit < total_bytes_read_) { - // The limit position is in the current buffer. We must adjust - // the buffer size accordingly. - buffer_size_after_limit_ = total_bytes_read_ - closest_limit; - buffer_size_ -= buffer_size_after_limit_; - } else { - buffer_size_after_limit_ = 0; - } -} - -CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { - // Current position relative to the beginning of the stream. - int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); - - Limit old_limit = current_limit_; - - // security: byte_limit is possibly evil, so check for negative values - // and overflow. - if (byte_limit >= 0 && - byte_limit <= INT_MAX - current_position) { - current_limit_ = current_position + byte_limit; - } else { - // Negative or overflow. - current_limit_ = INT_MAX; - } - - // We need to enforce all limits, not just the new one, so if the previous - // limit was before the new requested limit, we continue to enforce the - // previous limit. - current_limit_ = min(current_limit_, old_limit); - - RecomputeBufferLimits(); - return old_limit; -} - -void CodedInputStream::PopLimit(Limit limit) { - // The limit passed in is actually the *old* limit, which we returned from - // PushLimit(). - current_limit_ = limit; - RecomputeBufferLimits(); - - // We may no longer be at a legitimate message end. ReadTag() needs to be - // called again to find out. - legitimate_message_end_ = false; -} - -int CodedInputStream::BytesUntilLimit() { - if (current_limit_ == INT_MAX) return -1; - int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); - - return current_limit_ - current_position; -} - -void CodedInputStream::SetTotalBytesLimit( - int total_bytes_limit, int warning_threshold) { - // Make sure the limit isn't already past, since this could confuse other - // code. - int current_position = total_bytes_read_ - - (buffer_size_ + buffer_size_after_limit_); - total_bytes_limit_ = max(current_position, total_bytes_limit); - total_bytes_warning_threshold_ = warning_threshold; - RecomputeBufferLimits(); -} - -void CodedInputStream::PrintTotalBytesLimitError() { - GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too " - "big (more than " << total_bytes_limit_ - << " bytes). To increase the limit (or to disable these " - "warnings), see CodedInputStream::SetTotalBytesLimit() " - "in google/protobuf/io/coded_stream.h."; -} - -bool CodedInputStream::Skip(int count) { - if (count < 0) return false; // security: count is often user-supplied - - if (count <= buffer_size_) { - // Just skipping within the current buffer. Easy. - Advance(count); - return true; - } - - if (buffer_size_after_limit_ > 0) { - // We hit a limit inside this buffer. Advance to the limit and fail. - Advance(buffer_size_); - return false; - } - - count -= buffer_size_; - buffer_ = NULL; - buffer_size_ = 0; - - // Make sure this skip doesn't try to skip past the current limit. - int closest_limit = min(current_limit_, total_bytes_limit_); - int bytes_until_limit = closest_limit - total_bytes_read_; - if (bytes_until_limit < count) { - // We hit the limit. Skip up to it then fail. - total_bytes_read_ = closest_limit; - input_->Skip(bytes_until_limit); - return false; - } - - total_bytes_read_ += count; - return input_->Skip(count); -} - -bool CodedInputStream::ReadRaw(void* buffer, int size) { - while (buffer_size_ < size) { - // Reading past end of buffer. Copy what we have, then refresh. - memcpy(buffer, buffer_, buffer_size_); - buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_; - size -= buffer_size_; - if (!Refresh()) return false; - } - - memcpy(buffer, buffer_, size); - Advance(size); - - return true; -} - -bool CodedInputStream::ReadString(string* buffer, int size) { - if (size < 0) return false; // security: size is often user-supplied - - if (!buffer->empty()) { - buffer->clear(); - } - - if (size < buffer_size_) { - STLStringResizeUninitialized(buffer, size); - memcpy((uint8*)buffer->data(), buffer_, size); - Advance(size); - return true; - } - - while (buffer_size_ < size) { - // Some STL implementations "helpfully" crash on buffer->append(NULL, 0). - if (buffer_size_ != 0) { - // Note: string1.append(string2) is O(string2.size()) (as opposed to - // O(string1.size() + string2.size()), which would be bad). - buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_); - } - size -= buffer_size_; - if (!Refresh()) return false; - } - - buffer->append(reinterpret_cast<const char*>(buffer_), size); - Advance(size); - - return true; -} - - -bool CodedInputStream::ReadLittleEndian32(uint32* value) { - uint8 bytes[sizeof(*value)]; - - const uint8* ptr; - if (buffer_size_ >= sizeof(*value)) { - // Fast path: Enough bytes in the buffer to read directly. - ptr = buffer_; - Advance(sizeof(*value)); - } else { - // Slow path: Had to read past the end of the buffer. - if (!ReadRaw(bytes, sizeof(*value))) return false; - ptr = bytes; - } - - *value = (static_cast<uint32>(ptr[0]) ) | - (static_cast<uint32>(ptr[1]) << 8) | - (static_cast<uint32>(ptr[2]) << 16) | - (static_cast<uint32>(ptr[3]) << 24); - return true; -} - -bool CodedInputStream::ReadLittleEndian64(uint64* value) { - uint8 bytes[sizeof(*value)]; - - const uint8* ptr; - if (buffer_size_ >= sizeof(*value)) { - // Fast path: Enough bytes in the buffer to read directly. - ptr = buffer_; - Advance(sizeof(*value)); - } else { - // Slow path: Had to read past the end of the buffer. - if (!ReadRaw(bytes, sizeof(*value))) return false; - ptr = bytes; - } - - uint32 part0 = (static_cast<uint32>(ptr[0]) ) | - (static_cast<uint32>(ptr[1]) << 8) | - (static_cast<uint32>(ptr[2]) << 16) | - (static_cast<uint32>(ptr[3]) << 24); - uint32 part1 = (static_cast<uint32>(ptr[4]) ) | - (static_cast<uint32>(ptr[5]) << 8) | - (static_cast<uint32>(ptr[6]) << 16) | - (static_cast<uint32>(ptr[7]) << 24); - *value = static_cast<uint64>(part0) | - (static_cast<uint64>(part1) << 32); - return true; -} - -bool CodedInputStream::ReadVarint32Fallback(uint32* value) { - if (buffer_size_ >= kMaxVarintBytes || - // Optimization: If the varint ends at exactly the end of the buffer, - // we can detect that and still use the fast path. - (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - const uint8* ptr = buffer_; - uint32 b; - uint32 result; - - b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done; - - // If the input is larger than 32 bits, we still need to read it all - // and discard the high-order bits. - for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) { - b = *(ptr++); if (!(b & 0x80)) goto done; - } - - // We have overrun the maximum size of a varint (10 bytes). Assume - // the data is corrupt. - return false; - - done: - Advance(ptr - buffer_); - *value = result; - return true; - - } else { - // Optimization: If we're at a limit, detect that quickly. (This is - // common when reading tags.) - while (buffer_size_ == 0) { - // Detect cases where we definitely hit a byte limit without calling - // Refresh(). - if (// If we hit a limit, buffer_size_after_limit_ will be non-zero. - buffer_size_after_limit_ > 0 && - // Make sure that the limit we hit is not total_bytes_limit_, since - // in that case we still need to call Refresh() so that it prints an - // error. - total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) { - // We hit a byte limit. - legitimate_message_end_ = true; - return false; - } - - // Call refresh. - if (!Refresh()) { - // Refresh failed. Make sure that it failed due to EOF, not because - // we hit total_bytes_limit_, which, unlike normal limits, is not a - // valid place to end a message. - int current_position = total_bytes_read_ - buffer_size_after_limit_; - if (current_position >= total_bytes_limit_) { - // Hit total_bytes_limit_. But if we also hit the normal limit, - // we're still OK. - legitimate_message_end_ = current_limit_ == total_bytes_limit_; - } else { - legitimate_message_end_ = true; - } - return false; - } - } - - // Slow path: Just do a 64-bit read. - uint64 result; - if (!ReadVarint64(&result)) return false; - *value = (uint32)result; - return true; - } -} - -bool CodedInputStream::ReadVarint64(uint64* value) { - if (buffer_size_ >= kMaxVarintBytes || - // Optimization: If the varint ends at exactly the end of the buffer, - // we can detect that and still use the fast path. - (buffer_size_ != 0 && !(buffer_[buffer_size_-1] & 0x80))) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this read won't cross the end, so we can skip the checks. - - const uint8* ptr = buffer_; - uint32 b; - - // Splitting into 32-bit pieces gives better performance on 32-bit - // processors. - uint32 part0 = 0, part1 = 0, part2 = 0; - - b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done; - b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done; - b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done; - b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done; - - // We have overrun the maximum size of a varint (10 bytes). The data - // must be corrupt. - return false; - - done: - Advance(ptr - buffer_); - *value = (static_cast<uint64>(part0) ) | - (static_cast<uint64>(part1) << 28) | - (static_cast<uint64>(part2) << 56); - return true; - - } else { - // Slow path: This read might cross the end of the buffer, so we - // need to check and refresh the buffer if and when it does. - - uint64 result = 0; - int count = 0; - uint32 b; - - do { - if (count == kMaxVarintBytes) return false; - while (buffer_size_ == 0) { - if (!Refresh()) return false; - } - b = *buffer_; - result |= static_cast<uint64>(b & 0x7F) << (7 * count); - Advance(1); - ++count; - } while(b & 0x80); - - *value = result; - return true; - } -} - -bool CodedInputStream::Refresh() { - if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0) { - // We've hit a limit. Stop. - buffer_ += buffer_size_; - buffer_size_ = 0; - - int current_position = total_bytes_read_ - buffer_size_after_limit_; - - if (current_position >= total_bytes_limit_ && - total_bytes_limit_ != current_limit_) { - // Hit total_bytes_limit_. - PrintTotalBytesLimitError(); - } - - return false; - } - - if (total_bytes_warning_threshold_ >= 0 && - total_bytes_read_ >= total_bytes_warning_threshold_) { - GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the " - "message turns out to be larger than " - << total_bytes_limit_ << " bytes, parsing will be halted " - "for security reasons. To increase the limit (or to " - "disable these warnings), see " - "CodedInputStream::SetTotalBytesLimit() in " - "google/protobuf/io/coded_stream.h."; - - // Don't warn again for this stream. - total_bytes_warning_threshold_ = -1; - } - - const void* void_buffer; - if (input_->Next(&void_buffer, &buffer_size_)) { - buffer_ = reinterpret_cast<const uint8*>(void_buffer); - GOOGLE_CHECK_GE(buffer_size_, 0); - - if (total_bytes_read_ <= INT_MAX - buffer_size_) { - total_bytes_read_ += buffer_size_; - } else { - // Overflow. Reset buffer_size_ to not include the bytes beyond INT_MAX. - // We can't get that far anyway, because total_bytes_limit_ is guaranteed - // to be less than it. We need to keep track of the number of bytes - // we discarded, though, so that we can call input_->BackUp() to back - // up over them on destruction. - - // The following line is equivalent to: - // overflow_bytes_ = total_bytes_read_ + buffer_size_ - INT_MAX; - // except that it avoids overflows. Signed integer overflow has - // undefined results according to the C standard. - overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size_); - buffer_size_ -= overflow_bytes_; - total_bytes_read_ = INT_MAX; - } - - RecomputeBufferLimits(); - return true; - } else { - buffer_ = NULL; - buffer_size_ = 0; - return false; - } -} - -// CodedOutputStream ================================================= - -CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) - : output_(output), - buffer_(NULL), - buffer_size_(0), - total_bytes_(0) { -} - -CodedOutputStream::~CodedOutputStream() { - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } -} - -bool CodedOutputStream::WriteRaw(const void* data, int size) { - while (buffer_size_ < size) { - memcpy(buffer_, data, buffer_size_); - size -= buffer_size_; - data = reinterpret_cast<const uint8*>(data) + buffer_size_; - if (!Refresh()) return false; - } - - memcpy(buffer_, data, size); - Advance(size); - return true; -} - - -bool CodedOutputStream::WriteLittleEndian32(uint32 value) { - uint8 bytes[sizeof(value)]; - - bool use_fast = buffer_size_ >= sizeof(value); - uint8* ptr = use_fast ? buffer_ : bytes; - - ptr[0] = static_cast<uint8>(value ); - ptr[1] = static_cast<uint8>(value >> 8); - ptr[2] = static_cast<uint8>(value >> 16); - ptr[3] = static_cast<uint8>(value >> 24); - - if (use_fast) { - Advance(sizeof(value)); - return true; - } else { - return WriteRaw(bytes, sizeof(value)); - } -} - -bool CodedOutputStream::WriteLittleEndian64(uint64 value) { - uint8 bytes[sizeof(value)]; - - uint32 part0 = static_cast<uint32>(value); - uint32 part1 = static_cast<uint32>(value >> 32); - - bool use_fast = buffer_size_ >= sizeof(value); - uint8* ptr = use_fast ? buffer_ : bytes; - - ptr[0] = static_cast<uint8>(part0 ); - ptr[1] = static_cast<uint8>(part0 >> 8); - ptr[2] = static_cast<uint8>(part0 >> 16); - ptr[3] = static_cast<uint8>(part0 >> 24); - ptr[4] = static_cast<uint8>(part1 ); - ptr[5] = static_cast<uint8>(part1 >> 8); - ptr[6] = static_cast<uint8>(part1 >> 16); - ptr[7] = static_cast<uint8>(part1 >> 24); - - if (use_fast) { - Advance(sizeof(value)); - return true; - } else { - return WriteRaw(bytes, sizeof(value)); - } -} - -bool CodedOutputStream::WriteVarint32Fallback(uint32 value) { - if (buffer_size_ >= kMaxVarint32Bytes) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this write won't cross the end, so we can skip the checks. - uint8* target = buffer_; - - target[0] = static_cast<uint8>(value | 0x80); - if (value >= (1 << 7)) { - target[1] = static_cast<uint8>((value >> 7) | 0x80); - if (value >= (1 << 14)) { - target[2] = static_cast<uint8>((value >> 14) | 0x80); - if (value >= (1 << 21)) { - target[3] = static_cast<uint8>((value >> 21) | 0x80); - if (value >= (1 << 28)) { - target[4] = static_cast<uint8>(value >> 28); - Advance(5); - } else { - target[3] &= 0x7F; - Advance(4); - } - } else { - target[2] &= 0x7F; - Advance(3); - } - } else { - target[1] &= 0x7F; - Advance(2); - } - } else { - target[0] &= 0x7F; - Advance(1); - } - - return true; - } else { - // Slow path: This write might cross the end of the buffer, so we - // compose the bytes first then use WriteRaw(). - uint8 bytes[kMaxVarint32Bytes]; - int size = 0; - while (value > 0x7F) { - bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80; - value >>= 7; - } - bytes[size++] = static_cast<uint8>(value) & 0x7F; - return WriteRaw(bytes, size); - } -} - -bool CodedOutputStream::WriteVarint64(uint64 value) { - if (buffer_size_ >= kMaxVarintBytes) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this write won't cross the end, so we can skip the checks. - uint8* target = buffer_; - - // Splitting into 32-bit pieces gives better performance on 32-bit - // processors. - uint32 part0 = static_cast<uint32>(value ); - uint32 part1 = static_cast<uint32>(value >> 28); - uint32 part2 = static_cast<uint32>(value >> 56); - - int size; - - // Here we can't really optimize for small numbers, since the value is - // split into three parts. Cheking for numbers < 128, for instance, - // would require three comparisons, since you'd have to make sure part1 - // and part2 are zero. However, if the caller is using 64-bit integers, - // it is likely that they expect the numbers to often be very large, so - // we probably don't want to optimize for small numbers anyway. Thus, - // we end up with a hardcoded binary search tree... - if (part2 == 0) { - if (part1 == 0) { - if (part0 < (1 << 14)) { - if (part0 < (1 << 7)) { - size = 1; goto size1; - } else { - size = 2; goto size2; - } - } else { - if (part0 < (1 << 21)) { - size = 3; goto size3; - } else { - size = 4; goto size4; - } - } - } else { - if (part1 < (1 << 14)) { - if (part1 < (1 << 7)) { - size = 5; goto size5; - } else { - size = 6; goto size6; - } - } else { - if (part1 < (1 << 21)) { - size = 7; goto size7; - } else { - size = 8; goto size8; - } - } - } - } else { - if (part2 < (1 << 7)) { - size = 9; goto size9; - } else { - size = 10; goto size10; - } - } - - GOOGLE_LOG(FATAL) << "Can't get here."; - - size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80); - size9 : target[8] = static_cast<uint8>((part2 ) | 0x80); - size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80); - size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80); - size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80); - size5 : target[4] = static_cast<uint8>((part1 ) | 0x80); - size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80); - size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80); - size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80); - size1 : target[0] = static_cast<uint8>((part0 ) | 0x80); - - target[size-1] &= 0x7F; - Advance(size); - return true; - } else { - // Slow path: This write might cross the end of the buffer, so we - // compose the bytes first then use WriteRaw(). - uint8 bytes[kMaxVarintBytes]; - int size = 0; - while (value > 0x7F) { - bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80; - value >>= 7; - } - bytes[size++] = static_cast<uint8>(value) & 0x7F; - return WriteRaw(bytes, size); - } -} - -bool CodedOutputStream::Refresh() { - void* void_buffer; - if (output_->Next(&void_buffer, &buffer_size_)) { - buffer_ = reinterpret_cast<uint8*>(void_buffer); - total_bytes_ += buffer_size_; - return true; - } else { - buffer_ = NULL; - buffer_size_ = 0; - return false; - } -} - -int CodedOutputStream::VarintSize32Fallback(uint32 value) { - if (value < (1 << 7)) { - return 1; - } else if (value < (1 << 14)) { - return 2; - } else if (value < (1 << 21)) { - return 3; - } else if (value < (1 << 28)) { - return 4; - } else { - return 5; - } -} - -int CodedOutputStream::VarintSize64(uint64 value) { - if (value < (1ull << 35)) { - if (value < (1ull << 7)) { - return 1; - } else if (value < (1ull << 14)) { - return 2; - } else if (value < (1ull << 21)) { - return 3; - } else if (value < (1ull << 28)) { - return 4; - } else { - return 5; - } - } else { - if (value < (1ull << 42)) { - return 6; - } else if (value < (1ull << 49)) { - return 7; - } else if (value < (1ull << 56)) { - return 8; - } else if (value < (1ull << 63)) { - return 9; - } else { - return 10; - } - } -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h deleted file mode 100644 index 91e5c56a..00000000 --- a/src/google/protobuf/io/coded_stream.h +++ /dev/null @@ -1,592 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains the CodedInputStream and CodedOutputStream classes, -// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively, -// and allow you to read or write individual pieces of data in various -// formats. In particular, these implement the varint encoding for -// integers, a simple variable-length encoding in which smaller numbers -// take fewer bytes. -// -// Typically these classes will only be used internally by the protocol -// buffer library in order to encode and decode protocol buffers. Clients -// of the library only need to know about this class if they wish to write -// custom message parsing or serialization procedures. -// -// CodedOutputStream example: -// // Write some data to "myfile". First we write a 4-byte "magic number" -// // to identify the file type, then write a length-delimited string. The -// // string is composed of a varint giving the length followed by the raw -// // bytes. -// int fd = open("myfile", O_WRONLY); -// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); -// CodedOutputStream* coded_output = new CodedOutputStream(raw_output); -// -// int magic_number = 1234; -// char text[] = "Hello world!"; -// coded_output->WriteLittleEndian32(magic_number); -// coded_output->WriteVarint32(strlen(text)); -// coded_output->WriteRaw(text, strlen(text)); -// -// delete coded_output; -// delete raw_output; -// close(fd); -// -// CodedInputStream example: -// // Read a file created by the above code. -// int fd = open("myfile", O_RDONLY); -// ZeroCopyInputStream* raw_input = new FileInputStream(fd); -// CodedInputStream coded_input = new CodedInputStream(raw_input); -// -// coded_input->ReadLittleEndian32(&magic_number); -// if (magic_number != 1234) { -// cerr << "File not in expected format." << endl; -// return; -// } -// -// uint32 size; -// coded_input->ReadVarint32(&size); -// -// char* text = new char[size + 1]; -// coded_input->ReadRaw(buffer, size); -// text[size] = '\0'; -// -// delete coded_input; -// delete raw_input; -// close(fd); -// -// cout << "Text is: " << text << endl; -// delete [] text; -// -// For those who are interested, varint encoding is defined as follows: -// -// The encoding operates on unsigned integers of up to 64 bits in length. -// Each byte of the encoded value has the format: -// * bits 0-6: Seven bits of the number being encoded. -// * bit 7: Zero if this is the last byte in the encoding (in which -// case all remaining bits of the number are zero) or 1 if -// more bytes follow. -// The first byte contains the least-significant 7 bits of the number, the -// second byte (if present) contains the next-least-significant 7 bits, -// and so on. So, the binary number 1011000101011 would be encoded in two -// bytes as "10101011 00101100". -// -// In theory, varint could be used to encode integers of any length. -// However, for practicality we set a limit at 64 bits. The maximum encoded -// length of a number is thus 10 bytes. - -#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ -#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - -namespace google { - -namespace protobuf { -namespace io { - -// Defined in this file. -class CodedInputStream; -class CodedOutputStream; - -// Defined in other files. -class ZeroCopyInputStream; // zero_copy_stream.h -class ZeroCopyOutputStream; // zero_copy_stream.h - -// Class which reads and decodes binary data which is composed of varint- -// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream. -// Most users will not need to deal with CodedInputStream. -// -// Most methods of CodedInputStream that return a bool return false if an -// underlying I/O error occurs or if the data is malformed. Once such a -// failure occurs, the CodedInputStream is broken and is no longer useful. -class LIBPROTOBUF_EXPORT CodedInputStream { - public: - // Create a CodedInputStream that reads from the given ZeroCopyInputStream. - explicit CodedInputStream(ZeroCopyInputStream* input); - - // Destroy the CodedInputStream and position the underlying - // ZeroCopyInputStream at the first unread byte. If an error occurred while - // reading (causing a method to return false), then the exact position of - // the input stream may be anywhere between the last value that was read - // successfully and the stream's byte limit. - ~CodedInputStream(); - - - // Skips a number of bytes. Returns false if an underlying read error - // occurs. - bool Skip(int count); - - // Read raw bytes, copying them into the given buffer. - bool ReadRaw(void* buffer, int size); - - // Like ReadRaw, but reads into a string. - // - // Implementation Note: ReadString() grows the string gradually as it - // reads in the data, rather than allocating the entire requested size - // upfront. This prevents denial-of-service attacks in which a client - // could claim that a string is going to be MAX_INT bytes long in order to - // crash the server because it can't allocate this much space at once. - bool ReadString(string* buffer, int size); - - - // Read a 32-bit little-endian integer. - bool ReadLittleEndian32(uint32* value); - // Read a 64-bit little-endian integer. - bool ReadLittleEndian64(uint64* value); - - // Read an unsigned integer with Varint encoding, truncating to 32 bits. - // Reading a 32-bit value is equivalent to reading a 64-bit one and casting - // it to uint32, but may be more efficient. - bool ReadVarint32(uint32* value); - // Read an unsigned integer with Varint encoding. - bool ReadVarint64(uint64* value); - - // Read a tag. This calls ReadVarint32() and returns the result, or returns - // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates - // the last tag value, which can be checked with LastTagWas(). - // Always inline because this is only called in once place per parse loop - // but it is called for every iteration of said loop, so it should be fast. - // GCC doesn't want to inline this by default. - uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Usually returns true if calling ReadVarint32() now would produce the given - // value. Will always return false if ReadVarint32() would not return the - // given value. If ExpectTag() returns true, it also advances past - // the varint. For best performance, use a compile-time constant as the - // parameter. - // Always inline because this collapses to a small number of instructions - // when given a constant parameter, but GCC doesn't want to inline by default. - bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Usually returns true if no more bytes can be read. Always returns false - // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent - // call to LastTagWas() will act as if ReadTag() had been called and returned - // zero, and ConsumedEntireMessage() will return true. - bool ExpectAtEnd(); - - // If the last call to ReadTag() returned the given value, returns true. - // Otherwise, returns false; - // - // This is needed because parsers for some types of embedded messages - // (with field type TYPE_GROUP) don't actually know that they've reached the - // end of a message until they see an ENDGROUP tag, which was actually part - // of the enclosing message. The enclosing message would like to check that - // tag to make sure it had the right number, so it calls LastTagWas() on - // return from the embedded parser to check. - bool LastTagWas(uint32 expected); - - // When parsing message (but NOT a group), this method must be called - // immediately after MergeFromCodedStream() returns (if it returns true) - // to further verify that the message ended in a legitimate way. For - // example, this verifies that parsing did not end on an end-group tag. - // It also checks for some cases where, due to optimizations, - // MergeFromCodedStream() can incorrectly return true. - bool ConsumedEntireMessage(); - - // Limits ---------------------------------------------------------- - // Limits are used when parsing length-delimited embedded messages. - // After the message's length is read, PushLimit() is used to prevent - // the CodedInputStream from reading beyond that length. Once the - // embedded message has been parsed, PopLimit() is called to undo the - // limit. - - // Opaque type used with PushLimit() and PopLimit(). Do not modify - // values of this type yourself. The only reason that this isn't a - // struct with private internals is for efficiency. - typedef int Limit; - - // Places a limit on the number of bytes that the stream may read, - // starting from the current position. Once the stream hits this limit, - // it will act like the end of the input has been reached until PopLimit() - // is called. - // - // As the names imply, the stream conceptually has a stack of limits. The - // shortest limit on the stack is always enforced, even if it is not the - // top limit. - // - // The value returned by PushLimit() is opaque to the caller, and must - // be passed unchanged to the corresponding call to PopLimit(). - Limit PushLimit(int byte_limit); - - // Pops the last limit pushed by PushLimit(). The input must be the value - // returned by that call to PushLimit(). - void PopLimit(Limit limit); - - // Returns the number of bytes left until the nearest limit on the - // stack is hit, or -1 if no limits are in place. - int BytesUntilLimit(); - - // Total Bytes Limit ----------------------------------------------- - // To prevent malicious users from sending excessively large messages - // and causing integer overflows or memory exhaustion, CodedInputStream - // imposes a hard limit on the total number of bytes it will read. - - // Sets the maximum number of bytes that this CodedInputStream will read - // before refusing to continue. To prevent integer overflows in the - // protocol buffers implementation, as well as to prevent servers from - // allocating enormous amounts of memory to hold parsed messages, the - // maximum message length should be limited to the shortest length that - // will not harm usability. The theoretical shortest message that could - // cause integer overflows is 512MB. The default limit is 64MB. Apps - // should set shorter limits if possible. If warning_threshold is not -1, - // a warning will be printed to stderr after warning_threshold bytes are - // read. An error will always be printed to stderr if the limit is - // reached. - // - // This is unrelated to PushLimit()/PopLimit(). - // - // Hint: If you are reading this because your program is printing a - // warning about dangerously large protocol messages, you may be - // confused about what to do next. The best option is to change your - // design such that excessively large messages are not necessary. - // For example, try to design file formats to consist of many small - // messages rather than a single large one. If this is infeasible, - // you will need to increase the limit. Chances are, though, that - // your code never constructs a CodedInputStream on which the limit - // can be set. You probably parse messages by calling things like - // Message::ParseFromString(). In this case, you will need to change - // your code to instead construct some sort of ZeroCopyInputStream - // (e.g. an ArrayInputStream), construct a CodedInputStream around - // that, then call Message::ParseFromCodedStream() instead. Then - // you can adjust the limit. Yes, it's more work, but you're doing - // something unusual. - void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); - - // Recursion Limit ------------------------------------------------- - // To prevent corrupt or malicious messages from causing stack overflows, - // we must keep track of the depth of recursion when parsing embedded - // messages and groups. CodedInputStream keeps track of this because it - // is the only object that is passed down the stack during parsing. - - // Sets the maximum recursion depth. The default is 64. - void SetRecursionLimit(int limit); - - // Increments the current recursion depth. Returns true if the depth is - // under the limit, false if it has gone over. - bool IncrementRecursionDepth(); - - // Decrements the recursion depth. - void DecrementRecursionDepth(); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); - - ZeroCopyInputStream* input_; - const uint8* buffer_; - int buffer_size_; // size of current buffer - int total_bytes_read_; // total bytes read from input_, including - // the current buffer - - // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here - // so that we can BackUp() on destruction. - int overflow_bytes_; - - // LastTagWas() stuff. - uint32 last_tag_; // result of last ReadTag(). - - // This is set true by ReadVarint32Fallback() if it is called when exactly - // at EOF, or by ExpectAtEnd() when it returns true. This happens when we - // reach the end of a message and attempt to read another tag. - bool legitimate_message_end_; - - // See EnableAliasing(). - bool aliasing_enabled_; - - // Limits - Limit current_limit_; // if position = -1, no limit is applied - - // For simplicity, if the current buffer crosses a limit (either a normal - // limit created by PushLimit() or the total bytes limit), buffer_size_ - // only tracks the number of bytes before that limit. This field - // contains the number of bytes after it. Note that this implies that if - // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've - // hit a limit. However, if both are zero, it doesn't necessarily mean - // we aren't at a limit -- the buffer may have ended exactly at the limit. - int buffer_size_after_limit_; - - // Maximum number of bytes to read, period. This is unrelated to - // current_limit_. Set using SetTotalBytesLimit(). - int total_bytes_limit_; - int total_bytes_warning_threshold_; - - // Current recursion depth, controlled by IncrementRecursionDepth() and - // DecrementRecursionDepth(). - int recursion_depth_; - // Recursion depth limit, set by SetRecursionLimit(). - int recursion_limit_; - - // Advance the buffer by a given number of bytes. - void Advance(int amount); - - // Recomputes the value of buffer_size_after_limit_. Must be called after - // current_limit_ or total_bytes_limit_ changes. - void RecomputeBufferLimits(); - - // Writes an error message saying that we hit total_bytes_limit_. - void PrintTotalBytesLimitError(); - - // Called when the buffer runs out to request more data. Implies an - // Advance(buffer_size_). - bool Refresh(); - - bool ReadVarint32Fallback(uint32* value); -}; - -// Class which encodes and writes binary data which is composed of varint- -// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream. -// Most users will not need to deal with CodedOutputStream. -// -// Most methods of CodedOutputStream which return a bool return false if an -// underlying I/O error occurs. Once such a failure occurs, the -// CodedOutputStream is broken and is no longer useful. -class LIBPROTOBUF_EXPORT CodedOutputStream { - public: - // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. - explicit CodedOutputStream(ZeroCopyOutputStream* output); - - // Destroy the CodedOutputStream and position the underlying - // ZeroCopyOutputStream immediately after the last byte written. - ~CodedOutputStream(); - - // Write raw bytes, copying them from the given buffer. - bool WriteRaw(const void* buffer, int size); - - // Equivalent to WriteRaw(str.data(), str.size()). - bool WriteString(const string& str); - - - // Write a 32-bit little-endian integer. - bool WriteLittleEndian32(uint32 value); - // Write a 64-bit little-endian integer. - bool WriteLittleEndian64(uint64 value); - - // Write an unsigned integer with Varint encoding. Writing a 32-bit value - // is equivalent to casting it to uint64 and writing it as a 64-bit value, - // but may be more efficient. - bool WriteVarint32(uint32 value); - // Write an unsigned integer with Varint encoding. - bool WriteVarint64(uint64 value); - - // Equivalent to WriteVarint32() except when the value is negative, - // in which case it must be sign-extended to a full 10 bytes. - bool WriteVarint32SignExtended(int32 value); - - // This is identical to WriteVarint32(), but optimized for writing tags. - // In particular, if the input is a compile-time constant, this method - // compiles down to a couple instructions. - // Always inline because otherwise the aformentioned optimization can't work, - // but GCC by default doesn't want to inline this. - bool WriteTag(uint32 value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; - - // Returns the number of bytes needed to encode the given value as a varint. - static int VarintSize32(uint32 value); - // Returns the number of bytes needed to encode the given value as a varint. - static int VarintSize64(uint64 value); - - // If negative, 10 bytes. Otheriwse, same as VarintSize32(). - static int VarintSize32SignExtended(int32 value); - - // Returns the total number of bytes written since this object was created. - inline int ByteCount() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); - - ZeroCopyOutputStream* output_; - uint8* buffer_; - int buffer_size_; - int total_bytes_; // Sum of sizes of all buffers seen so far. - - // Advance the buffer by a given number of bytes. - void Advance(int amount); - - // Called when the buffer runs out to request more data. Implies an - // Advance(buffer_size_). - bool Refresh(); - - bool WriteVarint32Fallback(uint32 value); - static int VarintSize32Fallback(uint32 value); -}; - -// inline methods ==================================================== -// The vast majority of varints are only one byte. These inline -// methods optimize for that case. - -inline bool CodedInputStream::ReadVarint32(uint32* value) { - if (buffer_size_ != 0 && *buffer_ < 0x80) { - *value = *buffer_; - Advance(1); - return true; - } else { - return ReadVarint32Fallback(value); - } -} - -inline uint32 CodedInputStream::ReadTag() { - if (buffer_size_ != 0 && buffer_[0] < 0x80) { - last_tag_ = buffer_[0]; - Advance(1); - return last_tag_; - } else if (buffer_size_ >= 2 && buffer_[1] < 0x80) { - last_tag_ = (buffer_[0] & 0x7f) + (buffer_[1] << 7); - Advance(2); - return last_tag_; - } else if (ReadVarint32Fallback(&last_tag_)) { - return last_tag_; - } else { - last_tag_ = 0; - return 0; - } -} - -inline bool CodedInputStream::LastTagWas(uint32 expected) { - return last_tag_ == expected; -} - -inline bool CodedInputStream::ConsumedEntireMessage() { - return legitimate_message_end_; -} - -inline bool CodedInputStream::ExpectTag(uint32 expected) { - if (expected < (1 << 7)) { - if (buffer_size_ != 0 && buffer_[0] == expected) { - Advance(1); - return true; - } else { - return false; - } - } else if (expected < (1 << 14)) { - if (buffer_size_ >= 2 && - buffer_[0] == static_cast<uint8>(expected | 0x80) && - buffer_[1] == static_cast<uint8>(expected >> 7)) { - Advance(2); - return true; - } else { - return false; - } - } else { - // Don't bother optimizing for larger values. - return false; - } -} - -inline bool CodedInputStream::ExpectAtEnd() { - // If we are at a limit we know no more bytes can be read. Otherwise, it's - // hard to say without calling Refresh(), and we'd rather not do that. - - if (buffer_size_ == 0 && buffer_size_after_limit_ != 0) { - last_tag_ = 0; // Pretend we called ReadTag()... - legitimate_message_end_ = true; // ... and it hit EOF. - return true; - } else { - return false; - } -} - -inline bool CodedOutputStream::WriteVarint32(uint32 value) { - if (value < 0x80 && buffer_size_ > 0) { - *buffer_ = value; - Advance(1); - return true; - } else { - return WriteVarint32Fallback(value); - } -} - -inline bool CodedOutputStream::WriteVarint32SignExtended(int32 value) { - if (value < 0) { - return WriteVarint64(static_cast<uint64>(value)); - } else { - return WriteVarint32(static_cast<uint32>(value)); - } -} - -inline bool CodedOutputStream::WriteTag(uint32 value) { - if (value < (1 << 7)) { - if (buffer_size_ != 0) { - buffer_[0] = value; - Advance(1); - return true; - } - } else if (value < (1 << 14)) { - if (buffer_size_ >= 2) { - buffer_[0] = static_cast<uint8>(value | 0x80); - buffer_[1] = static_cast<uint8>(value >> 7); - Advance(2); - return true; - } - } - return WriteVarint32Fallback(value); -} - -inline int CodedOutputStream::VarintSize32(uint32 value) { - if (value < (1 << 7)) { - return 1; - } else { - return VarintSize32Fallback(value); - } -} - -inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { - if (value < 0) { - return 10; // TODO(kenton): Make this a symbolic constant. - } else { - return VarintSize32(static_cast<uint32>(value)); - } -} - -inline bool CodedOutputStream::WriteString(const string& str) { - return WriteRaw(str.data(), str.size()); -} - -inline int CodedOutputStream::ByteCount() const { - return total_bytes_ - buffer_size_; -} - -inline void CodedInputStream::Advance(int amount) { - buffer_ += amount; - buffer_size_ -= amount; -} - -inline void CodedOutputStream::Advance(int amount) { - buffer_ += amount; - buffer_size_ -= amount; -} - -inline void CodedInputStream::SetRecursionLimit(int limit) { - recursion_limit_ = limit; -} - -inline bool CodedInputStream::IncrementRecursionDepth() { - ++recursion_depth_; - return recursion_depth_ <= recursion_limit_; -} - -inline void CodedInputStream::DecrementRecursionDepth() { - if (recursion_depth_ > 0) --recursion_depth_; -} - -} // namespace io -} // namespace protobuf - -} // 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 deleted file mode 100644 index c1a88349..00000000 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ /dev/null @@ -1,929 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains tests and benchmarks. - -#include <vector> - -#include <google/protobuf/io/coded_stream.h> - -#include <limits.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/strutil.h> - - -// This declares an unsigned long long integer literal in a portable way. -// (The original macro is way too big and ruins my formatting.) -#undef ULL -#define ULL(x) GOOGLE_ULONGLONG(x) - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// =================================================================== -// Data-Driven Test Infrastructure - -// TEST_1D and TEST_2D are macros I'd eventually like to see added to -// gTest. These macros can be used to declare tests which should be -// run multiple times, once for each item in some input array. TEST_1D -// tests all cases in a single input array. TEST_2D tests all -// combinations of cases from two arrays. The arrays must be statically -// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: -// -// int kCases[] = {1, 2, 3, 4} -// TEST_1D(MyFixture, MyTest, kCases) { -// EXPECT_GT(kCases_case, 0); -// } -// -// This test iterates through the numbers 1, 2, 3, and 4 and tests that -// they are all grater than zero. In case of failure, the exact case -// which failed will be printed. The case type must be printable using -// ostream::operator<<. - -#define TEST_1D(FIXTURE, NAME, CASES) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template <typename CaseType> \ - void DoSingleCase(const CaseType& CASES##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES " case #" << i << ": " << CASES[i]); \ - DoSingleCase(CASES[i]); \ - } \ - } \ - \ - template <typename CaseType> \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) - -#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template <typename CaseType1, typename CaseType2> \ - void DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ - for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ - << #CASES2 " case #" << j << ": " << CASES2[j]); \ - DoSingleCase(CASES1[i], CASES2[j]); \ - } \ - } \ - } \ - \ - template <typename CaseType1, typename CaseType2> \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case) - -// =================================================================== - -class CodedStreamTest : public testing::Test { - protected: - static const int kBufferSize = 1024 * 64; - static uint8 buffer_[kBufferSize]; -}; - -uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize]; - -// We test each operation over a variety of block sizes to insure that -// we test cases where reads or writes cross buffer boundaries, cases -// where they don't, and cases where there is so much buffer left that -// we can use special optimized paths that don't worry about bounds -// checks. -const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; - -// ------------------------------------------------------------------- -// Varint tests. - -struct VarintCase { - uint8 bytes[10]; // Encoded bytes. - int size; // Encoded size, in bytes. - uint64 value; // Parsed value. -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) { - return os << c.value; -} - -VarintCase kVarintCases[] = { - // 32-bit values - {{0x00} , 1, 0}, - {{0x01} , 1, 1}, - {{0x7f} , 1, 127}, - {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882 - {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5, // 2961488830 - (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | - (ULL(0x0b) << 28)}, - - // 64-bit - {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5, // 7256456126 - (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | - (ULL(0x1b) << 28)}, - {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8, // 41256202580718336 - (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | - (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) | - (ULL(0x49) << 49)}, - // 11964378330978735131 - {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10, - (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | - (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) | - (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)}, -}; - -TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_TRUE(coded_input.ReadVarint32(&value)); - EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 expected_value = static_cast<uint32>(kVarintCases_case.value); - EXPECT_EQ(expected_value, coded_input.ReadTag()); - - EXPECT_TRUE(coded_input.LastTagWas(expected_value)); - EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1)); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -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. - buffer_[0] = '\0'; - memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_)); - - { - CodedInputStream coded_input(&input); - - // Read one byte to force coded_input.Refill() to be called. Otherwise, - // ExpectTag() will return a false negative. - uint8 dummy; - coded_input.ReadRaw(&dummy, 1); - EXPECT_EQ((uint)'\0', (uint)dummy); - - uint32 expected_value = static_cast<uint32>(kVarintCases_case.value); - - // ExpectTag() produces false negatives for large values. - if (kVarintCases_case.size <= 2) { - EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1)); - EXPECT_TRUE(coded_input.ExpectTag(expected_value)); - } else { - EXPECT_FALSE(coded_input.ExpectTag(expected_value)); - } - } - - if (kVarintCases_case.size <= 2) { - EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount()); - } else { - EXPECT_EQ(1, input.ByteCount()); - } -} - -TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) { - memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadVarint64(&value)); - EXPECT_EQ(kVarintCases_case.value, value); - } - - EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); -} - -TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) { - if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) { - // Skip this test for the 64-bit values. - return; - } - - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteVarint32( - static_cast<uint32>(kVarintCases_case.value))); - - EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); - } - - EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); - EXPECT_EQ(0, - memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); -} - -TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteVarint64(kVarintCases_case.value)); - - EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount()); - } - - EXPECT_EQ(kVarintCases_case.size, output.ByteCount()); - EXPECT_EQ(0, - memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size)); -} - -// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -int32 kSignExtendedVarintCases[] = { - 0, 1, -1, 1237894, -37895138 -}; - -TEST_2D(CodedStreamTest, WriteVarint32SignExtended, - kSignExtendedVarintCases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteVarint32SignExtended( - kSignExtendedVarintCases_case)); - - if (kSignExtendedVarintCases_case < 0) { - EXPECT_EQ(10, coded_output.ByteCount()); - } else { - EXPECT_LE(coded_output.ByteCount(), 5); - } - } - - if (kSignExtendedVarintCases_case < 0) { - EXPECT_EQ(10, output.ByteCount()); - } else { - EXPECT_LE(output.ByteCount(), 5); - } - - // Read value back in as a varint64 and insure it matches. - ArrayInputStream input(buffer_, sizeof(buffer_)); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadVarint64(&value)); - - EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value)); - } - - EXPECT_EQ(output.ByteCount(), input.ByteCount()); -} - -#endif - - -// ------------------------------------------------------------------- -// Varint failure test. - -struct VarintErrorCase { - uint8 bytes[12]; - int size; - bool can_parse; -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) { - return os << "size " << c.size; -} - -const VarintErrorCase kVarintErrorCases[] = { - // Control case. (Insures that there isn't something else wrong that - // makes parsing always fail.) - {{0x00}, 1, true}, - - // No input data. - {{}, 0, false}, - - // Input ends unexpectedly. - {{0xf0, 0xab}, 2, false}, - - // Input ends unexpectedly after 32 bits. - {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false}, - - // Longer than 10 bytes. - {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, - 11, false}, -}; - -TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) { - memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); - ArrayInputStream input(buffer_, kVarintErrorCases_case.size, - kBlockSizes_case); - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value)); -} - -TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) { - memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size); - ArrayInputStream input(buffer_, kVarintErrorCases_case.size, - kBlockSizes_case); - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value)); -} - -// ------------------------------------------------------------------- -// VarintSize - -struct VarintSizeCase { - uint64 value; - int size; -}; - -inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) { - return os << c.value; -} - -VarintSizeCase kVarintSizeCases[] = { - {0u, 1}, - {1u, 1}, - {127u, 1}, - {128u, 2}, - {758923u, 3}, - {4000000000u, 5}, - {ULL(41256202580718336), 8}, - {ULL(11964378330978735131), 10}, -}; - -TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) { - if (kVarintSizeCases_case.value > 0xffffffffu) { - // Skip 64-bit values. - return; - } - - EXPECT_EQ(kVarintSizeCases_case.size, - CodedOutputStream::VarintSize32( - static_cast<uint32>(kVarintSizeCases_case.value))); -} - -TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) { - EXPECT_EQ(kVarintSizeCases_case.size, - CodedOutputStream::VarintSize64(kVarintSizeCases_case.value)); -} - -// ------------------------------------------------------------------- -// Fixed-size int tests - -struct Fixed32Case { - uint8 bytes[sizeof(uint32)]; // Encoded bytes. - uint32 value; // Parsed value. -}; - -struct Fixed64Case { - uint8 bytes[sizeof(uint64)]; // Encoded bytes. - uint64 value; // Parsed value. -}; - -inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) { - return os << "0x" << hex << c.value << dec; -} - -inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) { - return os << "0x" << hex << c.value << dec; -} - -Fixed32Case kFixed32Cases[] = { - {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu}, - {{0x12, 0x34, 0x56, 0x78}, 0x78563412u}, -}; - -Fixed64Case kFixed64Cases[] = { - {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)}, - {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)}, -}; - -TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) { - memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint32 value; - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(kFixed32Cases_case.value, value); - } - - EXPECT_EQ(sizeof(uint32), input.ByteCount()); -} - -TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) { - memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - uint64 value; - EXPECT_TRUE(coded_input.ReadLittleEndian64(&value)); - EXPECT_EQ(kFixed64Cases_case.value, value); - } - - EXPECT_EQ(sizeof(uint64), input.ByteCount()); -} - -TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteLittleEndian32(kFixed32Cases_case.value)); - - EXPECT_EQ(sizeof(uint32), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(uint32), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32))); -} - -TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteLittleEndian64(kFixed64Cases_case.value)); - - EXPECT_EQ(sizeof(uint64), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(uint64), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64))); -} - -// ------------------------------------------------------------------- -// Raw reads and writes - -const char kRawBytes[] = "Some bytes which will be writted and read raw."; - -TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) { - memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - char read_buffer[sizeof(kRawBytes)]; - - { - CodedInputStream coded_input(&input); - - EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes))); - EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes))); - } - - EXPECT_EQ(sizeof(kRawBytes), input.ByteCount()); -} - -TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) { - ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedOutputStream coded_output(&output); - - EXPECT_TRUE(coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes))); - - EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount()); - } - - EXPECT_EQ(sizeof(kRawBytes), output.ByteCount()); - EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes))); -} - -TEST_1D(CodedStreamTest, ReadString, kBlockSizes) { - memcpy(buffer_, kRawBytes, sizeof(kRawBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes))); - EXPECT_EQ(kRawBytes, str); - } - - EXPECT_EQ(strlen(kRawBytes), input.ByteCount()); -} - -// Check to make sure ReadString doesn't crash on impossibly large strings. -TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - // Try to read a gigabyte. - EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30)); - } -} - - -// ------------------------------------------------------------------- -// Skip - -const char kSkipTestBytes[] = - "<Before skipping><To be skipped><After skipping>"; -const char kSkipOutputTestBytes[] = - "-----------------<To be skipped>----------------"; - -TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) { - memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes)); - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>"))); - EXPECT_EQ("<Before skipping>", str); - EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>"))); - EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>"))); - EXPECT_EQ("<After skipping>", str); - } - - EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount()); -} - -// ------------------------------------------------------------------- -// Limits - -TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit = coded_input.PushLimit(8); - - // Read until we hit the limit. - uint32 value; - EXPECT_EQ(8, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(12, input.ByteCount()); -} - -// Test what happens when we push two limits where the second (top) one is -// shorter. -TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit1 = coded_input.PushLimit(8); - EXPECT_EQ(8, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit2 = coded_input.PushLimit(4); - - uint32 value; - - // Read until we hit limit2, the top and shortest limit. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit2); - - // Read until we hit limit1. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit1); - - // No more limits. - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(12, input.ByteCount()); -} - -// Test what happens when we push two limits where the second (top) one is -// longer. In this case, the top limit is shortened to match the previous -// limit. -TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) { - ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case); - - { - CodedInputStream coded_input(&input); - - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit1 = coded_input.PushLimit(4); - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - CodedInputStream::Limit limit2 = coded_input.PushLimit(8); - - uint32 value; - - // Read until we hit limit2. Except, wait! limit1 is shorter, so - // we end up hitting that first, despite having 4 bytes to go on - // limit2. - EXPECT_EQ(4, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit2); - - // OK, popped limit2, now limit1 is on top, which we've already hit. - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - EXPECT_FALSE(coded_input.ReadLittleEndian32(&value)); - EXPECT_EQ(0, coded_input.BytesUntilLimit()); - - coded_input.PopLimit(limit1); - - // No more limits. - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - } - - EXPECT_EQ(8, input.ByteCount()); -} - -TEST_F(CodedStreamTest, ExpectAtEnd) { - // Test ExpectAtEnd(), which is based on limits. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - EXPECT_FALSE(coded_input.ExpectAtEnd()); - - CodedInputStream::Limit limit = coded_input.PushLimit(4); - - uint32 value; - EXPECT_TRUE(coded_input.ReadLittleEndian32(&value)); - EXPECT_TRUE(coded_input.ExpectAtEnd()); - - coded_input.PopLimit(limit); - EXPECT_FALSE(coded_input.ExpectAtEnd()); -} - -TEST_F(CodedStreamTest, NegativeLimit) { - // Check what happens when we push a negative limit. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - CodedInputStream::Limit limit = coded_input.PushLimit(-1234); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, NegativeLimitAfterReading) { - // Check what happens when we push a negative limit. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - ASSERT_TRUE(coded_input.Skip(128)); - - CodedInputStream::Limit limit = coded_input.PushLimit(-64); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, OverflowLimit) { - // Check what happens when we push a limit large enough that its absolute - // position is more than 2GB into the stream. - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - ASSERT_TRUE(coded_input.Skip(128)); - - CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX); - // BytesUntilLimit() returns -1 to mean "no limit", which actually means - // "the limit is INT_MAX relative to the beginning of the stream". - EXPECT_EQ(-1, coded_input.BytesUntilLimit()); - coded_input.PopLimit(limit); -} - -TEST_F(CodedStreamTest, TotalBytesLimit) { - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - coded_input.SetTotalBytesLimit(16, -1); - - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 16)); - - vector<string> errors; - - { - ScopedMemoryLog error_log; - EXPECT_FALSE(coded_input.ReadString(&str, 1)); - errors = error_log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "A protocol message was rejected because it was too big", errors[0]); - - coded_input.SetTotalBytesLimit(32, -1); - EXPECT_TRUE(coded_input.ReadString(&str, 16)); -} - -TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) { - // total_bytes_limit_ is not a valid place for a message to end. - - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - - // Set both total_bytes_limit and a regular limit at 16 bytes. - coded_input.SetTotalBytesLimit(16, -1); - CodedInputStream::Limit limit = coded_input.PushLimit(16); - - // Read 16 bytes. - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 16)); - - // Read a tag. Should fail, but report being a valid endpoint since it's - // a regular limit. - EXPECT_EQ(0, coded_input.ReadTag()); - EXPECT_TRUE(coded_input.ConsumedEntireMessage()); - - // Pop the limit. - coded_input.PopLimit(limit); - - // Read a tag. Should fail, and report *not* being a valid endpoint, since - // this time we're hitting the total bytes limit. - EXPECT_EQ(0, coded_input.ReadTag()); - EXPECT_FALSE(coded_input.ConsumedEntireMessage()); -} - -TEST_F(CodedStreamTest, RecursionLimit) { - ArrayInputStream input(buffer_, sizeof(buffer_)); - CodedInputStream coded_input(&input); - coded_input.SetRecursionLimit(4); - - // This is way too much testing for a counter. - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 - coded_input.DecrementRecursionDepth(); // 5 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6 - coded_input.DecrementRecursionDepth(); // 5 - coded_input.DecrementRecursionDepth(); // 4 - coded_input.DecrementRecursionDepth(); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - coded_input.DecrementRecursionDepth(); // 4 - coded_input.DecrementRecursionDepth(); // 3 - coded_input.DecrementRecursionDepth(); // 2 - coded_input.DecrementRecursionDepth(); // 1 - coded_input.DecrementRecursionDepth(); // 0 - coded_input.DecrementRecursionDepth(); // 0 - coded_input.DecrementRecursionDepth(); // 0 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3 - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5 - - coded_input.SetRecursionLimit(6); - EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6 - EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7 -} - -class ReallyBigInputStream : public ZeroCopyInputStream { - public: - ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {} - ~ReallyBigInputStream() {} - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size) { - // We only expect BackUp() to be called at the end. - EXPECT_EQ(0, backup_amount_); - - switch (buffer_count_++) { - case 0: - *data = buffer_; - *size = sizeof(buffer_); - return true; - case 1: - // Return an enormously large buffer that, when combined with the 1k - // returned already, should overflow the total_bytes_read_ counter in - // CodedInputStream. Note that we'll only read the first 1024 bytes - // of this buffer so it's OK that we have it point at buffer_. - *data = buffer_; - *size = INT_MAX; - return true; - default: - return false; - } - } - - void BackUp(int count) { - backup_amount_ = count; - } - - bool Skip(int count) { GOOGLE_LOG(FATAL) << "Not implemented."; return false; } - int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; } - - int backup_amount_; - - private: - char buffer_[1024]; - int64 buffer_count_; -}; - -TEST_F(CodedStreamTest, InputOver2G) { - // CodedInputStream should gracefully handle input over 2G and call - // input.BackUp() with the correct number of bytes on destruction. - ReallyBigInputStream input; - - vector<string> errors; - - { - ScopedMemoryLog error_log; - CodedInputStream coded_input(&input); - string str; - EXPECT_TRUE(coded_input.ReadString(&str, 512)); - EXPECT_TRUE(coded_input.ReadString(&str, 1024)); - errors = error_log.GetMessages(ERROR); - } - - EXPECT_EQ(INT_MAX - 512, input.backup_amount_); - EXPECT_EQ(0, errors.size()); -} - -// =================================================================== - - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/package_info.h b/src/google/protobuf/io/package_info.h deleted file mode 100644 index 8272d51d..00000000 --- a/src/google/protobuf/io/package_info.h +++ /dev/null @@ -1,40 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file exists solely to document the google::protobuf::io namespace. -// It is not compiled into anything, but it may be read by an automated -// documentation generator. - -namespace google { - -namespace protobuf { - -// Auxiliary classes used for I/O. -// -// The Protocol Buffer library uses the classes in this package to deal with -// I/O and encoding/decoding raw bytes. Most users will not need to -// deal with this package. However, users who want to adapt the system to -// work with their own I/O abstractions -- e.g., to allow Protocol Buffers -// to be read from a different kind of input stream without the need for a -// temporary buffer -- should take a closer look. -namespace io {} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc deleted file mode 100644 index 7b3e3de4..00000000 --- a/src/google/protobuf/io/printer.cc +++ /dev/null @@ -1,165 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace io { - -Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter) - : variable_delimiter_(variable_delimiter), - output_(output), - buffer_(NULL), - buffer_size_(0), - at_start_of_line_(true), - failed_(false) { -} - -Printer::~Printer() { - // Only BackUp() if we're sure we've successfully called Next() at least once. - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } -} - -void Printer::Print(const map<string, string>& variables, const char* text) { - int size = strlen(text); - int pos = 0; // The number of bytes we've written so far. - - for (int i = 0; i < size; i++) { - if (text[i] == '\n') { - // Saw newline. If there is more text, we may need to insert an indent - // here. So, write what we have so far, including the '\n'. - Write(text + pos, i - pos + 1); - pos = i + 1; - - // Setting this true will cause the next Write() to insert an indent - // first. - at_start_of_line_ = true; - - } else if (text[i] == variable_delimiter_) { - // Saw the start of a variable name. - - // Write what we have so far. - Write(text + pos, i - pos); - pos = i + 1; - - // Find closing delimiter. - const char* end = strchr(text + pos, variable_delimiter_); - if (end == NULL) { - GOOGLE_LOG(DFATAL) << " Unclosed variable name."; - end = text + pos; - } - int endpos = end - text; - - string varname(text + pos, endpos - pos); - if (varname.empty()) { - // Two delimiters in a row reduce to a literal delimiter character. - Write(&variable_delimiter_, 1); - } else { - // Replace with the variable's value. - map<string, string>::const_iterator iter = variables.find(varname); - if (iter == variables.end()) { - GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; - } else { - Write(iter->second.data(), iter->second.size()); - } - } - - // Advance past this variable. - i = endpos; - pos = endpos + 1; - } - } - - // Write the rest. - Write(text + pos, size - pos); -} - -void Printer::Print(const char* text) { - static map<string, string> empty; - Print(empty, text); -} - -void Printer::Print(const char* text, - const char* variable, const string& value) { - map<string, string> vars; - vars[variable] = value; - Print(vars, text); -} - -void Printer::Print(const char* text, - const char* variable1, const string& value1, - const char* variable2, const string& value2) { - map<string, string> vars; - vars[variable1] = value1; - vars[variable2] = value2; - Print(vars, text); -} - -void Printer::Indent() { - indent_ += " "; -} - -void Printer::Outdent() { - if (indent_.empty()) { - GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; - return; - } - - indent_.resize(indent_.size() - 2); -} - -void Printer::Write(const char* data, int size) { - if (failed_) return; - if (size == 0) return; - - if (at_start_of_line_) { - // Insert an indent. - at_start_of_line_ = false; - Write(indent_.data(), indent_.size()); - if (failed_) return; - } - - while (size > buffer_size_) { - // Data exceeds space in the buffer. Copy what we can and request a - // new buffer. - memcpy(buffer_, data, buffer_size_); - data += buffer_size_; - size -= buffer_size_; - void* void_buffer; - failed_ = !output_->Next(&void_buffer, &buffer_size_); - if (failed_) return; - buffer_ = reinterpret_cast<char*>(void_buffer); - } - - // Buffer is big enough to receive the data; copy it. - memcpy(buffer_, data, size); - buffer_ += size; - buffer_size_ -= size; -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h deleted file mode 100644 index ee8f46c8..00000000 --- a/src/google/protobuf/io/printer.h +++ /dev/null @@ -1,109 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Utility class for writing text to a ZeroCopyOutputStream. - -#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__ -#define GOOGLE_PROTOBUF_IO_PRINTER_H__ - -#include <string> -#include <map> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace io { - -class ZeroCopyOutputStream; // zero_copy_stream.h - -// This simple utility class assists in code generation. It basically -// allows the caller to define a set of variables and then output some -// text with variable substitutions. Example usage: -// -// Printer printer(output, '$'); -// map<string, string> vars; -// vars["name"] = "Bob"; -// printer.Print(vars, "My name is $name$."); -// -// The above writes "My name is Bob." to the output stream. -// -// Printer aggressively enforces correct usage, crashing (with assert failures) -// in the case of undefined variables. This helps greatly in debugging code -// which uses it. This class is not intended to be used by production servers. -class LIBPROTOBUF_EXPORT Printer { - public: - // Create a printer that writes text to the given output stream. Use the - // given character as the delimiter for variables. - Printer(ZeroCopyOutputStream* output, char variable_delimiter); - ~Printer(); - - // Print some text after applying variable substitutions. If a particular - // variable in the text is not defined, this will crash. Variables to be - // substituted are identified by their names surrounded by delimiter - // characters (as given to the constructor). The variable bindings are - // defined by the given map. - void Print(const map<string, string>& variables, const char* text); - - // Like the first Print(), except the substitutions are given as parameters. - void Print(const char* text); - // Like the first Print(), except the substitutions are given as parameters. - void Print(const char* text, const char* variable, const string& value); - // 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 - // to be enough. - - // Indent text by two spaces. After calling Indent(), two spaces will be - // inserted at the beginning of each line of text. Indent() may be called - // multiple times to produce deeper indents. - void Indent(); - - // Reduces the current indent level by two spaces, or crashes if the indent - // level is zero. - void Outdent(); - - // True if any write to the underlying stream failed. (We don't just - // crash in this case because this is an I/O failure, not a programming - // error.) - bool failed() const { return failed_; } - - private: - // Write some text to the output buffer. - void Write(const char* data, int size); - - const char variable_delimiter_; - - ZeroCopyOutputStream* const output_; - char* buffer_; - int buffer_size_; - - string indent_; - bool at_start_of_line_; - bool failed_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer); -}; - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__ diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc deleted file mode 100644 index 652728bc..00000000 --- a/src/google/protobuf/io/printer_unittest.cc +++ /dev/null @@ -1,210 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> - -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// Each test repeats over several block sizes in order to test both cases -// where particular writes cross a buffer boundary and cases where they do -// not. - -TEST(Printer, EmptyPrinter) { - char buffer[8192]; - const int block_size = 100; - ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size); - Printer printer(&output, '\0'); - EXPECT_TRUE(!printer.failed()); -} - -TEST(Printer, BasicPrinting) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '\0'); - - printer.Print("Hello World!"); - printer.Print(" This is the same line.\n"); - printer.Print("But this is a new one.\nAnd this is another one."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ(buffer, - "Hello World! This is the same line.\n" - "But this is a new one.\n" - "And this is another one."); - } -} - -TEST(Printer, VariableSubstitution) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '$'); - map<string, string> vars; - - vars["foo"] = "World"; - vars["bar"] = "$foo$"; - vars["abcdefg"] = "1234"; - - printer.Print(vars, "Hello $foo$!\nbar = $bar$\n"); - printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$"); - - vars["foo"] = "blah"; - printer.Print(vars, "\nNow foo = $foo$."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ(buffer, - "Hello World!\n" - "bar = $foo$\n" - "1234\n" - "A literal dollar sign: $\n" - "Now foo = blah."); - } -} - -TEST(Printer, InlineVariableSubstitution) { - char buffer[8192]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - - { - Printer printer(&output, '$'); - printer.Print("Hello $foo$!\n", "foo", "World"); - printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two"); - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ(buffer, - "Hello World!\n" - "one two\n"); -} - -TEST(Printer, Indenting) { - char buffer[8192]; - - for (int block_size = 1; block_size < 512; block_size *= 2) { - ArrayOutputStream output(buffer, sizeof(buffer), block_size); - - { - Printer printer(&output, '$'); - map<string, string> vars; - - vars["newline"] = "\n"; - - printer.Print("This is not indented.\n"); - printer.Indent(); - printer.Print("This is indented\nAnd so is this\n"); - printer.Outdent(); - printer.Print("But this is not."); - printer.Indent(); - printer.Print(" And this is still the same line.\n" - "But this is indented.\n"); - printer.Print(vars, "Note that a newline in a variable will break " - "indenting, as we see$newline$here.\n"); - printer.Indent(); - printer.Print("And this"); - printer.Outdent(); - printer.Outdent(); - printer.Print(" is double-indented\nBack to normal."); - - EXPECT_FALSE(printer.failed()); - } - - buffer[output.ByteCount()] = '\0'; - - EXPECT_STREQ(buffer, - "This is not indented.\n" - " This is indented\n" - " And so is this\n" - "But this is not. And this is still the same line.\n" - " But this is indented.\n" - " Note that a newline in a variable will break indenting, as we see\n" - "here.\n" - " And this is double-indented\n" - "Back to normal."); - } -} - -// Death tests do not work on Windows as of yet. -#ifdef GTEST_HAS_DEATH_TEST -TEST(Printer, Death) { - char buffer[8192]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - Printer printer(&output, '$'); - - EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable"); - EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name"); - EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent"); -} -#endif // GTEST_HAS_DEATH_TEST - -TEST(Printer, WriteFailure) { - char buffer[16]; - - ArrayOutputStream output(buffer, sizeof(buffer)); - Printer printer(&output, '$'); - - // Print 16 bytes to fill the buffer exactly (should not fail). - printer.Print("0123456789abcdef"); - EXPECT_FALSE(printer.failed()); - - // Try to print one more byte (should fail). - printer.Print(" "); - EXPECT_TRUE(printer.failed()); - - // Should not crash - printer.Print("blah"); - EXPECT_TRUE(printer.failed()); - - // Buffer should contain the first 16 bytes written. - EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer))); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc deleted file mode 100644 index 3864fcfb..00000000 --- a/src/google/protobuf/io/tokenizer.cc +++ /dev/null @@ -1,679 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Here we have a hand-written lexer. At first you might ask yourself, -// "Hand-written text processing? Is Kenton crazy?!" Well, first of all, -// yes I am crazy, but that's beside the point. There are actually reasons -// why I ended up writing this this way. -// -// The traditional approach to lexing is to use lex to generate a lexer for -// you. Unfortunately, lex's output is ridiculously ugly and difficult to -// integrate cleanly with C++ code, especially abstract code or code meant -// as a library. Better parser-generators exist but would add dependencies -// which most users won't already have, which we'd like to avoid. (GNU flex -// has a C++ output option, but it's still ridiculously ugly, non-abstract, -// and not library-friendly.) -// -// The next approach that any good software engineer should look at is to -// use regular expressions. And, indeed, I did. I have code which -// implements this same class using regular expressions. It's about 200 -// lines shorter. However: -// - Rather than error messages telling you "This string has an invalid -// escape sequence at line 5, column 45", you get error messages like -// "Parse error on line 5". Giving more precise errors requires adding -// a lot of code that ends up basically as complex as the hand-coded -// version anyway. -// - The regular expression to match a string literal looks like this: -// kString = new RE("(\"([^\"\\\\]|" // non-escaped -// "\\\\[abfnrtv?\"'\\\\0-7]|" // normal escape -// "\\\\x[0-9a-fA-F])*\"|" // hex escape -// "\'([^\'\\\\]|" // Also support single-quotes. -// "\\\\[abfnrtv?\"'\\\\0-7]|" -// "\\\\x[0-9a-fA-F])*\')"); -// Verifying the correctness of this line noise is actually harder than -// verifying the correctness of ConsumeString(), defined below. I'm not -// even confident that the above is correct, after staring at it for some -// time. -// - PCRE is fast, but there's still more overhead involved than the code -// below. -// - Sadly, regular expressions are not part of the C standard library, so -// using them would require depending on some other library. For the -// open source release, this could be really annoying. Nobody likes -// downloading one piece of software just to find that they need to -// download something else to make it work, and in all likelihood -// people downloading Protocol Buffers will already be doing so just -// to make something else work. We could include a copy of PCRE with -// our code, but that obligates us to keep it up-to-date and just seems -// like a big waste just to save 200 lines of code. -// -// On a similar but unrelated note, I'm even scared to use ctype.h. -// Apparently functions like isalpha() are locale-dependent. So, if we used -// that, then if this code is being called from some program that doesn't -// have its locale set to "C", it would behave strangely. We can't just set -// the locale to "C" ourselves since we might break the calling program that -// way, particularly if it is multi-threaded. WTF? Someone please let me -// (Kenton) know if I'm missing something here... -// -// I'd love to hear about other alternatives, though, as this code isn't -// exactly pretty. - -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// As mentioned above, I don't trust ctype.h due to the presence of "locales". -// So, I have written replacement functions here. Someone please smack me if -// this is a bad idea or if there is some way around this. -// -// These "character classes" are designed to be used in template methods. -// For instance, Tokenizer::ConsumeZeroOrMore<Whitespace>() will eat -// whitespace. - -// Note: No class is allowed to contain '\0', since this is used to mark end- -// of-input and is handled specially. - -#define CHARACTER_CLASS(NAME, EXPRESSION) \ - class NAME { \ - public: \ - static inline bool InClass(char c) { \ - return EXPRESSION; \ - } \ - } - -CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' || - c == '\r' || c == '\v'); - -CHARACTER_CLASS(Unprintable, c < ' ' && c != '\0'); - -CHARACTER_CLASS(Digit, '0' <= c && c <= '9'); -CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7'); -CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') || - ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F')); - -CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - (c == '_')); - -CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || - (c == '_')); - -CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' || - c == 'r' || c == 't' || c == 'v' || c == '\\' || - c == '?' || c == '\'' || c == '\"'); - -#undef CHARACTER_CLASS - -// Given a char, interpret it as a numeric digit and return its value. -// This supports any number base up to 36. -inline int DigitValue(char digit) { - if ('0' <= digit && digit <= '9') return digit - '0'; - if ('a' <= digit && digit <= 'z') return digit - 'a' + 10; - if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10; - return -1; -} - -// Inline because it's only used in one place. -inline char TranslateEscape(char c) { - switch (c) { - case 'a': return '\a'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - case '\\': return '\\'; - case '?': return '\?'; // Trigraphs = :( - case '\'': return '\''; - case '"': return '\"'; - - // We expect escape sequences to have been validated separately. - default: return '?'; - } -} - -} // anonymous namespace - -ErrorCollector::~ErrorCollector() {} - -// =================================================================== - -Tokenizer::Tokenizer(ZeroCopyInputStream* input, - ErrorCollector* error_collector) - : input_(input), - error_collector_(error_collector), - buffer_(NULL), - buffer_size_(0), - buffer_pos_(0), - read_error_(false), - line_(0), - column_(0), - token_start_(-1), - allow_f_after_float_(false), - comment_style_(CPP_COMMENT_STYLE) { - - current_.line = 0; - current_.column = 0; - current_.type = TYPE_START; - - Refresh(); -} - -Tokenizer::~Tokenizer() { - // If we had any buffer left unread, return it to the underlying stream - // so that someone else can read it. - if (buffer_size_ > buffer_pos_) { - input_->BackUp(buffer_size_ - buffer_pos_); - } -} - -// ------------------------------------------------------------------- -// Internal helpers. - -void Tokenizer::NextChar() { - // Update our line and column counters based on the character being - // consumed. - if (current_char_ == '\n') { - ++line_; - column_ = 0; - } else if (current_char_ == '\t') { - column_ += kTabWidth - column_ % kTabWidth; - } else { - ++column_; - } - - // Advance to the next character. - ++buffer_pos_; - if (buffer_pos_ < buffer_size_) { - current_char_ = buffer_[buffer_pos_]; - } else { - Refresh(); - } -} - -void Tokenizer::Refresh() { - if (read_error_) { - current_char_ = '\0'; - return; - } - - // If we're in a token, append the rest of the buffer to it. - if (token_start_ >= 0 && token_start_ < buffer_size_) { - current_.text.append(buffer_ + token_start_, buffer_size_ - token_start_); - token_start_ = 0; - } - - const void* data = NULL; - buffer_ = NULL; - buffer_pos_ = 0; - do { - if (!input_->Next(&data, &buffer_size_)) { - // end of stream (or read error) - buffer_size_ = 0; - read_error_ = true; - current_char_ = '\0'; - return; - } - } while (buffer_size_ == 0); - - buffer_ = static_cast<const char*>(data); - - current_char_ = buffer_[0]; -} - -inline void Tokenizer::StartToken() { - token_start_ = buffer_pos_; - current_.type = TYPE_START; // Just for the sake of initializing it. - current_.text.clear(); - current_.line = line_; - current_.column = column_; -} - -inline void Tokenizer::EndToken() { - // Note: The if() is necessary because some STL implementations crash when - // you call string::append(NULL, 0), presumably because they are trying to - // be helpful by detecting the NULL pointer, even though there's nothing - // wrong with reading zero bytes from NULL. - if (buffer_pos_ != token_start_) { - current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_); - } - token_start_ = -1; -} - -// ------------------------------------------------------------------- -// Helper methods that consume characters. - -template<typename CharacterClass> -inline bool Tokenizer::LookingAt() { - return CharacterClass::InClass(current_char_); -} - -template<typename CharacterClass> -inline bool Tokenizer::TryConsumeOne() { - if (CharacterClass::InClass(current_char_)) { - NextChar(); - return true; - } else { - return false; - } -} - -inline bool Tokenizer::TryConsume(char c) { - if (current_char_ == c) { - NextChar(); - return true; - } else { - return false; - } -} - -template<typename CharacterClass> -inline void Tokenizer::ConsumeZeroOrMore() { - while (CharacterClass::InClass(current_char_)) { - NextChar(); - } -} - -template<typename CharacterClass> -inline void Tokenizer::ConsumeOneOrMore(const char* error) { - if (!CharacterClass::InClass(current_char_)) { - AddError(error); - } else { - do { - NextChar(); - } while (CharacterClass::InClass(current_char_)); - } -} - -// ------------------------------------------------------------------- -// Methods that read whole patterns matching certain kinds of tokens -// or comments. - -void Tokenizer::ConsumeString(char delimiter) { - while (true) { - switch (current_char_) { - case '\0': - case '\n': { - AddError("String literals cannot cross line boundaries."); - return; - } - - case '\\': { - // An escape sequence. - NextChar(); - if (TryConsumeOne<Escape>()) { - // Valid escape sequence. - } else if (TryConsumeOne<OctalDigit>()) { - // Possibly followed by two more octal digits, but these will - // just be consumed by the main loop anyway so we don't need - // to do so explicitly here. - } else if (TryConsume('x') || TryConsume('X')) { - if (!TryConsumeOne<HexDigit>()) { - AddError("Expected hex digits for escape sequence."); - } - // Possibly followed by another hex digit, but again we don't care. - } else { - AddError("Invalid escape sequence in string literal."); - } - break; - } - - default: { - if (current_char_ == delimiter) { - NextChar(); - return; - } - NextChar(); - break; - } - } - } -} - -Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero, - bool started_with_dot) { - bool is_float = false; - - if (started_with_zero && (TryConsume('x') || TryConsume('X'))) { - // A hex number (started with "0x"). - ConsumeOneOrMore<HexDigit>("\"0x\" must be followed by hex digits."); - - } else if (started_with_zero && LookingAt<Digit>()) { - // An octal number (had a leading zero). - ConsumeZeroOrMore<OctalDigit>(); - if (LookingAt<Digit>()) { - AddError("Numbers starting with leading zero must be in octal."); - ConsumeZeroOrMore<Digit>(); - } - - } else { - // A decimal number. - if (started_with_dot) { - is_float = true; - ConsumeZeroOrMore<Digit>(); - } else { - ConsumeZeroOrMore<Digit>(); - - if (TryConsume('.')) { - is_float = true; - ConsumeZeroOrMore<Digit>(); - } - } - - if (TryConsume('e') || TryConsume('E')) { - is_float = true; - TryConsume('-') || TryConsume('+'); - ConsumeOneOrMore<Digit>("\"e\" must be followed by exponent."); - } - - if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) { - is_float = true; - } - } - - if (LookingAt<Letter>()) { - AddError("Need space between number and identifier."); - } else if (current_char_ == '.') { - if (is_float) { - AddError( - "Already saw decimal point or exponent; can't have another one."); - } else { - AddError("Hex and octal numbers must be integers."); - } - } - - return is_float ? TYPE_FLOAT : TYPE_INTEGER; -} - -void Tokenizer::ConsumeLineComment() { - while (current_char_ != '\0' && current_char_ != '\n') { - NextChar(); - } - TryConsume('\n'); -} - -void Tokenizer::ConsumeBlockComment() { - int start_line = line_; - int start_column = column_ - 2; - - while (true) { - while (current_char_ != '\0' && - current_char_ != '*' && - current_char_ != '/') { - NextChar(); - } - - if (TryConsume('*') && TryConsume('/')) { - // End of comment. - break; - } else if (TryConsume('/') && current_char_ == '*') { - // Note: We didn't consume the '*' because if there is a '/' after it - // we want to interpret that as the end of the comment. - AddError( - "\"/*\" inside block comment. Block comments cannot be nested."); - } else if (current_char_ == '\0') { - AddError("End-of-file inside block comment."); - error_collector_->AddError( - start_line, start_column, " Comment started here."); - break; - } - } -} - -// ------------------------------------------------------------------- - -bool Tokenizer::Next() { - TokenType last_token_type = current_.type; - - // Did we skip any characters after the last token? - bool skipped_stuff = false; - - while (!read_error_) { - if (TryConsumeOne<Whitespace>()) { - ConsumeZeroOrMore<Whitespace>(); - - } else if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) { - // Starting a comment? - if (TryConsume('/')) { - ConsumeLineComment(); - } else if (TryConsume('*')) { - ConsumeBlockComment(); - } else { - // Oops, it was just a slash. Return it. - current_.type = TYPE_SYMBOL; - current_.text = "/"; - current_.line = line_; - current_.column = column_ - 1; - return true; - } - - } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) { - ConsumeLineComment(); - - } else if (LookingAt<Unprintable>() || current_char_ == '\0') { - AddError("Invalid control characters encountered in text."); - NextChar(); - // Skip more unprintable characters, too. But, remember that '\0' is - // also what current_char_ is set to after EOF / read error. We have - // to be careful not to go into an infinite loop of trying to consume - // it, so make sure to check read_error_ explicitly before consuming - // '\0'. - while (TryConsumeOne<Unprintable>() || - (!read_error_ && TryConsume('\0'))) { - // Ignore. - } - - } else { - // Reading some sort of token. - StartToken(); - - if (TryConsumeOne<Letter>()) { - ConsumeZeroOrMore<Alphanumeric>(); - current_.type = TYPE_IDENTIFIER; - } else if (TryConsume('0')) { - current_.type = ConsumeNumber(true, false); - } else if (TryConsume('.')) { - // This could be the beginning of a floating-point number, or it could - // just be a '.' symbol. - - if (TryConsumeOne<Digit>()) { - // It's a floating-point number. - if (last_token_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."); - } - current_.type = ConsumeNumber(false, true); - } else { - current_.type = TYPE_SYMBOL; - } - } else if (TryConsumeOne<Digit>()) { - current_.type = ConsumeNumber(false, false); - } else if (TryConsume('\"')) { - ConsumeString('\"'); - current_.type = TYPE_STRING; - } else if (TryConsume('\'')) { - ConsumeString('\''); - current_.type = TYPE_STRING; - } else { - NextChar(); - current_.type = TYPE_SYMBOL; - } - - EndToken(); - return true; - } - - skipped_stuff = true; - } - - // EOF - current_.type = TYPE_END; - current_.text.clear(); - current_.line = line_; - current_.column = column_; - return false; -} - -// ------------------------------------------------------------------- -// Token-parsing helpers. Remember that these don't need to report -// errors since any errors should already have been reported while -// tokenizing. Also, these can assume that whatever text they -// are given is text that the tokenizer actually parsed as a token -// of the given type. - -bool Tokenizer::ParseInteger(const string& text, uint64 max_value, - uint64* output) { - // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull() - // is non-standard. I hate the C standard library. :( - -// return strtoull(text.c_str(), NULL, 0); - - const char* ptr = text.c_str(); - int base = 10; - if (ptr[0] == '0') { - if (ptr[1] == 'x') { - // This is hex. - base = 16; - ptr += 2; - } else { - // This is octal. - base = 8; - } - } - - uint64 result = 0; - for (; *ptr != '\0'; ptr++) { - int digit = DigitValue(*ptr); - GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base) - << " Tokenizer::ParseInteger() passed text that could not have been" - " tokenized as an integer: " << CEscape(text); - if (digit > max_value || result > (max_value - digit) / base) { - // Overflow. - return false; - } - result = result * base + digit; - } - - *output = result; - return true; -} - -double Tokenizer::ParseFloat(const string& text) { - const char* start = text.c_str(); - char* end; - double result = NoLocaleStrtod(start, &end); - - // "1e" is not a valid float, but if the tokenizer reads it, it will - // report an error but still return it as a valid token. We need to - // accept anything the tokenizer could possibly return, error or not. - if (*end == 'e' || *end == 'E') { - ++end; - if (*end == '-' || *end == '+') ++end; - } - - // If the Tokenizer had allow_f_after_float_ enabled, the float may be - // suffixed with the letter 'f'. - if (*end == 'f' || *end == 'F') { - ++end; - } - - GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-') - << " Tokenizer::ParseFloat() passed text that could not have been" - " tokenized as a float: " << CEscape(text); - return result; -} - -void Tokenizer::ParseString(const string& text, string* output) { - output->clear(); - - // Reminder: text[0] is always the quote character. (If text is - // empty, it's invalid, so we'll just return.) - if (text.empty()) { - GOOGLE_LOG(DFATAL) - << " ParseString::ParseString() passed text that could not have been" - " tokenized as a string: " << CEscape(text); - return; - } - - output->reserve(text.size()); - - // Loop through the string copying characters to "output" and - // interpreting escape sequences. Note that any invalid escape - // sequences or other errors were already reported while tokenizing. - // In this case we do not need to produce valid results. - for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) { - if (*ptr == '\\' && ptr[1] != '\0') { - // An escape sequence. - ++ptr; - - if (OctalDigit::InClass(*ptr)) { - // An octal escape. May one, two, or three digits. - int code = DigitValue(*ptr); - if (OctalDigit::InClass(ptr[1])) { - ++ptr; - code = code * 8 + DigitValue(*ptr); - } - if (OctalDigit::InClass(ptr[1])) { - ++ptr; - code = code * 8 + DigitValue(*ptr); - } - output->push_back(static_cast<char>(code)); - - } else if (*ptr == 'x') { - // A hex escape. May zero, one, or two digits. (The zero case - // will have been caught as an error earlier.) - int code = 0; - if (HexDigit::InClass(ptr[1])) { - ++ptr; - code = DigitValue(*ptr); - } - if (HexDigit::InClass(ptr[1])) { - ++ptr; - code = code * 16 + DigitValue(*ptr); - } - output->push_back(static_cast<char>(code)); - - } else { - // Some other escape code. - output->push_back(TranslateEscape(*ptr)); - } - - } else if (*ptr == text[0]) { - // Ignore quote matching the starting quote. - } else { - output->push_back(*ptr); - } - } - - return; -} - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h deleted file mode 100644 index 841564ce..00000000 --- a/src/google/protobuf/io/tokenizer.h +++ /dev/null @@ -1,276 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Class for parsing tokenized text from a ZeroCopyInputStream. - -#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__ -#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { -namespace io { - -class ZeroCopyInputStream; // zero_copy_stream.h - -// Defined in this file. -class ErrorCollector; -class Tokenizer; - -// Abstract interface for an object which collects the errors that occur -// during parsing. A typical implementation might simply print the errors -// to stdout. -class LIBPROTOBUF_EXPORT ErrorCollector { - public: - inline ErrorCollector() {} - virtual ~ErrorCollector(); - - // Indicates that there was an error in the input at the given line and - // column numbers. The numbers are zero-based, so you may want to add - // 1 to each before printing them. - virtual void AddError(int line, int column, const string& message) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector); -}; - -// This class converts a stream of raw text into a stream of tokens for -// the protocol definition parser to parse. The tokens recognized are -// similar to those that make up the C language; see the TokenType enum for -// precise descriptions. Whitespace and comments are skipped. By default, -// C- and C++-style comments are recognized, but other styles can be used by -// calling set_comment_style(). -class LIBPROTOBUF_EXPORT Tokenizer { - public: - // Construct a Tokenizer that reads and tokenizes text from the given - // input stream and writes errors to the given error_collector. - // The caller keeps ownership of input and error_collector. - Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector); - ~Tokenizer(); - - enum TokenType { - TYPE_START, // Next() has not yet been called. - TYPE_END, // End of input reached. "text" is empty. - - TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not - // starting with a digit. It is an error for a number - // to be followed by an identifier with no space in - // between. - TYPE_INTEGER, // A sequence of digits representing an integer. Normally - // the digits are decimal, but a prefix of "0x" indicates - // a hex number and a leading zero indicates octal, just - // like with C numeric literals. A leading negative sign - // is NOT included in the token; it's up to the parser to - // interpret the unary minus operator on its own. - TYPE_FLOAT, // A floating point literal, with a fractional part and/or - // an exponent. Always in decimal. Again, never - // negative. - TYPE_STRING, // A quoted sequence of escaped characters. Either single - // or double quotes can be used, but they must match. - // A string literal cannot cross a line break. - TYPE_SYMBOL, // Any other printable character, like '!' or '+'. - // Symbols are always a single character, so "!+$%" is - // four tokens. - }; - - // Structure representing a token read from the token stream. - struct Token { - TokenType type; - string text; // The exact text of the token as it appeared in - // the input. e.g. tokens of TYPE_STRING will still - // be escaped and in quotes. - - // "line" and "column" specify the position of the first character of - // the token within the input stream. They are zero-based. - int line; - int 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(); - - // Advance to the next token. Returns false if the end of the input is - // reached. - bool Next(); - - // Parse helpers --------------------------------------------------- - - // Parses a TYPE_FLOAT token. This never fails, so long as the text actually - // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the - // result is undefined (possibly an assert failure). - static double ParseFloat(const string& text); - - // Parses a TYPE_STRING token. This never fails, so long as the text actually - // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the - // result is undefined (possibly an assert failure). - static void ParseString(const string& text, string* output); - - // Parses a TYPE_INTEGER token. Returns false if the result would be - // greater than max_value. Otherwise, returns true and sets *output to the - // result. If the text is not from a Token of type TYPE_INTEGER originally - // parsed by a Tokenizer, the result is undefined (possibly an assert - // failure). - static bool ParseInteger(const string& text, uint64 max_value, - uint64* output); - - // Options --------------------------------------------------------- - - // Set true to allow floats to be suffixed with the letter 'f'. Tokens - // which would otherwise be integers but which have the 'f' suffix will be - // forced to be interpreted as floats. For all other purposes, the 'f' is - // ignored. - void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; } - - // Valid values for set_comment_style(). - enum CommentStyle { - // Line comments begin with "//", block comments are delimited by "/*" and - // "*/". - CPP_COMMENT_STYLE, - // Line comments begin with "#". No way to write block comments. - SH_COMMENT_STYLE - }; - - // Sets the comment style. - void set_comment_style(CommentStyle style) { comment_style_ = style; } - - // ----------------------------------------------------------------- - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); - - Token current_; // Returned by current(). - - ZeroCopyInputStream* input_; - ErrorCollector* error_collector_; - - char current_char_; // == buffer_[buffer_pos_], updated by NextChar(). - const char* buffer_; // Current buffer returned from input_. - int buffer_size_; // Size of buffer_. - int buffer_pos_; // Current position within the buffer. - bool read_error_; // Did we previously encounter a read error? - - // Line and column number of current_char_ within the whole input stream. - int line_; - int column_; - - // Position in buffer_ where StartToken() was called. If the token - // started in the previous buffer, this is zero, and current_.text already - // contains the part of the token from the previous buffer. If not - // currently parsing a token, this is -1. - int token_start_; - - // Options. - bool allow_f_after_float_; - CommentStyle comment_style_; - - // Since we count columns we need to interpret tabs somehow. We'll take - // the standard 8-character definition for lack of any way to do better. - static const int kTabWidth = 8; - - // ----------------------------------------------------------------- - // Helper methods. - - // Consume this character and advance to the next one. - void NextChar(); - - // Read a new buffer from the input. - void Refresh(); - - // Called when the current character is the first character of a new - // token (not including whitespace or comments). - inline void StartToken(); - // Called when the current character is the first character after the - // end of the last token. After this returns, current_.text will - // contain all text consumed since StartToken() was called. - inline void EndToken(); - - // Convenience method to add an error at the current line and column. - void AddError(const string& message) { - error_collector_->AddError(line_, column_, message); - } - - // ----------------------------------------------------------------- - // The following four methods are used to consume tokens of specific - // types. They are actually used to consume all characters *after* - // the first, since the calling function consumes the first character - // in order to decide what kind of token is being read. - - // Read and consume a string, ending when the given delimiter is - // consumed. - void ConsumeString(char delimiter); - - // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER - // depending on what was read. This needs to know if the first - // character was a zero in order to correctly recognize hex and octal - // numbers. - // It also needs to know if the first characted was a . to parse floating - // point correctly. - TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot); - - // Consume the rest of a line. - void ConsumeLineComment(); - // Consume until "*/". - void ConsumeBlockComment(); - - // ----------------------------------------------------------------- - // These helper methods make the parsing code more readable. The - // "character classes" refered to are defined at the top of the .cc file. - // Basically it is a C++ class with one method: - // static bool InClass(char c); - // The method returns true if c is a member of this "class", like "Letter" - // or "Digit". - - // Returns true if the current character is of the given character - // class, but does not consume anything. - template<typename CharacterClass> - inline bool LookingAt(); - - // If the current character is in the given class, consume it and return - // true. Otherwise return false. - // e.g. TryConsumeOne<Letter>() - template<typename CharacterClass> - inline bool TryConsumeOne(); - - // Like above, but try to consume the specific character indicated. - inline bool TryConsume(char c); - - // Consume zero or more of the given character class. - template<typename CharacterClass> - inline void ConsumeZeroOrMore(); - - // Consume one or more of the given character class or log the given - // error message. - // e.g. ConsumeOneOrMore<Digit>("Expected digits."); - template<typename CharacterClass> - inline void ConsumeOneOrMore(const char* error); -}; - -// inline methods ==================================================== -inline const Tokenizer::Token& Tokenizer::current() { - return current_; -} - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__ diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc deleted file mode 100644 index 2171fcc3..00000000 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ /dev/null @@ -1,706 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <vector> -#include <math.h> -#include <limits.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/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace io { -namespace { - -// =================================================================== -// Data-Driven Test Infrastructure - -// TODO(kenton): This is copied from coded_stream_unittest. This is -// temporary until these fetaures are integrated into gTest itself. - -// TEST_1D and TEST_2D are macros I'd eventually like to see added to -// gTest. These macros can be used to declare tests which should be -// run multiple times, once for each item in some input array. TEST_1D -// tests all cases in a single input array. TEST_2D tests all -// combinations of cases from two arrays. The arrays must be statically -// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example: -// -// int kCases[] = {1, 2, 3, 4} -// TEST_1D(MyFixture, MyTest, kCases) { -// EXPECT_GT(kCases_case, 0); -// } -// -// This test iterates through the numbers 1, 2, 3, and 4 and tests that -// they are all grater than zero. In case of failure, the exact case -// which failed will be printed. The case type must be printable using -// ostream::operator<<. - -#define TEST_1D(FIXTURE, NAME, CASES) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template <typename CaseType> \ - void DoSingleCase(const CaseType& CASES##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES " case #" << i << ": " << CASES[i]); \ - DoSingleCase(CASES[i]); \ - } \ - } \ - \ - template <typename CaseType> \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case) - -#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \ - class FIXTURE##_##NAME##_DD : public FIXTURE { \ - protected: \ - template <typename CaseType1, typename CaseType2> \ - void DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case); \ - }; \ - \ - TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \ - for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \ - SCOPED_TRACE(testing::Message() \ - << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ - << #CASES2 " case #" << j << ": " << CASES2[j]); \ - DoSingleCase(CASES1[i], CASES2[j]); \ - } \ - } \ - } \ - \ - template <typename CaseType1, typename CaseType2> \ - void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \ - const CaseType2& CASES2##_case) - -// ------------------------------------------------------------------- - -// An input stream that is basically like an ArrayInputStream but sometimes -// returns empty buffers, just to throw us off. -class TestInputStream : public ZeroCopyInputStream { - public: - TestInputStream(const void* data, int size, int block_size) - : array_stream_(data, size, block_size), counter_(0) {} - ~TestInputStream() {} - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size) { - // We'll return empty buffers starting with the first buffer, and every - // 3 and 5 buffers after that. - if (counter_ % 3 == 0 || counter_ % 5 == 0) { - *data = NULL; - *size = 0; - ++counter_; - return true; - } else { - ++counter_; - return array_stream_.Next(data, size); - } - } - - void BackUp(int count) { return array_stream_.BackUp(count); } - bool Skip(int count) { return array_stream_.Skip(count); } - int64 ByteCount() const { return array_stream_.ByteCount(); } - - private: - ArrayInputStream array_stream_; - int counter_; -}; - -// ------------------------------------------------------------------- - -// An error collector which simply concatenates all its errors into a big -// block of text which can be checked. -class TestErrorCollector : public ErrorCollector { - public: - TestErrorCollector() {} - ~TestErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(int line, int column, const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", - line, column, message); - } -}; - -// ------------------------------------------------------------------- - -// We test each operation over a variety of block sizes to insure that -// we test cases where reads cross buffer boundaries as well as cases -// where they don't. This is sort of a brute-force approach to this, -// but it's easy to write and easy to understand. -const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024}; - -class TokenizerTest : public testing::Test { - protected: - // For easy testing. - uint64 ParseInteger(const string& text) { - uint64 result; - EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result)); - return result; - } -}; - -// =================================================================== - -// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -// In each test case, the entire input text should parse as a single token -// of the given type. -struct SimpleTokenCase { - string input; - Tokenizer::TokenType type; -}; - -inline ostream& operator<<(ostream& out, - const SimpleTokenCase& test_case) { - return out << CEscape(test_case.input); -} - -SimpleTokenCase kSimpleTokenCases[] = { - // Test identifiers. - { "hello", Tokenizer::TYPE_IDENTIFIER }, - - // Test integers. - { "123", Tokenizer::TYPE_INTEGER }, - { "0xab6", Tokenizer::TYPE_INTEGER }, - { "0XAB6", Tokenizer::TYPE_INTEGER }, - { "0X1234567", Tokenizer::TYPE_INTEGER }, - { "0x89abcdef", Tokenizer::TYPE_INTEGER }, - { "0x89ABCDEF", Tokenizer::TYPE_INTEGER }, - { "01234567", Tokenizer::TYPE_INTEGER }, - - // Test floats. - { "123.45", Tokenizer::TYPE_FLOAT }, - { "1.", Tokenizer::TYPE_FLOAT }, - { "1e3", Tokenizer::TYPE_FLOAT }, - { "1E3", Tokenizer::TYPE_FLOAT }, - { "1e-3", Tokenizer::TYPE_FLOAT }, - { "1e+3", Tokenizer::TYPE_FLOAT }, - { "1.e3", Tokenizer::TYPE_FLOAT }, - { "1.2e3", Tokenizer::TYPE_FLOAT }, - { ".1", Tokenizer::TYPE_FLOAT }, - { ".1e3", Tokenizer::TYPE_FLOAT }, - { ".1e-3", Tokenizer::TYPE_FLOAT }, - { ".1e+3", Tokenizer::TYPE_FLOAT }, - - // Test strings. - { "'hello'", Tokenizer::TYPE_STRING }, - { "\"foo\"", Tokenizer::TYPE_STRING }, - { "'a\"b'", Tokenizer::TYPE_STRING }, - { "\"a'b\"", Tokenizer::TYPE_STRING }, - { "'a\\'b'", Tokenizer::TYPE_STRING }, - { "\"a\\\"b\"", Tokenizer::TYPE_STRING }, - { "'\\xf'", Tokenizer::TYPE_STRING }, - { "'\\0'", Tokenizer::TYPE_STRING }, - - // Test symbols. - { "+", Tokenizer::TYPE_SYMBOL }, - { ".", Tokenizer::TYPE_SYMBOL }, -}; - -TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kSimpleTokenCases_case.input.data(), - kSimpleTokenCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Before Next() is called, the initial token should always be TYPE_START. - EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // Parse the token. - ASSERT_TRUE(tokenizer.Next()); - - // Check that it has the right type. - EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type); - // Check that it contains the complete input text. - EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text); - // Check that it is located at the beginning of the input - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - - // After Next() returns false, the token should have type TYPE_END. - EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column); - - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) { - // Test the "allow_f_after_float" option. - - // Set up the tokenizer. - const char* text = "1f 2.5f 6e3f 7F"; - TestInputStream input(text, strlen(text), kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - tokenizer.set_allow_f_after_float(true); - - // Advance through tokens and check that they are parsed as expected. - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "1f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "2.5f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "6e3f"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - ASSERT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, "7F"); - EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT); - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -#endif - -// ------------------------------------------------------------------- - -// In each case, the input is parsed to produce a list of tokens. The -// last token in "output" must have type TYPE_END. -struct MultiTokenCase { - string input; - Tokenizer::Token output[10]; // The compiler wants a constant array - // size for initialization to work. There - // is no reason this can't be increased if - // needed. -}; - -inline ostream& operator<<(ostream& out, - const MultiTokenCase& test_case) { - return out << CEscape(test_case.input); -} - -MultiTokenCase kMultiTokenCases[] = { - // Test empty input. - { "", { - { Tokenizer::TYPE_END , "" , 0, 0 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, - - // 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 }, - }}, -}; - -TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kMultiTokenCases_case.input.data(), - kMultiTokenCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Before Next() is called, the initial token should always be TYPE_START. - EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type); - EXPECT_EQ("", tokenizer.current().text); - EXPECT_EQ(0, tokenizer.current().line); - EXPECT_EQ(0, tokenizer.current().column); - - // Loop through all expected tokens. - int i = 0; - Tokenizer::Token token; - do { - token = kMultiTokenCases_case.output[i++]; - - SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text); - - // Next() should only return false when it hits the end token. - if (token.type != Tokenizer::TYPE_END) { - ASSERT_TRUE(tokenizer.Next()); - } else { - ASSERT_FALSE(tokenizer.Next()); - } - - // 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); - - } while (token.type != Tokenizer::TYPE_END); - - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error: -// "sorry, unimplemented: `method_call_expr' not supported by dump_expr" -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) - -TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) { - // Test the "comment_style" option. - - const char* text = "foo # bar\n" - "baz // qux\n" - "corge /* grault */\n" - "garply"; - const char* const kTokens[] = {"foo", // "# bar" is ignored - "baz", "/", "/", "qux", - "corge", "/", "*", "grault", "*", "/", - "garply"}; - - // Set up the tokenizer. - TestInputStream input(text, strlen(text), kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE); - - // Advance through tokens and check that they are parsed as expected. - for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) { - EXPECT_TRUE(tokenizer.Next()); - EXPECT_EQ(tokenizer.current().text, kTokens[i]); - } - - // There should be no more input. - EXPECT_FALSE(tokenizer.Next()); - // There should be no errors. - EXPECT_TRUE(error_collector.text_.empty()); -} - -#endif - -// ------------------------------------------------------------------- - -// Test parse helpers. It's not really worth setting up a full data-driven -// test here. -TEST_F(TokenizerTest, ParseInteger) { - EXPECT_EQ(0, ParseInteger("0")); - EXPECT_EQ(123, ParseInteger("123")); - EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12")); - EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12")); - EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF")); - EXPECT_EQ(01234567, ParseInteger("01234567")); - - // Test invalid integers that may still be tokenized as integers. - EXPECT_EQ(0, ParseInteger("0x")); - - uint64 i; -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - // Test invalid integers that will never be tokenized as integers. - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i), - "passed text that could not have been tokenized as an integer"); -#endif // GTEST_HAS_DEATH_TEST - - // Test overflows. - EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i)); - EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i)); - EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i)); -} - -TEST_F(TokenizerTest, ParseFloat) { - EXPECT_DOUBLE_EQ(1 , Tokenizer::ParseFloat("1.")); - EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1e3")); - EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1E3")); - EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3")); - EXPECT_DOUBLE_EQ(.1 , Tokenizer::ParseFloat(".1")); - EXPECT_DOUBLE_EQ(.25 , Tokenizer::ParseFloat(".25")); - EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3")); - EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3")); - EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3")); - EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3")); - EXPECT_DOUBLE_EQ(5 , Tokenizer::ParseFloat("5")); - EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12")); - EXPECT_DOUBLE_EQ(1.2 , Tokenizer::ParseFloat("1.2")); - EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2")); - - // Test invalid integers that may still be tokenized as integers. - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e")); - - // Test 'f' suffix. - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f")); - EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F")); - - // These should parse successfully even though they are out of range. - // Overflows become infinity and underflows become zero. - EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999")); - EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999")); - -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - // Test invalid integers that will never be tokenized as integers. - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"), - "passed text that could not have been tokenized as a float"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"), - "passed text that could not have been tokenized as a float"); - EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"), - "passed text that could not have been tokenized as a float"); -#endif // GTEST_HAS_DEATH_TEST -} - -TEST_F(TokenizerTest, ParseString) { - string output; - Tokenizer::ParseString("'hello'", &output); - EXPECT_EQ("hello", output); - Tokenizer::ParseString("\"blah\\nblah2\"", &output); - EXPECT_EQ("blah\nblah2", output); - Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output); - EXPECT_EQ("\1x\1\123\739\52\334n\3", output); - Tokenizer::ParseString("'\\x20\\x4'", &output); - EXPECT_EQ("\x20\x4", output); - - // Test invalid strings that may still be tokenized as strings. - Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid - EXPECT_EQ("\a?\v\t", output); - Tokenizer::ParseString("'", &output); - EXPECT_EQ("", output); - Tokenizer::ParseString("'\\", &output); - EXPECT_EQ("\\", output); - - // Test invalid strings that will never be tokenized as strings. -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet - EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output), - "passed text that could not have been tokenized as a string"); -#endif // GTEST_HAS_DEATH_TEST -} - -// ------------------------------------------------------------------- - -// Each case parses some input text, ignoring the tokens produced, and -// checks that the error output matches what is expected. -struct ErrorCase { - string input; - bool recoverable; // True if the tokenizer should be able to recover and - // parse more tokens after seeing this error. Cases - // for which this is true must end with "foo" as - // the last token, which the test will check for. - const char* errors; -}; - -inline ostream& operator<<(ostream& out, - const ErrorCase& test_case) { - return out << CEscape(test_case.input); -} - -ErrorCase kErrorCases[] = { - // String errors. - { "'\\l' foo", true, - "0:2: Invalid escape sequence in string literal.\n" }, - { "'\\x' foo", true, - "0:3: Expected hex digits for escape sequence.\n" }, - { "'foo", false, - "0:4: String literals cannot cross line boundaries.\n" }, - { "'bar\nfoo", true, - "0:4: String literals cannot cross line boundaries.\n" }, - - // Integer errors. - { "123foo", true, - "0:3: Need space between number and identifier.\n" }, - - // Hex/octal errors. - { "0x foo", true, - "0:2: \"0x\" must be followed by hex digits.\n" }, - { "0541823 foo", true, - "0:4: Numbers starting with leading zero must be in octal.\n" }, - { "0x123z foo", true, - "0:5: Need space between number and identifier.\n" }, - { "0x123.4 foo", true, - "0:5: Hex and octal numbers must be integers.\n" }, - { "0123.4 foo", true, - "0:4: Hex and octal numbers must be integers.\n" }, - - // Float errors. - { "1e foo", true, - "0:2: \"e\" must be followed by exponent.\n" }, - { "1e- foo", true, - "0:3: \"e\" must be followed by exponent.\n" }, - { "1.2.3 foo", true, - "0:3: Already saw decimal point or exponent; can't have another one.\n" }, - { "1e2.3 foo", true, - "0:3: Already saw decimal point or exponent; can't have another one.\n" }, - { "a.1 foo", true, - "0:1: Need space between identifier and decimal point.\n" }, - // allow_f_after_float not enabled, so this should be an error. - { "1.0f foo", true, - "0:3: Need space between number and identifier.\n" }, - - // Block comment errors. - { "/*", false, - "0:2: End-of-file inside block comment.\n" - "0:0: Comment started here.\n"}, - { "/*/*/ foo", true, - "0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"}, - - // Control characters. Multiple consecutive control characters should only - // produce one error. - { "\b foo", true, - "0:0: Invalid control characters encountered in text.\n" }, - { "\b\b foo", true, - "0:0: Invalid control characters encountered in text.\n" }, - - // Check that control characters at end of input don't result in an - // infinite loop. - { "\b", false, - "0:0: Invalid control characters encountered in text.\n" }, - - // Check recovery from '\0'. We have to explicitly specify the length of - // these strings because otherwise the string constructor will just call - // strlen() which will see the first '\0' and think that is the end of the - // string. - { string("\0foo", 4), true, - "0:0: Invalid control characters encountered in text.\n" }, - { string("\0\0foo", 5), true, - "0:0: Invalid control characters encountered in text.\n" }, -}; - -TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) { - // Set up the tokenizer. - TestInputStream input(kErrorCases_case.input.data(), - kErrorCases_case.input.size(), - kBlockSizes_case); - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - // Ignore all input, except remember if the last token was "foo". - bool last_was_foo = false; - while (tokenizer.Next()) { - last_was_foo = tokenizer.current().text == "foo"; - } - - // Check that the errors match what was expected. - EXPECT_EQ(error_collector.text_, kErrorCases_case.errors); - - // If the error was recoverable, make sure we saw "foo" after it. - if (kErrorCases_case.recoverable) { - EXPECT_TRUE(last_was_foo); - } -} - -// ------------------------------------------------------------------- - -TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) { - string text = "foo bar"; - TestInputStream input(text.data(), text.size(), kBlockSizes_case); - - // Create a tokenizer, read one token, then destroy it. - { - TestErrorCollector error_collector; - Tokenizer tokenizer(&input, &error_collector); - - tokenizer.Next(); - } - - // Only "foo" should have been read. - EXPECT_EQ(strlen("foo"), input.ByteCount()); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/zero_copy_stream.cc b/src/google/protobuf/io/zero_copy_stream.cc deleted file mode 100644 index 80559c4a..00000000 --- a/src/google/protobuf/io/zero_copy_stream.cc +++ /dev/null @@ -1,34 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/io/zero_copy_stream.h> - - -namespace google { -namespace protobuf { -namespace io { - -ZeroCopyInputStream::~ZeroCopyInputStream() {} -ZeroCopyOutputStream::~ZeroCopyOutputStream() {} - - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/zero_copy_stream.h b/src/google/protobuf/io/zero_copy_stream.h deleted file mode 100644 index bce5f2d3..00000000 --- a/src/google/protobuf/io/zero_copy_stream.h +++ /dev/null @@ -1,224 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream -// interfaces, which represent abstract I/O streams to and from which -// protocol buffers can be read and written. For a few simple -// implementations of these interfaces, see zero_copy_stream_impl.h. -// -// These interfaces are different from classic I/O streams in that they -// try to minimize the amount of data copying that needs to be done. -// To accomplish this, responsibility for allocating buffers is moved to -// the stream object, rather than being the responsibility of the caller. -// So, the stream can return a buffer which actually points directly into -// the final data structure where the bytes are to be stored, and the caller -// can interact directly with that buffer, eliminating an intermediate copy -// operation. -// -// As an example, consider the common case in which you are reading bytes -// from an array that is already in memory (or perhaps an mmap()ed file). -// With classic I/O streams, you would do something like: -// char buffer[BUFFER_SIZE]; -// input->Read(buffer, BUFFER_SIZE); -// DoSomething(buffer, BUFFER_SIZE); -// Then, the stream basically just calls memcpy() to copy the data from -// the array into your buffer. With a ZeroCopyInputStream, you would do -// this instead: -// const void* buffer; -// int size; -// input->Next(&buffer, &size); -// DoSomething(buffer, size); -// Here, no copy is performed. The input stream returns a pointer directly -// into the backing array, and the caller ends up reading directly from it. -// -// If you want to be able to read the old-fashion way, you can create -// a CodedInputStream or CodedOutputStream wrapping these objects and use -// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy -// step, but Coded*Stream will handle buffering so at least it will be -// reasonably efficient. -// -// ZeroCopyInputStream example: -// // Read in a file and print its contents to stdout. -// int fd = open("myfile", O_RDONLY); -// ZeroCopyInputStream* input = new FileInputStream(fd); -// -// const void* buffer; -// int size; -// while (input->Next(&buffer, &size)) { -// cout.write(buffer, size); -// } -// -// delete input; -// close(fd); -// -// ZeroCopyOutputStream example: -// // Copy the contents of "infile" to "outfile", using plain read() for -// // "infile" but a ZeroCopyOutputStream for "outfile". -// int infd = open("infile", O_RDONLY); -// int outfd = open("outfile", O_WRONLY); -// ZeroCopyInputStream* output = new FileOutputStream(outfd); -// -// void* buffer; -// int size; -// while (output->Next(&buffer, &size)) { -// int bytes = read(infd, buffer, size); -// if (bytes < size) { -// // Reached EOF. -// output->BackUp(size - bytes); -// break; -// } -// } -// -// delete output; -// close(infd); -// close(outfd); - -#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ -#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - -namespace google { - -namespace protobuf { -namespace io { - -// Defined in this file. -class ZeroCopyInputStream; -class ZeroCopyOutputStream; - -// Abstract interface similar to an input stream but designed to minimize -// copying. -class LIBPROTOBUF_EXPORT ZeroCopyInputStream { - public: - inline ZeroCopyInputStream() {} - virtual ~ZeroCopyInputStream(); - - // Obtains a chunk of data from the stream. - // - // Preconditions: - // * "size" and "data" are not NULL. - // - // Postconditions: - // * If the returned value is false, there is no more data to return or - // an error occurred. All errors are permanent. - // * Otherwise, "size" points to the actual number of bytes read and "data" - // points to a pointer to a buffer containing these bytes. - // * Ownership of this buffer remains with the stream, and the buffer - // remains valid only until some other method of the stream is called - // or the stream is destroyed. - // * It is legal for the returned buffer to have zero size, as long - // as repeatedly calling Next() eventually yields a buffer with non-zero - // size. - virtual bool Next(const void** data, int* size) = 0; - - // Backs up a number of bytes, so that the next call to Next() returns - // data again that was already returned by the last call to Next(). This - // is useful when writing procedures that are only supposed to read up - // to a certain point in the input, then return. If Next() returns a - // buffer that goes beyond what you wanted to read, you can use BackUp() - // to return to the point where you intended to finish. - // - // Preconditions: - // * The last method called must have been Next(). - // * count must be less than or equal to the size of the last buffer - // returned by Next(). - // - // Postconditions: - // * The last "count" bytes of the last buffer returned by Next() will be - // pushed back into the stream. Subsequent calls to Next() will return - // the same data again before producing new data. - virtual void BackUp(int count) = 0; - - // Skips a number of bytes. Returns false if the end of the stream is - // reached or some input error occurred. In the end-of-stream case, the - // stream is advanced to the end of the stream (so ByteCount() will return - // the total size of the stream). - virtual bool Skip(int count) = 0; - - // Returns the total number of bytes read since this object was created. - virtual int64 ByteCount() const = 0; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); -}; - -// Abstract interface similar to an output stream but designed to minimize -// copying. -class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { - public: - inline ZeroCopyOutputStream() {} - virtual ~ZeroCopyOutputStream(); - - // Obtains a buffer into which data can be written. Any data written - // into this buffer will eventually (maybe instantly, maybe later on) - // be written to the output. - // - // Preconditions: - // * "size" and "data" are not NULL. - // - // Postconditions: - // * If the returned value is false, an error occurred. All errors are - // permanent. - // * Otherwise, "size" points to the actual number of bytes in the buffer - // and "data" points to the buffer. - // * Ownership of this buffer remains with the stream, and the buffer - // remains valid only until some other method of the stream is called - // or the stream is destroyed. - // * Any data which the caller stores in this buffer will eventually be - // written to the output (unless BackUp() is called). - // * It is legal for the returned buffer to have zero size, as long - // as repeatedly calling Next() eventually yields a buffer with non-zero - // size. - virtual bool Next(void** data, int* size) = 0; - - // Backs up a number of bytes, so that the end of the last buffer returned - // by Next() is not actually written. This is needed when you finish - // writing all the data you want to write, but the last buffer was bigger - // than you needed. You don't want to write a bunch of garbage after the - // end of your data, so you use BackUp() to back up. - // - // Preconditions: - // * The last method called must have been Next(). - // * count must be less than or equal to the size of the last buffer - // returned by Next(). - // * The caller must not have written anything to the last "count" bytes - // of that buffer. - // - // Postconditions: - // * The last "count" bytes of the last buffer returned by Next() will be - // ignored. - virtual void BackUp(int count) = 0; - - // Returns the total number of bytes written since this object was created. - virtual int64 ByteCount() const = 0; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); -}; - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc deleted file mode 100644 index 7ff84460..00000000 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ /dev/null @@ -1,793 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifdef _MSC_VER -#include <io.h> -#else -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#endif -#include <errno.h> -#include <iostream> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/stl_util-inl.h> - -namespace google { -namespace protobuf { -namespace io { - -#ifdef _WIN32 -// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its -// return value is undefined. We re-define it to always produce an error. -#define lseek(fd, offset, origin) ((off_t)-1) -#endif - -namespace { - - -// EINTR sucks. -int close_no_eintr(int fd) { - int result; - do { - result = close(fd); - } while (result < 0 && errno == EINTR); - return result; -} - -// Default block size for Copying{In,Out}putStreamAdaptor. -static const int kDefaultBlockSize = 8192; - -} // namespace - -// =================================================================== - -ArrayInputStream::ArrayInputStream(const void* data, int size, - int block_size) - : data_(reinterpret_cast<const uint8*>(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayInputStream::~ArrayInputStream() { -} - -bool ArrayInputStream::Next(const void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayInputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -bool ArrayInputStream::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - last_returned_size_ = 0; // Don't let caller back up. - if (count > size_ - position_) { - position_ = size_; - return false; - } else { - position_ += count; - return true; - } -} - -int64 ArrayInputStream::ByteCount() const { - return position_; -} - - -// =================================================================== - -ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size) - : data_(reinterpret_cast<uint8*>(data)), - size_(size), - block_size_(block_size > 0 ? block_size : size), - position_(0), - last_returned_size_(0) { -} - -ArrayOutputStream::~ArrayOutputStream() { -} - -bool ArrayOutputStream::Next(void** data, int* size) { - if (position_ < size_) { - last_returned_size_ = min(block_size_, size_ - position_); - *data = data_ + position_; - *size = last_returned_size_; - position_ += last_returned_size_; - return true; - } else { - // We're at the end of the array. - last_returned_size_ = 0; // Don't let caller back up. - return false; - } -} - -void ArrayOutputStream::BackUp(int count) { - GOOGLE_CHECK_GT(last_returned_size_, 0) - << "BackUp() can only be called after a successful Next()."; - GOOGLE_CHECK_LE(count, last_returned_size_); - GOOGLE_CHECK_GE(count, 0); - position_ -= count; - last_returned_size_ = 0; // Don't let caller back up further. -} - -int64 ArrayOutputStream::ByteCount() const { - return position_; -} - -// =================================================================== - -StringOutputStream::StringOutputStream(string* target) - : target_(target) { -} - -StringOutputStream::~StringOutputStream() { -} - -bool StringOutputStream::Next(void** data, int* size) { - int old_size = target_->size(); - - // Grow the string. - if (old_size < target_->capacity()) { - // Resize the string to match its capacity, since we can get away - // without a memory allocation this way. - target_->resize(target_->capacity()); - } else { - // Size has reached capacity, so double the size. Also make sure - // that the new size is at least kMinimumSize. - target_->resize( - max(old_size * 2, - kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. - } - - *data = string_as_array(target_) + old_size; - *size = target_->size() - old_size; - return true; -} - -void StringOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_LE(count, target_->size()); - target_->resize(target_->size() - count); -} - -int64 StringOutputStream::ByteCount() const { - return target_->size(); -} - -// =================================================================== - - -// =================================================================== - -CopyingInputStream::~CopyingInputStream() {} - -int CopyingInputStream::Skip(int count) { - char junk[4096]; - int skipped = 0; - while (skipped < count) { - int bytes = Read(junk, min(count, implicit_cast<int>(sizeof(junk)))); - if (bytes <= 0) { - // EOF or read error. - return skipped; - } - skipped += bytes; - } - return skipped; -} - -CopyingInputStreamAdaptor::CopyingInputStreamAdaptor( - CopyingInputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0), - backup_bytes_(0) { -} - -CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() { - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingInputStreamAdaptor::Next(const void** data, int* size) { - if (failed_) { - // Already failed on a previous read. - return false; - } - - AllocateBufferIfNeeded(); - - if (backup_bytes_ > 0) { - // We have data left over from a previous BackUp(), so just return that. - *data = buffer_.get() + buffer_used_ - backup_bytes_; - *size = backup_bytes_; - backup_bytes_ = 0; - return true; - } - - // Read new data into the buffer. - buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_); - if (buffer_used_ <= 0) { - // EOF or read error. We don't need the buffer anymore. - if (buffer_used_ < 0) { - // Read error (not EOF). - failed_ = true; - } - FreeBuffer(); - return false; - } - position_ += buffer_used_; - - *size = buffer_used_; - *data = buffer_.get(); - return true; -} - -void CopyingInputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - GOOGLE_CHECK_GE(count, 0) - << " Parameter to BackUp() can't be negative."; - - backup_bytes_ = count; -} - -bool CopyingInputStreamAdaptor::Skip(int count) { - GOOGLE_CHECK_GE(count, 0); - - if (failed_) { - // Already failed on a previous read. - return false; - } - - // First skip any bytes left over from a previous BackUp(). - if (backup_bytes_ >= count) { - // We have more data left over than we're trying to skip. Just chop it. - backup_bytes_ -= count; - return true; - } - - count -= backup_bytes_; - backup_bytes_ = 0; - - int skipped = copying_stream_->Skip(count); - position_ += skipped; - return skipped == count; -} - -int64 CopyingInputStreamAdaptor::ByteCount() const { - return position_ - backup_bytes_; -} - -void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_.get() == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingInputStreamAdaptor::FreeBuffer() { - GOOGLE_CHECK_EQ(backup_bytes_, 0); - buffer_used_ = 0; - buffer_.reset(); -} - -// =================================================================== - -CopyingOutputStream::~CopyingOutputStream() {} - -CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor( - CopyingOutputStream* copying_stream, int block_size) - : copying_stream_(copying_stream), - owns_copying_stream_(false), - failed_(false), - position_(0), - buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize), - buffer_used_(0) { -} - -CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() { - WriteBuffer(); - if (owns_copying_stream_) { - delete copying_stream_; - } -} - -bool CopyingOutputStreamAdaptor::Flush() { - return WriteBuffer(); -} - -bool CopyingOutputStreamAdaptor::Next(void** data, int* size) { - if (buffer_used_ == buffer_size_) { - if (!WriteBuffer()) return false; - } - - AllocateBufferIfNeeded(); - - *data = buffer_.get() + buffer_used_; - *size = buffer_size_ - buffer_used_; - buffer_used_ = buffer_size_; - return true; -} - -void CopyingOutputStreamAdaptor::BackUp(int count) { - GOOGLE_CHECK_GE(count, 0); - GOOGLE_CHECK_EQ(buffer_used_, buffer_size_) - << " BackUp() can only be called after Next()."; - GOOGLE_CHECK_LE(count, buffer_used_) - << " Can't back up over more bytes than were returned by the last call" - " to Next()."; - - buffer_used_ -= count; -} - -int64 CopyingOutputStreamAdaptor::ByteCount() const { - return position_ + buffer_used_; -} - -bool CopyingOutputStreamAdaptor::WriteBuffer() { - if (failed_) { - // Already failed on a previous write. - return false; - } - - if (buffer_used_ == 0) return true; - - if (copying_stream_->Write(buffer_.get(), buffer_used_)) { - position_ += buffer_used_; - buffer_used_ = 0; - return true; - } else { - failed_ = true; - FreeBuffer(); - return false; - } -} - -void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() { - if (buffer_ == NULL) { - buffer_.reset(new uint8[buffer_size_]); - } -} - -void CopyingOutputStreamAdaptor::FreeBuffer() { - buffer_used_ = 0; - buffer_.reset(); -} - -// =================================================================== - -FileInputStream::FileInputStream(int file_descriptor, int block_size) - : copying_input_(file_descriptor), - impl_(©ing_input_, block_size) { -} - -FileInputStream::~FileInputStream() {} - -bool FileInputStream::Close() { - return copying_input_.Close(); -} - -bool FileInputStream::Next(const void** data, int* size) { - return impl_.Next(data, size); -} - -void FileInputStream::BackUp(int count) { - impl_.BackUp(count); -} - -bool FileInputStream::Skip(int count) { - return impl_.Skip(count); -} - -int64 FileInputStream::ByteCount() const { - return impl_.ByteCount(); -} - -FileInputStream::CopyingFileInputStream::CopyingFileInputStream( - int file_descriptor) - : file_(file_descriptor), - close_on_delete_(false), - is_closed_(false), - errno_(0), - previous_seek_failed_(false) { -} - -FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() { - if (close_on_delete_) { - if (!Close()) { - GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); - } - } -} - -bool FileInputStream::CopyingFileInputStream::Close() { - GOOGLE_CHECK(!is_closed_); - - is_closed_ = true; - if (close_no_eintr(file_) != 0) { - // The docs on close() do not specify whether a file descriptor is still - // open after close() fails with EIO. However, the glibc source code - // seems to indicate that it is not. - errno_ = errno; - return false; - } - - return true; -} - -int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) { - GOOGLE_CHECK(!is_closed_); - - int result; - do { - result = read(file_, buffer, size); - } while (result < 0 && errno == EINTR); - - if (result < 0) { - // Read error (not EOF). - errno_ = errno; - } - - return result; -} - -int FileInputStream::CopyingFileInputStream::Skip(int count) { - GOOGLE_CHECK(!is_closed_); - - if (!previous_seek_failed_ && - lseek(file_, count, SEEK_CUR) != (off_t)-1) { - // Seek succeeded. - return count; - } else { - // Failed to seek. - - // Note to self: Don't seek again. This file descriptor doesn't - // support it. - previous_seek_failed_ = true; - - // Use the default implementation. - return CopyingInputStream::Skip(count); - } -} - -// =================================================================== - -FileOutputStream::FileOutputStream(int file_descriptor, int block_size) - : copying_output_(file_descriptor), - impl_(©ing_output_, block_size) { -} - -FileOutputStream::~FileOutputStream() { - impl_.Flush(); -} - -bool FileOutputStream::Close() { - bool flush_succeeded = impl_.Flush(); - return copying_output_.Close() && flush_succeeded; -} - -bool FileOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void FileOutputStream::BackUp(int count) { - impl_.BackUp(count); -} - -int64 FileOutputStream::ByteCount() const { - return impl_.ByteCount(); -} - -FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( - int file_descriptor) - : file_(file_descriptor), - close_on_delete_(false), - is_closed_(false), - errno_(0) { -} - -FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { - if (close_on_delete_) { - if (!Close()) { - GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_); - } - } -} - -bool FileOutputStream::CopyingFileOutputStream::Close() { - GOOGLE_CHECK(!is_closed_); - - is_closed_ = true; - if (close_no_eintr(file_) != 0) { - // The docs on close() do not specify whether a file descriptor is still - // open after close() fails with EIO. However, the glibc source code - // seems to indicate that it is not. - errno_ = errno; - return false; - } - - return true; -} - -bool FileOutputStream::CopyingFileOutputStream::Write( - const void* buffer, int size) { - GOOGLE_CHECK(!is_closed_); - int total_written = 0; - - const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer); - - while (total_written < size) { - int bytes; - do { - bytes = write(file_, buffer_base + total_written, size - total_written); - } while (bytes < 0 && errno == EINTR); - - if (bytes <= 0) { - // Write error. - - // FIXME(kenton): According to the man page, if write() returns zero, - // there was no error; write() simply did not write anything. It's - // unclear under what circumstances this might happen, but presumably - // errno won't be set in this case. I am confused as to how such an - // event should be handled. For now I'm treating it as an error, since - // retrying seems like it could lead to an infinite loop. I suspect - // this never actually happens anyway. - - if (bytes < 0) { - errno_ = errno; - } - return false; - } - total_written += bytes; - } - - return true; -} - -// =================================================================== - -IstreamInputStream::IstreamInputStream(istream* input, int block_size) - : copying_input_(input), - impl_(©ing_input_, block_size) { -} - -IstreamInputStream::~IstreamInputStream() {} - -bool IstreamInputStream::Next(const void** data, int* size) { - return impl_.Next(data, size); -} - -void IstreamInputStream::BackUp(int count) { - impl_.BackUp(count); -} - -bool IstreamInputStream::Skip(int count) { - return impl_.Skip(count); -} - -int64 IstreamInputStream::ByteCount() const { - return impl_.ByteCount(); -} - -IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream( - istream* input) - : input_(input) { -} - -IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {} - -int IstreamInputStream::CopyingIstreamInputStream::Read( - void* buffer, int size) { - input_->read(reinterpret_cast<char*>(buffer), size); - int result = input_->gcount(); - if (result == 0 && input_->fail() && !input_->eof()) { - return -1; - } - return result; -} - -// =================================================================== - -OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size) - : copying_output_(output), - impl_(©ing_output_, block_size) { -} - -OstreamOutputStream::~OstreamOutputStream() { - impl_.Flush(); -} - -bool OstreamOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void OstreamOutputStream::BackUp(int count) { - impl_.BackUp(count); -} - -int64 OstreamOutputStream::ByteCount() const { - return impl_.ByteCount(); -} - -OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream( - ostream* output) - : output_(output) { -} - -OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() { -} - -bool OstreamOutputStream::CopyingOstreamOutputStream::Write( - const void* buffer, int size) { - output_->write(reinterpret_cast<const char*>(buffer), size); - return output_->good(); -} - -// =================================================================== - -ConcatenatingInputStream::ConcatenatingInputStream( - ZeroCopyInputStream* const streams[], int count) - : streams_(streams), stream_count_(count), bytes_retired_(0) { -} - -ConcatenatingInputStream::~ConcatenatingInputStream() { -} - -bool ConcatenatingInputStream::Next(const void** data, int* size) { - while (stream_count_ > 0) { - if (streams_[0]->Next(data, size)) return true; - - // That stream is done. Advance to the next one. - bytes_retired_ += streams_[0]->ByteCount(); - ++streams_; - --stream_count_; - } - - // No more streams. - return false; -} - -void ConcatenatingInputStream::BackUp(int count) { - if (stream_count_ > 0) { - streams_[0]->BackUp(count); - } else { - GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next()."; - } -} - -bool ConcatenatingInputStream::Skip(int count) { - while (stream_count_ > 0) { - // Assume that ByteCount() can be used to find out how much we actually - // skipped when Skip() fails. - int64 target_byte_count = streams_[0]->ByteCount() + count; - if (streams_[0]->Skip(count)) return true; - - // Hit the end of the stream. Figure out how many more bytes we still have - // to skip. - int64 final_byte_count = streams_[0]->ByteCount(); - GOOGLE_DCHECK_LT(final_byte_count, target_byte_count); - count = target_byte_count - final_byte_count; - - // That stream is done. Advance to the next one. - bytes_retired_ += final_byte_count; - ++streams_; - --stream_count_; - } - - return false; -} - -int64 ConcatenatingInputStream::ByteCount() const { - if (stream_count_ == 0) { - return bytes_retired_; - } else { - return bytes_retired_ + streams_[0]->ByteCount(); - } -} - - -// =================================================================== - -LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input, - int64 limit) - : input_(input), limit_(limit) {} - -LimitingInputStream::~LimitingInputStream() { - // If we overshot the limit, back up. - if (limit_ < 0) input_->BackUp(-limit_); -} - -bool LimitingInputStream::Next(const void** data, int* size) { - if (limit_ < 0) return false; - if (!input_->Next(data, size)) return false; - - limit_ -= *size; - if (limit_ < 0) { - // We overshot the limit. Reduce *size to hide the rest of the buffer. - *size += limit_; - } - return true; -} - -void LimitingInputStream::BackUp(int count) { - if (limit_ < 0) { - input_->BackUp(count - limit_); - limit_ = count; - } else { - input_->BackUp(count); - limit_ += count; - } -} - -bool LimitingInputStream::Skip(int count) { - if (count > limit_) { - if (limit_ < 0) return false; - input_->Skip(limit_); - limit_ = 0; - return false; - } else { - if (!input_->Skip(count)) return false; - limit_ -= count; - return true; - } -} - -int64 LimitingInputStream::ByteCount() const { - if (limit_ < 0) { - return input_->ByteCount() + limit_; - } else { - return input_->ByteCount(); - } -} - - -// =================================================================== - -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h deleted file mode 100644 index bd73afb7..00000000 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ /dev/null @@ -1,617 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains common implementations of the interfaces defined in -// zero_copy_stream.h. These implementations cover I/O on raw arrays, -// strings, and file descriptors. Of course, many users will probably -// want to write their own implementations of these interfaces specific -// to the particular I/O abstractions they prefer to use, but these -// should cover the most common cases. - -#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ -#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ - -#include <string> -#include <iosfwd> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/common.h> - - -namespace google { -namespace protobuf { -namespace io { - -// =================================================================== - -// A ZeroCopyInputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { - public: - // Create an InputStream that returns the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayInputStream(const void* data, int size, int block_size = -1); - ~ArrayInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - const uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream backed by an in-memory array of bytes. -class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { - public: - // Create an OutputStream that writes to the bytes pointed to by "data". - // "data" remains the property of the caller but must remain valid until - // the stream is destroyed. If a block_size is given, calls to Next() - // will return data blocks no larger than the given size. Otherwise, the - // first call to Next() returns the entire array. block_size is mainly - // useful for testing; in production you would probably never want to set - // it. - ArrayOutputStream(void* data, int size, int block_size = -1); - ~ArrayOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - uint8* const data_; // The byte array. - const int size_; // Total size of the array. - const int block_size_; // How many bytes to return at a time. - - int position_; - int last_returned_size_; // How many bytes we returned last time Next() - // was called (used for error checking only). - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which appends bytes to a string. -class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { - public: - // Create a StringOutputStream which appends bytes to the given string. - // The string remains property of the caller, but it MUST NOT be accessed - // in any way until the stream is destroyed. - // - // Hint: If you call target->reserve(n) before creating the stream, - // the first call to Next() will return at least n bytes of buffer - // space. - explicit StringOutputStream(string* target); - ~StringOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - static const int kMinimumSize = 16; - - string* target_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream); -}; - -// Note: There is no StringInputStream. Instead, just create an -// ArrayInputStream as follows: -// ArrayInputStream input(str.data(), str.size()); - -// =================================================================== - - -// =================================================================== - -// A generic traditional input stream interface. -// -// Lots of traditional input streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every read -// involves copying bytes into a buffer. If you want to take such an -// interface and make a ZeroCopyInputStream based on it, simply implement -// CopyingInputStream and then use CopyingInputStreamAdaptor. -// -// CopyingInputStream implementations should avoid buffering if possible. -// CopyingInputStreamAdaptor does its own buffering and will read data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingInputStream { - public: - virtual ~CopyingInputStream(); - - // Reads up to "size" bytes into the given buffer. Returns the number of - // bytes read. Read() waits until at least one byte is available, or - // returns zero if no bytes will ever become available (EOF), or -1 if a - // permanent read error occurred. - virtual int Read(void* buffer, int size) = 0; - - // Skips the next "count" bytes of input. Returns the number of bytes - // actually skipped. This will always be exactly equal to "count" unless - // EOF was reached or a permanent read error occurred. - // - // The default implementation just repeatedly calls Read() into a scratch - // buffer. - virtual int Skip(int count); -}; - -// A ZeroCopyInputStream which reads from a CopyingInputStream. This is -// useful for implementing ZeroCopyInputStreams that read from traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to read from file descriptors or C++ istreams, this is -// already implemented for you: use FileInputStream or IstreamInputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given CopyingInputStream. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. The caller retains ownership of - // copying_stream unless SetOwnsCopyingStream(true) is called. - explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, - int block_size = -1); - ~CopyingInputStreamAdaptor(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to - // delete the underlying CopyingInputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer and resets buffer_used_. - void FreeBuffer(); - - // The underlying copying stream. - CopyingInputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started reading. - int64 position_; - - // Data is read into this buffer. It may be NULL if no buffer is currently - // in use. Otherwise, it points to an array of size buffer_size_. - scoped_array<uint8> buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - // Number of bytes in the buffer which were backed up over by a call to - // BackUp(). These need to be returned again. - // 0 <= backup_bytes_ <= buffer_used_ - int backup_bytes_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor); -}; - -// =================================================================== - -// A generic traditional output stream interface. -// -// Lots of traditional output streams (e.g. file descriptors, C stdio -// streams, and C++ iostreams) expose an interface where every write -// involves copying bytes from a buffer. If you want to take such an -// interface and make a ZeroCopyOutputStream based on it, simply implement -// CopyingOutputStream and then use CopyingOutputStreamAdaptor. -// -// CopyingOutputStream implementations should avoid buffering if possible. -// CopyingOutputStreamAdaptor does its own buffering and will write data -// in large blocks. -class LIBPROTOBUF_EXPORT CopyingOutputStream { - public: - virtual ~CopyingOutputStream(); - - // Writes "size" bytes from the given buffer to the output. Returns true - // if successful, false on a write error. - virtual bool Write(const void* buffer, int size) = 0; -}; - -// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is -// useful for implementing ZeroCopyOutputStreams that write to traditional -// streams. Note that this class is not really zero-copy. -// -// If you want to write to file descriptors or C++ ostreams, this is -// already implemented for you: use FileOutputStream or OstreamOutputStream -// respectively. -class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given Unix file descriptor. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, - int block_size = -1); - ~CopyingOutputStreamAdaptor(); - - // Writes all pending data to the underlying stream. Returns false if a - // write error occurred on the underlying stream. (The underlying - // stream itself is not necessarily flushed.) - bool Flush(); - - // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to - // delete the underlying CopyingOutputStream when it is destroyed. - void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - // Write the current buffer, if it is present. - bool WriteBuffer(); - // Insures that buffer_ is not NULL. - void AllocateBufferIfNeeded(); - // Frees the buffer. - void FreeBuffer(); - - // The underlying copying stream. - CopyingOutputStream* copying_stream_; - bool owns_copying_stream_; - - // True if we have seen a permenant error from the underlying stream. - bool failed_; - - // The current position of copying_stream_, relative to the point where - // we started writing. - int64 position_; - - // Data is written from this buffer. It may be NULL if no buffer is - // currently in use. Otherwise, it points to an array of size buffer_size_. - scoped_array<uint8> buffer_; - const int buffer_size_; - - // Number of valid bytes currently in the buffer (i.e. the size last - // returned by Next()). When BackUp() is called, we just reduce this. - // 0 <= buffer_used_ <= buffer_size_. - int buffer_used_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor); -}; - -// =================================================================== - -// A ZeroCopyInputStream which reads from a file descriptor. -// -// FileInputStream is preferred over using an ifstream with IstreamInputStream. -// The latter will introduce an extra layer of buffering, harming performance. -// Also, it's conceivable that FileInputStream could someday be enhanced -// to use zero-copy file descriptors on OSs which support them. -class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given Unix file descriptor. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. - explicit FileInputStream(int file_descriptor, int block_size = -1); - ~FileInputStream(); - - // Flushes any buffers and closes the underlying file. Returns false if - // an error occurs during the process; use GetErrno() to examine the error. - // Even if an error occurs, the file descriptor is closed when this returns. - bool Close(); - - // By default, the file descriptor is not closed when the stream is - // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: - // This leaves no way for the caller to detect if close() fails. If - // detecting close() errors is important to you, you should arrange - // to close the descriptor yourself. - void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } - - // If an I/O error has occurred on this file descriptor, this is the - // errno from that error. Otherwise, this is zero. Once an error - // occurs, the stream is broken and all subsequent operations will - // fail. - int GetErrno() { return copying_input_.GetErrno(); } - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { - public: - CopyingFileInputStream(int file_descriptor); - ~CopyingFileInputStream(); - - bool Close(); - void SetCloseOnDelete(bool value) { close_on_delete_ = value; } - int GetErrno() { return errno_; } - - // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); - int Skip(int count); - - private: - // The file descriptor. - const int file_; - bool close_on_delete_; - bool is_closed_; - - // The errno of the I/O error, if one has occurred. Otherwise, zero. - int errno_; - - // Did we try to seek once and fail? If so, we assume this file descriptor - // doesn't support seeking and won't try again. - bool previous_seek_failed_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); - }; - - CopyingFileInputStream copying_input_; - CopyingInputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which writes to a file descriptor. -// -// FileInputStream is preferred over using an ofstream with OstreamOutputStream. -// The latter will introduce an extra layer of buffering, harming performance. -// Also, it's conceivable that FileInputStream could someday be enhanced -// to use zero-copy file descriptors on OSs which support them. -class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given Unix file descriptor. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit FileOutputStream(int file_descriptor, int block_size = -1); - ~FileOutputStream(); - - // Flushes any buffers and closes the underlying file. Returns false if - // an error occurs during the process; use GetErrno() to examine the error. - // Even if an error occurs, the file descriptor is closed when this returns. - bool Close(); - - // By default, the file descriptor is not closed when the stream is - // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: - // This leaves no way for the caller to detect if close() fails. If - // detecting close() errors is important to you, you should arrange - // to close the descriptor yourself. - void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } - - // If an I/O error has occurred on this file descriptor, this is the - // errno from that error. Otherwise, this is zero. Once an error - // occurs, the stream is broken and all subsequent operations will - // fail. - int GetErrno() { return copying_output_.GetErrno(); } - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { - public: - CopyingFileOutputStream(int file_descriptor); - ~CopyingFileOutputStream(); - - bool Close(); - void SetCloseOnDelete(bool value) { close_on_delete_ = value; } - int GetErrno() { return errno_; } - - // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); - - private: - // The file descriptor. - const int file_; - bool close_on_delete_; - bool is_closed_; - - // The errno of the I/O error, if one has occurred. Otherwise, zero. - int errno_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); - }; - - CopyingFileOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which reads from a C++ istream. -// -// Note that for reading files (or anything represented by a file descriptor), -// FileInputStream is more efficient. -class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { - public: - // Creates a stream that reads from the given C++ istream. - // If a block_size is given, it specifies the number of bytes that - // should be read and returned with each call to Next(). Otherwise, - // a reasonable default is used. - explicit IstreamInputStream(istream* stream, int block_size = -1); - ~IstreamInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { - public: - CopyingIstreamInputStream(istream* input); - ~CopyingIstreamInputStream(); - - // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); - // (We use the default implementation of Skip().) - - private: - // The stream. - istream* input_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); - }; - - CopyingIstreamInputStream copying_input_; - CopyingInputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); -}; - -// =================================================================== - -// A ZeroCopyOutputStream which writes to a C++ ostream. -// -// Note that for writing files (or anything represented by a file descriptor), -// FileOutputStream is more efficient. -class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { - public: - // Creates a stream that writes to the given C++ ostream. - // If a block_size is given, it specifies the size of the buffers - // that should be returned by Next(). Otherwise, a reasonable default - // is used. - explicit OstreamOutputStream(ostream* stream, int block_size = -1); - ~OstreamOutputStream(); - - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; - - private: - class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { - public: - CopyingOstreamOutputStream(ostream* output); - ~CopyingOstreamOutputStream(); - - // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); - - private: - // The stream. - ostream* output_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); - }; - - CopyingOstreamOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which reads from several other streams in sequence. -// ConcatenatingInputStream is unable to distinguish between end-of-stream -// and read errors in the underlying streams, so it assumes any errors mean -// end-of-stream. So, if the underlying streams fail for any other reason, -// ConcatenatingInputStream may do odd things. It is suggested that you do -// not use ConcatenatingInputStream on streams that might produce read errors -// other than end-of-stream. -class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { - public: - // All streams passed in as well as the array itself must remain valid - // until the ConcatenatingInputStream is destroyed. - ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); - ~ConcatenatingInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - // As streams are retired, streams_ is incremented and count_ is - // decremented. - ZeroCopyInputStream* const* streams_; - int stream_count_; - int64 bytes_retired_; // Bytes read from previous streams. - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); -}; - -// =================================================================== - -// A ZeroCopyInputStream which wraps some other stream and limits it to -// a particular byte count. -class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { - public: - LimitingInputStream(ZeroCopyInputStream* input, int64 limit); - ~LimitingInputStream(); - - // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; - - - private: - ZeroCopyInputStream* input_; - int64 limit_; // Decreases as we go, becomes negative if we overshoot. - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); -}; - -// =================================================================== - -} // namespace io -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc deleted file mode 100644 index c618041f..00000000 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ /dev/null @@ -1,443 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Testing strategy: For each type of I/O (array, string, file, etc.) we -// create an output stream and write some data to it, then create a -// corresponding input stream to read the same data back and expect it to -// match. When the data is written, it is written in several small chunks -// of varying sizes, with a BackUp() after each chunk. It is read back -// similarly, but with chunks separated at different points. The whole -// process is run with a variety of block sizes for both the input and -// the output. -// -// TODO(kenton): Rewrite this test to bring it up to the standards of all -// the other proto2 tests. May want to wait for gTest to implement -// "parametized tests" so that one set of tests can be used on all the -// implementations. - -#ifdef _MSC_VER -#include <io.h> -#else -#include <unistd.h> -#endif -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <sstream> - -#include <google/protobuf/io/zero_copy_stream_impl.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace io { -namespace { - -#ifdef _WIN32 -#define pipe(fds) _pipe(fds, 4096, O_BINARY) -#endif - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -class IoTest : public testing::Test { - protected: - // Test helpers. - - // Helper to write an array of data to an output stream. - bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size); - // Helper to read a fixed-length array of data from an input stream. - int ReadFromInput(ZeroCopyInputStream* input, void* data, int size); - // Write a string to the output stream. - void WriteString(ZeroCopyOutputStream* output, const char* str); - // Read a number of bytes equal to the size of the given string and checks - // that it matches the string. - void ReadString(ZeroCopyInputStream* input, const char* str); - // Writes some text to the output stream in a particular order. Returns - // the number of bytes written, incase the caller needs that to set up an - // input stream. - int WriteStuff(ZeroCopyOutputStream* output); - // Reads text from an input stream and expects it to match what - // WriteStuff() writes. - void ReadStuff(ZeroCopyInputStream* input); - - static const int kBlockSizes[]; - static const int kBlockSizeCount; -}; - -const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64}; -const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes); - -bool IoTest::WriteToOutput(ZeroCopyOutputStream* output, - const void* data, int size) { - const uint8* in = reinterpret_cast<const uint8*>(data); - int in_size = size; - - void* out; - int out_size; - - while (true) { - if (!output->Next(&out, &out_size)) { - return false; - } - - if (in_size <= out_size) { - memcpy(out, in, in_size); - output->BackUp(out_size - in_size); - return true; - } - - memcpy(out, in, out_size); - in += out_size; - in_size -= out_size; - } -} - -int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) { - uint8* out = reinterpret_cast<uint8*>(data); - int out_size = size; - - const void* in; - int in_size = 0; - - while (true) { - if (!input->Next(&in, &in_size)) { - return size - out_size; - } - - if (out_size <= in_size) { - memcpy(out, in, out_size); - input->BackUp(in_size - out_size); - return size; // Copied all of it. - } - - memcpy(out, in, in_size); - out += in_size; - out_size -= in_size; - } -} - -void IoTest::WriteString(ZeroCopyOutputStream* output, const char* str) { - EXPECT_TRUE(WriteToOutput(output, str, strlen(str))); -} - -void IoTest::ReadString(ZeroCopyInputStream* input, const char* str) { - int length = strlen(str); - scoped_array<char> buffer(new char[length + 1]); - buffer[length] = '\0'; - EXPECT_EQ(ReadFromInput(input, buffer.get(), length), length); - EXPECT_STREQ(str, buffer.get()); -} - -int IoTest::WriteStuff(ZeroCopyOutputStream* output) { - WriteString(output, "Hello world!\n"); - WriteString(output, "Some te"); - WriteString(output, "xt. Blah blah."); - WriteString(output, "abcdefg"); - WriteString(output, "01234567890123456789"); - WriteString(output, "foobar"); - - EXPECT_EQ(output->ByteCount(), 68); - - int result = output->ByteCount(); - return result; -} - -// Reads text from an input stream and expects it to match what WriteStuff() -// writes. -void IoTest::ReadStuff(ZeroCopyInputStream* input) { - ReadString(input, "Hello world!\n"); - ReadString(input, "Some text. "); - ReadString(input, "Blah "); - ReadString(input, "blah."); - ReadString(input, "abcdefg"); - EXPECT_TRUE(input->Skip(20)); - ReadString(input, "foo"); - ReadString(input, "bar"); - - EXPECT_EQ(input->ByteCount(), 68); - - uint8 byte; - EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); -} - -// =================================================================== - -TEST_F(IoTest, ArrayIo) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - int size; - { - ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - size = WriteStuff(&output); - } - { - ArrayInputStream input(buffer, size, kBlockSizes[j]); - ReadStuff(&input); - } - } - } -} - -// There is no string input, only string output. Also, it doesn't support -// explicit block sizes. So, we'll only run one test and we'll use -// ArrayInput to read back the results. -TEST_F(IoTest, StringIo) { - string str; - { - StringOutputStream output(&str); - WriteStuff(&output); - } - { - ArrayInputStream input(str.data(), str.size()); - ReadStuff(&input); - } -} - - -// To test files, we create a temporary file, write, read, truncate, repeat. -TEST_F(IoTest, FileIo) { - string filename = TestTempDir() + "/zero_copy_stream_test_file"; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - // Make a temporary file. - int file = - open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); - ASSERT_GE(file, 0); - - { - FileOutputStream output(file, kBlockSizes[i]); - WriteStuff(&output); - EXPECT_EQ(0, output.GetErrno()); - } - - // Rewind. - ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); - - { - FileInputStream input(file, kBlockSizes[j]); - ReadStuff(&input); - EXPECT_EQ(0, input.GetErrno()); - } - - close(file); - } - } -} - -// MSVC raises various debugging exceptions if we try to use a file -// descriptor of -1, defeating our tests below. This class will disable -// these debug assertions while in scope. -class MsvcDebugDisabler { - public: -#ifdef _MSC_VER - MsvcDebugDisabler() { - old_handler_ = _set_invalid_parameter_handler(MyHandler); - old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); - } - ~MsvcDebugDisabler() { - old_handler_ = _set_invalid_parameter_handler(old_handler_); - old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_); - } - - static void MyHandler(const wchar_t *expr, - const wchar_t *func, - const wchar_t *file, - unsigned int line, - uintptr_t pReserved) { - // do nothing - } - - _invalid_parameter_handler old_handler_; - int old_mode_; -#else - // Dummy constructor and destructor to ensure that GCC doesn't complain - // that debug_disabler is an unused variable. - MsvcDebugDisabler() {} - ~MsvcDebugDisabler() {} -#endif -}; - -// Test that FileInputStreams report errors correctly. -TEST_F(IoTest, FileReadError) { - MsvcDebugDisabler debug_disabler; - - // -1 = invalid file descriptor. - FileInputStream input(-1); - - const void* buffer; - int size; - EXPECT_FALSE(input.Next(&buffer, &size)); - EXPECT_EQ(EBADF, input.GetErrno()); -} - -// Test that FileOutputStreams report errors correctly. -TEST_F(IoTest, FileWriteError) { - MsvcDebugDisabler debug_disabler; - - // -1 = invalid file descriptor. - FileOutputStream input(-1); - - void* buffer; - int size; - - // The first call to Next() succeeds because it doesn't have anything to - // write yet. - EXPECT_TRUE(input.Next(&buffer, &size)); - - // Second call fails. - EXPECT_FALSE(input.Next(&buffer, &size)); - - EXPECT_EQ(EBADF, input.GetErrno()); -} - -// Pipes are not seekable, so File{Input,Output}Stream ends up doing some -// different things to handle them. We'll test by writing to a pipe and -// reading back from it. -TEST_F(IoTest, PipeIo) { - int files[2]; - - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - // Need to create a new pipe each time because ReadStuff() expects - // to see EOF at the end. - ASSERT_EQ(pipe(files), 0); - - { - FileOutputStream output(files[1], kBlockSizes[i]); - WriteStuff(&output); - EXPECT_EQ(0, output.GetErrno()); - } - close(files[1]); // Send EOF. - - { - FileInputStream input(files[0], kBlockSizes[j]); - ReadStuff(&input); - EXPECT_EQ(0, input.GetErrno()); - } - close(files[0]); - } - } -} - -// Test using C++ iostreams. -TEST_F(IoTest, IostreamIo) { - for (int i = 0; i < kBlockSizeCount; i++) { - for (int j = 0; j < kBlockSizeCount; j++) { - stringstream stream; - - { - OstreamOutputStream output(&stream, kBlockSizes[i]); - WriteStuff(&output); - EXPECT_FALSE(stream.fail()); - } - - { - IstreamInputStream input(&stream, kBlockSizes[j]); - ReadStuff(&input); - EXPECT_TRUE(stream.eof()); - } - } - } -} - -// To test ConcatenatingInputStream, we create several ArrayInputStreams -// covering a buffer and then concatenate them. -TEST_F(IoTest, ConcatenatingInputStream) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - // Fill the buffer. - ArrayOutputStream output(buffer, kBufferSize); - WriteStuff(&output); - - // Now split it up into multiple streams of varying sizes. - ASSERT_EQ(68, output.ByteCount()); // Test depends on this. - ArrayInputStream input1(buffer , 12); - ArrayInputStream input2(buffer + 12, 7); - ArrayInputStream input3(buffer + 19, 6); - ArrayInputStream input4(buffer + 25, 15); - ArrayInputStream input5(buffer + 40, 0); - // Note: We want to make sure we have a stream boundary somewhere between - // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This - // tests that a bug that existed in the original code for Skip() is fixed. - ArrayInputStream input6(buffer + 40, 10); - ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes. - - ZeroCopyInputStream* streams[] = - {&input1, &input2, &input3, &input4, &input5, &input6, &input7}; - - // Create the concatenating stream and read. - ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams)); - ReadStuff(&input); -} - -// To test LimitingInputStream, we write our golden text to a buffer, then -// create an ArrayInputStream that contains the whole buffer (not just the -// bytes written), then use a LimitingInputStream to limit it just to the -// bytes written. -TEST_F(IoTest, LimitingInputStream) { - const int kBufferSize = 256; - uint8 buffer[kBufferSize]; - - // Fill the buffer. - ArrayOutputStream output(buffer, kBufferSize); - WriteStuff(&output); - - // Set up input. - ArrayInputStream array_input(buffer, kBufferSize); - LimitingInputStream input(&array_input, output.ByteCount()); - - ReadStuff(&input); -} - -// Check that a zero-size array doesn't confuse the code. -TEST(ZeroSizeArray, Input) { - ArrayInputStream input(NULL, 0); - const void* data; - int size; - EXPECT_FALSE(input.Next(&data, &size)); -} - -TEST(ZeroSizeArray, Output) { - ArrayOutputStream output(NULL, 0); - void* data; - int size; - EXPECT_FALSE(output.Next(&data, &size)); -} - -} // namespace -} // namespace io -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc deleted file mode 100644 index b9b1ac6c..00000000 --- a/src/google/protobuf/message.cc +++ /dev/null @@ -1,343 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <stack> -#include <google/protobuf/stubs/hash.h> - -#include <google/protobuf/message.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/stubs/map-util.h> - -namespace google { -namespace protobuf { - -using internal::WireFormat; -using internal::ReflectionOps; - -static string InitializationErrorMessage(const char* action, - const Message& message) { - return strings::Substitute( - "Can't $0 message of type \"$1\" because it is missing required " - "fields: $2", - action, message.GetDescriptor()->full_name(), - message.InitializationErrorString()); -} - -Message::~Message() {} - -void Message::MergeFrom(const Message& from) { - const Descriptor* descriptor = GetDescriptor(); - GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) - << ": Tried to merge from a message with a different type. " - "to: " << descriptor->full_name() << ", " - "from:" << from.GetDescriptor()->full_name(); - ReflectionOps::Merge(from, this); -} - -void Message::CopyFrom(const Message& from) { - const Descriptor* descriptor = GetDescriptor(); - GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor) - << ": Tried to copy from a message with a different type." - "to: " << descriptor->full_name() << ", " - "from:" << from.GetDescriptor()->full_name(); - ReflectionOps::Copy(from, this); -} - -void Message::Clear() { - ReflectionOps::Clear(this); -} - -bool Message::IsInitialized() const { - return ReflectionOps::IsInitialized(*this); -} - -void Message::FindInitializationErrors(vector<string>* errors) const { - return ReflectionOps::FindInitializationErrors(*this, "", errors); -} - -string Message::InitializationErrorString() const { - vector<string> errors; - FindInitializationErrors(&errors); - return JoinStrings(errors, ", "); -} - -void Message::CheckInitialized() const { - GOOGLE_CHECK(IsInitialized()) - << "Message of type \"" << GetDescriptor()->full_name() - << "\" is missing required fields: " << InitializationErrorString(); -} - -void Message::DiscardUnknownFields() { - return ReflectionOps::DiscardUnknownFields(this); -} - -bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) { - return WireFormat::ParseAndMergePartial(input, this); -} - -bool Message::MergeFromCodedStream(io::CodedInputStream* input) { - if (!MergePartialFromCodedStream(input)) return false; - if (!IsInitialized()) { - GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this); - return false; - } - return true; -} - -bool Message::ParseFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergeFromCodedStream(input); -} - -bool Message::ParsePartialFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergePartialFromCodedStream(input); -} - -bool Message::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage(); -} - -bool Message::ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream decoder(input); - return ParsePartialFromCodedStream(&decoder) && - decoder.ConsumedEntireMessage(); -} - -bool Message::ParseFromString(const string& data) { - io::ArrayInputStream input(data.data(), data.size()); - return ParseFromZeroCopyStream(&input); -} - -bool Message::ParsePartialFromString(const string& data) { - io::ArrayInputStream input(data.data(), data.size()); - return ParsePartialFromZeroCopyStream(&input); -} - -bool Message::ParseFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParseFromZeroCopyStream(&input); -} - -bool Message::ParsePartialFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParsePartialFromZeroCopyStream(&input); -} - -bool Message::ParseFromFileDescriptor(int file_descriptor) { - io::FileInputStream input(file_descriptor); - return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0; -} - -bool Message::ParsePartialFromFileDescriptor(int file_descriptor) { - io::FileInputStream input(file_descriptor); - return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0; -} - -bool Message::ParseFromIstream(istream* input) { - io::IstreamInputStream zero_copy_input(input); - return ParseFromZeroCopyStream(&zero_copy_input) && input->eof(); -} - -bool Message::ParsePartialFromIstream(istream* input) { - io::IstreamInputStream zero_copy_input(input); - return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof(); -} - - - -bool Message::SerializeWithCachedSizes( - io::CodedOutputStream* output) const { - return WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output); -} - -int Message::ByteSize() const { - int size = WireFormat::ByteSize(*this); - SetCachedSize(size); - return size; -} - -void Message::SetCachedSize(int size) const { - GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name() - << "\" implements neither SetCachedSize() nor ByteSize(). " - "Must implement one or the other."; -} - -bool Message::SerializeToCodedStream(io::CodedOutputStream* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return SerializePartialToCodedStream(output); -} - -bool Message::SerializePartialToCodedStream( - io::CodedOutputStream* output) const { - ByteSize(); // Force size to be cached. - if (!SerializeWithCachedSizes(output)) return false; - return true; -} - -bool Message::SerializeToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializeToCodedStream(&encoder); -} - -bool Message::SerializePartialToZeroCopyStream( - io::ZeroCopyOutputStream* output) const { - io::CodedOutputStream encoder(output); - return SerializePartialToCodedStream(&encoder); -} - -bool Message::AppendToString(string* output) const { - GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this); - return AppendPartialToString(output); -} - -bool Message::AppendPartialToString(string* output) const { - // For efficiency, we'd like to reserve the exact amount of space we need - // in the string. - int total_size = output->size() + ByteSize(); - output->reserve(total_size); - - io::StringOutputStream output_stream(output); - - { - io::CodedOutputStream encoder(&output_stream); - if (!SerializeWithCachedSizes(&encoder)) return false; - } - - GOOGLE_CHECK_EQ(output_stream.ByteCount(), total_size); - return true; -} - -bool Message::SerializeToString(string* output) const { - output->clear(); - return AppendToString(output); -} - -bool Message::SerializePartialToString(string* output) const { - output->clear(); - return AppendPartialToString(output); -} - -bool Message::SerializeToArray(void* data, int size) const { - io::ArrayOutputStream output_stream(data, size); - return SerializeToZeroCopyStream(&output_stream); -} - -bool Message::SerializePartialToArray(void* data, int size) const { - io::ArrayOutputStream output_stream(data, size); - return SerializePartialToZeroCopyStream(&output_stream); -} - -bool Message::SerializeToFileDescriptor(int file_descriptor) const { - io::FileOutputStream output(file_descriptor); - return SerializeToZeroCopyStream(&output); -} - -bool Message::SerializePartialToFileDescriptor(int file_descriptor) const { - io::FileOutputStream output(file_descriptor); - return SerializePartialToZeroCopyStream(&output); -} - -bool Message::SerializeToOstream(ostream* output) const { - io::OstreamOutputStream zero_copy_output(output); - return SerializeToZeroCopyStream(&zero_copy_output); -} - -bool Message::SerializePartialToOstream(ostream* output) const { - io::OstreamOutputStream zero_copy_output(output); - return SerializePartialToZeroCopyStream(&zero_copy_output); -} - - -Reflection::~Reflection() {} - -// =================================================================== -// MessageFactory - -MessageFactory::~MessageFactory() {} - -namespace { - -class GeneratedMessageFactory : public MessageFactory { - public: - GeneratedMessageFactory(); - ~GeneratedMessageFactory(); - - static GeneratedMessageFactory* singleton(); - - void RegisterType(const Descriptor* descriptor, const Message* prototype); - - // implements MessageFactory --------------------------------------- - const Message* GetPrototype(const Descriptor* type); - - private: - hash_map<const Descriptor*, const Message*> type_map_; -}; - -GeneratedMessageFactory::GeneratedMessageFactory() {} -GeneratedMessageFactory::~GeneratedMessageFactory() {} - -GeneratedMessageFactory* GeneratedMessageFactory::singleton() { - // No need for thread-safety here because this will be called at static - // initialization time. (And GCC4 makes this thread-safe anyway.) - static GeneratedMessageFactory singleton; - return &singleton; -} - -void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, - const Message* prototype) { - GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool()) - << "Tried to register a non-generated type with the generated " - "type registry."; - - if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) { - GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name(); - } -} - -const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { - return FindPtrOrNull(type_map_, type); -} - -} // namespace - -MessageFactory* MessageFactory::generated_factory() { - return GeneratedMessageFactory::singleton(); -} - -void MessageFactory::InternalRegisterGeneratedMessage( - const Descriptor* descriptor, const Message* prototype) { - GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype); -} - - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h deleted file mode 100644 index 1a297b12..00000000 --- a/src/google/protobuf/message.h +++ /dev/null @@ -1,687 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains the abstract interface for all protocol messages. -// Although it's possible to implement this interface manually, most users -// will use the protocol compiler to generate implementations. -// -// Example usage: -// -// Say you have a message defined as: -// -// message Foo { -// optional string text = 1; -// repeated int32 numbers = 2; -// } -// -// Then, if you used the protocol compiler to generate a class from the above -// definition, you could use it like so: -// -// string data; // Will store a serialized version of the message. -// -// { -// // Create a message and serialize it. -// Foo foo; -// foo.set_text("Hello World!"); -// foo.add_numbers(1); -// foo.add_numbers(5); -// foo.add_numbers(42); -// -// foo.SerializeToString(&data); -// } -// -// { -// // Parse the serialized message and check that it contains the -// // correct data. -// Foo foo; -// foo.ParseFromString(data); -// -// assert(foo.text() == "Hello World!"); -// assert(foo.numbers_size() == 3); -// assert(foo.numbers(0) == 1); -// assert(foo.numbers(1) == 5); -// assert(foo.numbers(2) == 42); -// } -// -// { -// // Same as the last block, but do it dynamically via the Message -// // reflection interface. -// Message* foo = new Foo; -// Descriptor* descriptor = foo->GetDescriptor(); -// -// // Get the descriptors for the fields we're interested in and verify -// // their types. -// FieldDescriptor* text_field = descriptor->FindFieldByName("text"); -// assert(text_field != NULL); -// assert(text_field->type() == FieldDescriptor::TYPE_STRING); -// assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL); -// FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers"); -// assert(numbers_field != NULL); -// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32); -// assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED); -// -// // Parse the message. -// foo->ParseFromString(data); -// -// // Use the reflection interface to examine the contents. -// Reflection* reflection = foo->GetReflection(); -// assert(reflection->GetString(foo, text_field) == "Hello World!"); -// assert(reflection->CountField(foo, numbers_field) == 3); -// assert(reflection->GetInt32(foo, numbers_field, 0) == 1); -// assert(reflection->GetInt32(foo, numbers_field, 1) == 5); -// assert(reflection->GetInt32(foo, numbers_field, 2) == 42); -// -// delete foo; -// } - -#ifndef GOOGLE_PROTOBUF_MESSAGE_H__ -#define GOOGLE_PROTOBUF_MESSAGE_H__ - -#include <vector> -#include <string> -#include <iosfwd> -#include <google/protobuf/stubs/common.h> - -namespace google { - -namespace protobuf { - -// Defined in this file. -class Message; -class Reflection; - -// Defined in other files. -class Descriptor; // descriptor.h -class FieldDescriptor; // descriptor.h -class EnumValueDescriptor; // descriptor.h -namespace io { - class ZeroCopyInputStream; // zero_copy_stream.h - class ZeroCopyOutputStream; // zero_copy_stream.h - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h -} -class UnknownFieldSet; // unknown_field_set.h - -// Abstract interface for protocol messages. -// -// The methods of this class that are virtual but not pure-virtual have -// default implementations based on reflection. Message classes which are -// optimized for speed will want to override these with faster implementations, -// but classes optimized for code size may be happy with keeping them. See -// the optimize_for option in descriptor.proto. -class LIBPROTOBUF_EXPORT Message { - public: - inline Message() {} - virtual ~Message(); - - // Basic Operations ------------------------------------------------ - - // Construct a new instance of the same type. Ownership is passed to the - // caller. - virtual Message* New() const = 0; - - // Make this message into a copy of the given message. The given message - // must have the same descriptor, but need not necessarily be the same class. - // By default this is just implemented as "Clear(); MergeFrom(from);". - virtual void CopyFrom(const Message& from); - - // Merge the fields from the given message into this message. Singular - // fields will be overwritten, except for embedded messages which will - // be merged. Repeated fields will be concatenated. The given message - // must be of the same type as this message (i.e. the exact same class). - virtual void MergeFrom(const Message& from); - - // Clear all fields of the message and set them to their default values. - // Clear() avoids freeing memory, assuming that any memory allocated - // to hold parts of the message will be needed again to hold the next - // message. If you actually want to free the memory used by a Message, - // you must delete it. - virtual void Clear(); - - // Quickly check if all required fields have values set. - virtual bool IsInitialized() const; - - // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with - // a nice error message. - void CheckInitialized() const; - - // Slowly build a list of all required fields that are not set. - // This is much, much slower than IsInitialized() as it is implemented - // purely via reflection. Generally, you should not call this unless you - // have already determined that an error exists by calling IsInitialized(). - void FindInitializationErrors(vector<string>* errors) const; - - // Like FindInitializationErrors, but joins all the strings, delimited by - // commas, and returns them. - string InitializationErrorString() const; - - // Clears all unknown fields from this message and all embedded messages. - // Normally, if unknown tag numbers are encountered when parsing a message, - // the tag and value are stored in the message's UnknownFieldSet and - // then written back out when the message is serialized. This allows servers - // which simply route messages to other servers to pass through messages - // that have new field definitions which they don't yet know about. However, - // this behavior can have security implications. To avoid it, call this - // method after parsing. - // - // See Reflection::GetUnknownFields() for more on unknown fields. - virtual void DiscardUnknownFields(); - - // Debugging ------------------------------------------------------- - - // Generates a human readable form of this message, useful for debugging - // and other purposes. - string DebugString() const; - // Like DebugString(), but with less whitespace. - string ShortDebugString() const; - // Convenience function useful in GDB. Prints DebugString() to stdout. - void PrintDebugString() const; - - // Parsing --------------------------------------------------------- - // Methods for parsing in protocol buffer format. Most of these are - // just simple wrappers around MergeFromCodedStream(). - - // Fill the message with a protocol buffer parsed from the given input - // stream. Returns false on a read error or if the input is in the - // wrong format. - bool ParseFromCodedStream(io::CodedInputStream* input); - // Like ParseFromCodedStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromCodedStream(io::CodedInputStream* input); - // Read a protocol buffer from the given zero-copy input stream. If - // successful, the entire input will be consumed. - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Like ParseFromZeroCopyStream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); - // Parse a protocol buffer contained in a string. - bool ParseFromString(const string& data); - // Like ParseFromString(), but accepts messages that are missing - // required fields. - bool ParsePartialFromString(const string& data); - // Parse a protocol buffer contained in an array of bytes. - bool ParseFromArray(const void* data, int size); - // Like ParseFromArray(), but accepts messages that are missing - // required fields. - bool ParsePartialFromArray(const void* data, int size); - - // Parse a protocol buffer from a file descriptor. If successful, the entire - // input will be consumed. - bool ParseFromFileDescriptor(int file_descriptor); - // Like ParseFromFileDescriptor(), but accepts messages that are missing - // required fields. - bool ParsePartialFromFileDescriptor(int file_descriptor); - // Parse a protocol buffer from a C++ istream. If successful, the entire - // input will be consumed. - bool ParseFromIstream(istream* input); - // Like ParseFromIstream(), but accepts messages that are missing - // required fields. - bool ParsePartialFromIstream(istream* input); - - - // Reads a protocol buffer from the stream and merges it into this - // Message. Singular fields read from the input overwrite what is - // already in the Message and repeated fields are appended to those - // already present. - // - // It is the responsibility of the caller to call input->LastTagWas() - // (for groups) or input->ConsumedEntireMessage() (for non-groups) after - // this returns to verify that the message's end was delimited correctly. - // - // ParsefromCodedStream() is implemented as Clear() followed by - // MergeFromCodedStream(). - bool MergeFromCodedStream(io::CodedInputStream* input); - - // Like MergeFromCodedStream(), but succeeds even if required fields are - // missing in the input. - // - // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() - // followed by IsInitialized(). - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); - - // Serialization --------------------------------------------------- - // Methods for serializing in protocol buffer format. Most of these - // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). - - // Write a protocol buffer of this message to the given output. Returns - // false on a write error. If the message is missing required fields, - // this may GOOGLE_CHECK-fail. - bool SerializeToCodedStream(io::CodedOutputStream* output) const; - // Like SerializeToCodedStream(), but allows missing required fields. - bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; - // Write the message to the given zero-copy output stream. All required - // fields must be set. - bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Like SerializeToZeroCopyStream(), but allows missing required fields. - bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; - // Serialize the message and store it in the given string. All required - // fields must be set. - bool SerializeToString(string* output) const; - // Like SerializeToString(), but allows missing required fields. - bool SerializePartialToString(string* output) const; - // Serialize the message and store it in the given byte array. All required - // fields must be set. - bool SerializeToArray(void* data, int size) const; - // Like SerializeToArray(), but allows missing required fields. - bool SerializePartialToArray(void* data, int size) const; - - // Serialize the message and write it to the given file descriptor. All - // required fields must be set. - bool SerializeToFileDescriptor(int file_descriptor) const; - // Like SerializeToFileDescriptor(), but allows missing required fields. - bool SerializePartialToFileDescriptor(int file_descriptor) const; - // Serialize the message and write it to the given C++ ostream. All - // required fields must be set. - bool SerializeToOstream(ostream* output) const; - // Like SerializeToOstream(), but allows missing required fields. - bool SerializePartialToOstream(ostream* output) const; - - - // Like SerializeToString(), but appends to the data to the string's existing - // contents. All required fields must be set. - bool AppendToString(string* output) const; - // Like AppendToString(), but allows missing required fields. - bool AppendPartialToString(string* output) const; - - // Computes the serialized size of the message. This recursively calls - // ByteSize() on all embedded messages. If a subclass does not override - // this, it MUST override SetCachedSize(). - virtual int ByteSize() const; - - // Serializes the message without recomputing the size. The message must - // not have changed since the last call to ByteSize(); if it has, the results - // are undefined. - virtual bool SerializeWithCachedSizes(io::CodedOutputStream* output) const; - - // Returns the result of the last call to ByteSize(). An embedded message's - // size is needed both to serialize it (because embedded messages are - // length-delimited) and to compute the outer message's size. Caching - // the size avoids computing it multiple times. - // - // ByteSize() does not automatically use the cached size when available - // because this would require invalidating it every time the message was - // modified, which would be too hard and expensive. (E.g. if a deeply-nested - // sub-message is changed, all of its parents' cached sizes would need to be - // invalidated, which is too much work for an otherwise inlined setter - // method.) - virtual int GetCachedSize() const = 0; - - private: - // This is called only by the default implementation of ByteSize(), to - // update the cached size. If you override ByteSize(), you do not need - // to override this. If you do not override ByteSize(), you MUST override - // this; the default implementation will crash. - // - // The method is private because subclasses should never call it; only - // override it. Yes, C++ lets you do that. Crazy, huh? - virtual void SetCachedSize(int size) const; - - public: - - // Introspection --------------------------------------------------- - - // Typedef for backwards-compatibility. - typedef google::protobuf::Reflection Reflection; - - // Get a Descriptor for this message's type. This describes what - // fields the message contains, the types of those fields, etc. - virtual const Descriptor* GetDescriptor() const = 0; - - // Get the Reflection interface for this Message, which can be used to - // read and modify the fields of the Message dynamically (in other words, - // without knowing the message type at compile time). This object remains - // property of the Message. - virtual const Reflection* GetReflection() const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); -}; - -// This interface contains methods that can be used to dynamically access -// and modify the fields of a protocol message. Their semantics are -// similar to the accessors the protocol compiler generates. -// -// To get the Reflection for a given Message, call Message::GetReflection(). -// -// This interface is separate from Message only for efficiency reasons; -// the vast majority of implementations of Message will share the same -// implementation of Reflection (GeneratedMessageReflection, -// defined in generated_message.h), and all Messages of a particular class -// should share the same Reflection object (though you should not rely on -// the latter fact). -// -// There are several ways that these methods can be used incorrectly. For -// example, any of the following conditions will lead to undefined -// results (probably assertion failures): -// - The FieldDescriptor is not a field of this message type. -// - The method called is not appropriate for the field's type. For -// each field type in FieldDescriptor::TYPE_*, there is only one -// Get*() method, one Set*() method, and one Add*() method that is -// valid for that type. It should be obvious which (except maybe -// for TYPE_BYTES, which are represented using strings in C++). -// - A Get*() or Set*() method for singular fields is called on a repeated -// field. -// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated -// field. -// - The Message object passed to any method is not of the right type for -// this Reflection object (i.e. message.GetReflection() != reflection). -// -// You might wonder why there is not any abstract representation for a field -// of arbitrary type. E.g., why isn't there just a "GetField()" method that -// returns "const Field&", where "Field" is some class with accessors like -// "GetInt32Value()". The problem is that someone would have to deal with -// allocating these Field objects. For generated message classes, having to -// allocate space for an additional object to wrap every field would at least -// double the message's memory footprint, probably worse. Allocating the -// objects on-demand, on the other hand, would be expensive and prone to -// memory leaks. So, instead we ended up with this flat interface. -// -// WARNING: This class is currently in the process of being converted from -// a per-instance object to a per-class object. You'll notice that there -// are two sets of methods below: ones that take a Message pointer or -// reference as a parameter, and ones that don't. The former ones are the -// new interface; the latter ones will go away soon. -// -// TODO(kenton): Create a utility class which callers can use to read and -// write fields from a Reflection without paying attention to the type. -class LIBPROTOBUF_EXPORT Reflection { - public: - // TODO(kenton): Remove parameter. - inline Reflection() {} - virtual ~Reflection(); - - // Get the UnknownFieldSet for the message. This contains fields which - // were seen when the Message was parsed but were not recognized according - // to the Message's definition. - virtual const UnknownFieldSet& GetUnknownFields( - const Message& message) const = 0; - // Get a mutable pointer to the UnknownFieldSet for the message. This - // contains fields which were seen when the Message was parsed but were not - // recognized according to the Message's definition. - virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0; - - // Check if the given non-repeated field is set. - virtual bool HasField(const Message& message, - const FieldDescriptor* field) const = 0; - - // Get the number of elements of a repeated field. - virtual int FieldSize(const Message& message, - const FieldDescriptor* field) const = 0; - - // Clear the value of a field, so that HasField() returns false or - // FieldSize() returns zero. - virtual void ClearField(Message* message, - const FieldDescriptor* field) const = 0; - - // List all fields of the message which are currently set. This includes - // extensions. Singular fields will only be listed if HasField(field) would - // return true and repeated fields will only be listed if FieldSize(field) - // would return non-zero. Fields (both normal fields and extension fields) - // will be listed ordered by field number. - virtual void ListFields(const Message& message, - vector<const FieldDescriptor*>* output) const = 0; - - // Singular field getters ------------------------------------------ - // These get the value of a non-repeated field. They return the default - // value for fields that aren't set. - - virtual int32 GetInt32 (const Message& message, - const FieldDescriptor* field) const = 0; - virtual int64 GetInt64 (const Message& message, - const FieldDescriptor* field) const = 0; - virtual uint32 GetUInt32(const Message& message, - const FieldDescriptor* field) const = 0; - virtual uint64 GetUInt64(const Message& message, - const FieldDescriptor* field) const = 0; - virtual float GetFloat (const Message& message, - const FieldDescriptor* field) const = 0; - virtual double GetDouble(const Message& message, - const FieldDescriptor* field) const = 0; - virtual bool GetBool (const Message& message, - const FieldDescriptor* field) const = 0; - virtual string GetString(const Message& message, - const FieldDescriptor* field) const = 0; - virtual const EnumValueDescriptor* GetEnum( - const Message& message, const FieldDescriptor* field) const = 0; - virtual const Message& GetMessage(const Message& message, - const FieldDescriptor* field) const = 0; - - // Get a string value without copying, if possible. - // - // GetString() necessarily returns a copy of the string. This can be - // inefficient when the string is already stored in a string object in the - // underlying message. GetStringReference() will return a reference to the - // underlying string in this case. Otherwise, it will copy the string into - // *scratch and return that. - // - // Note: It is perfectly reasonable and useful to write code like: - // str = reflection->GetStringReference(field, &str); - // This line would ensure that only one copy of the string is made - // regardless of the field's underlying representation. When initializing - // a newly-constructed string, though, it's just as fast and more readable - // to use code like: - // string str = reflection->GetString(field); - virtual const string& GetStringReference(const Message& message, - const FieldDescriptor* field, - string* scratch) const = 0; - - - // Singular field mutators ----------------------------------------- - // These mutate the value of a non-repeated field. - - virtual void SetInt32 (Message* message, - const FieldDescriptor* field, int32 value) const = 0; - virtual void SetInt64 (Message* message, - const FieldDescriptor* field, int64 value) const = 0; - virtual void SetUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const = 0; - virtual void SetUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const = 0; - virtual void SetFloat (Message* message, - const FieldDescriptor* field, float value) const = 0; - virtual void SetDouble(Message* message, - const FieldDescriptor* field, double value) const = 0; - virtual void SetBool (Message* message, - const FieldDescriptor* field, bool value) const = 0; - virtual void SetString(Message* message, - const FieldDescriptor* field, - const string& value) const = 0; - virtual void SetEnum (Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const = 0; - // Get a mutable pointer to a field with a message type. - virtual Message* MutableMessage(Message* message, - const FieldDescriptor* field) const = 0; - - - // Repeated field getters ------------------------------------------ - // These get the value of one element of a repeated field. - - virtual int32 GetRepeatedInt32 (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual int64 GetRepeatedInt64 (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual uint32 GetRepeatedUInt32(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual uint64 GetRepeatedUInt64(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual float GetRepeatedFloat (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual double GetRepeatedDouble(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual bool GetRepeatedBool (const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual string GetRepeatedString(const Message& message, - const FieldDescriptor* field, - int index) const = 0; - virtual const EnumValueDescriptor* GetRepeatedEnum( - const Message& message, - const FieldDescriptor* field, int index) const = 0; - virtual const Message& GetRepeatedMessage( - const Message& message, - const FieldDescriptor* field, int index) const = 0; - - // See GetStringReference(), above. - virtual const string& GetRepeatedStringReference( - const Message& message, const FieldDescriptor* field, - int index, string* scratch) const = 0; - - - // Repeated field mutators ----------------------------------------- - // These mutate the value of one element of a repeated field. - - virtual void SetRepeatedInt32 (Message* message, - const FieldDescriptor* field, - int index, int32 value) const = 0; - virtual void SetRepeatedInt64 (Message* message, - const FieldDescriptor* field, - int index, int64 value) const = 0; - virtual void SetRepeatedUInt32(Message* message, - const FieldDescriptor* field, - int index, uint32 value) const = 0; - virtual void SetRepeatedUInt64(Message* message, - const FieldDescriptor* field, - int index, uint64 value) const = 0; - virtual void SetRepeatedFloat (Message* message, - const FieldDescriptor* field, - int index, float value) const = 0; - virtual void SetRepeatedDouble(Message* message, - const FieldDescriptor* field, - int index, double value) const = 0; - virtual void SetRepeatedBool (Message* message, - const FieldDescriptor* field, - int index, bool value) const = 0; - virtual void SetRepeatedString(Message* message, - const FieldDescriptor* field, - int index, const string& value) const = 0; - virtual void SetRepeatedEnum(Message* message, - const FieldDescriptor* field, int index, - const EnumValueDescriptor* value) const = 0; - // Get a mutable pointer to an element of a repeated field with a message - // type. - virtual Message* MutableRepeatedMessage( - Message* message, const FieldDescriptor* field, int index) const = 0; - - - // Repeated field adders ------------------------------------------- - // These add an element to a repeated field. - - virtual void AddInt32 (Message* message, - const FieldDescriptor* field, int32 value) const = 0; - virtual void AddInt64 (Message* message, - const FieldDescriptor* field, int64 value) const = 0; - virtual void AddUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const = 0; - virtual void AddUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const = 0; - virtual void AddFloat (Message* message, - const FieldDescriptor* field, float value) const = 0; - virtual void AddDouble(Message* message, - const FieldDescriptor* field, double value) const = 0; - virtual void AddBool (Message* message, - const FieldDescriptor* field, bool value) const = 0; - virtual void AddString(Message* message, - const FieldDescriptor* field, - const string& value) const = 0; - virtual void AddEnum (Message* message, - const FieldDescriptor* field, - const EnumValueDescriptor* value) const = 0; - virtual Message* AddMessage(Message* message, - const FieldDescriptor* field) const = 0; - - - // Extensions ------------------------------------------------------ - - // Try to find an extension of this message type by fully-qualified field - // name. Returns NULL if no extension is known for this name or number. - virtual const FieldDescriptor* FindKnownExtensionByName( - const string& name) const = 0; - - // Try to find an extension of this message type by field number. - // Returns NULL if no extension is known for this name or number. - virtual const FieldDescriptor* FindKnownExtensionByNumber( - int number) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection); -}; - -// Abstract interface for a factory for message objects. -class LIBPROTOBUF_EXPORT MessageFactory { - public: - inline MessageFactory() {} - virtual ~MessageFactory(); - - // Given a Descriptor, gets or constructs the default (prototype) Message - // of that type. You can then call that message's New() method to construct - // a mutable message of that type. - // - // Calling this method twice with the same Descriptor returns the same - // object. The returned object remains property of the factory. Also, any - // objects created by calling the prototype's New() method share some data - // with the prototype, so these must be destoyed before the MessageFactory - // is destroyed. - // - // The given descriptor must outlive the returned message, and hence must - // outlive the MessageFactory. - // - // Some implementations do not support all types. GetPrototype() will - // return NULL if the descriptor passed in is not supported. - // - // This method may or may not be thread-safe depending on the implementation. - // Each implementation should document its own degree thread-safety. - virtual const Message* GetPrototype(const Descriptor* type) = 0; - - // Gets a MessageFactory which supports all generated, compiled-in messages. - // In other words, for any compiled-in type FooMessage, the following is true: - // MessageFactory::generated_factory()->GetPrototype( - // FooMessage::descriptor()) == FooMessage::default_instance() - // This factory supports all types which are found in - // DescriptorPool::generated_pool(). If given a descriptor from any other - // pool, GetPrototype() will return NULL. (You can also check if a - // descriptor is for a generated message by checking if - // descriptor->file()->pool() == DescriptorPool::generated_pool().) - // - // This factory is 100% thread-safe; calling GetPrototype() does not modify - // any shared data. - // - // This factory is a singleton. The caller must not delete the object. - static MessageFactory* generated_factory(); - - // For internal use only: Registers a message type at static initialization - // time, to be placed in generated_factory(). - static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, - const Message* prototype); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_MESSAGE_H__ diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc deleted file mode 100644 index 491d3799..00000000 --- a/src/google/protobuf/message_unittest.cc +++ /dev/null @@ -1,224 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/message.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef _MSC_VER -#include <io.h> -#else -#include <unistd.h> -#endif -#include <sstream> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -TEST(MessageTest, SerializeHelpers) { - // TODO(kenton): Test more helpers? They're all two-liners so it seems - // like a waste of time. - - protobuf_unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - stringstream stream; - - string str1("foo"); - string str2("bar"); - - message.SerializeToString(&str1); - message.AppendToString(&str2); - message.SerializeToOstream(&stream); - - EXPECT_EQ(str1.size() + 3, str2.size()); - EXPECT_EQ("bar", str2.substr(0, 3)); - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(str2.substr(3) == str1); - - // GCC gives some sort of error if we try to just do stream.str() == str1. - string temp = stream.str(); - EXPECT_TRUE(temp == str1); - -} - -TEST(MessageTest, ParseFromFileDescriptor) { - string filename = TestSourceDir() + - "/google/protobuf/testdata/golden_message"; - int file = open(filename.c_str(), O_RDONLY | O_BINARY); - - unittest::TestAllTypes message; - EXPECT_TRUE(message.ParseFromFileDescriptor(file)); - TestUtil::ExpectAllFieldsSet(message); - - EXPECT_GE(close(file), 0); -} - -TEST(MessageTest, ParseHelpers) { - // TODO(kenton): Test more helpers? They're all two-liners so it seems - // like a waste of time. - string data; - - { - // Set up. - protobuf_unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - message.SerializeToString(&data); - } - - { - // Test ParseFromString. - protobuf_unittest::TestAllTypes message; - EXPECT_TRUE(message.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(message); - } - - { - // Test ParseFromIstream. - protobuf_unittest::TestAllTypes message; - stringstream stream(data); - EXPECT_TRUE(message.ParseFromIstream(&stream)); - EXPECT_TRUE(stream.eof()); - TestUtil::ExpectAllFieldsSet(message); - } -} - -TEST(MessageTest, ParseFailsIfNotInitialized) { - unittest::TestRequired message; - vector<string> errors; - - { - ScopedMemoryLog log; - EXPECT_FALSE(message.ParseFromString("")); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" " - "because it is missing required fields: a, b, c", - errors[0]); -} - -TEST(MessageTest, BypassInitializationCheckOnParse) { - unittest::TestRequired message; - io::ArrayInputStream raw_input(NULL, 0); - io::CodedInputStream input(&raw_input); - EXPECT_TRUE(message.MergePartialFromCodedStream(&input)); -} - -TEST(MessageTest, InitializationErrorString) { - unittest::TestRequired message; - EXPECT_EQ("a, b, c", message.InitializationErrorString()); -} - -#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet. - -TEST(MessageTest, SerializeFailsIfNotInitialized) { - unittest::TestRequired message; - string data; - EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)), - "Can't serialize message of type \"protobuf_unittest.TestRequired\" because " - "it is missing required fields: a, b, c"); -} - -TEST(MessageTest, CheckInitialized) { - unittest::TestRequired message; - EXPECT_DEATH(message.CheckInitialized(), - "Message of type \"protobuf_unittest.TestRequired\" is missing required " - "fields: a, b, c"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(MessageTest, BypassInitializationCheckOnSerialize) { - unittest::TestRequired message; - io::ArrayOutputStream raw_output(NULL, 0); - io::CodedOutputStream output(&raw_output); - EXPECT_TRUE(message.SerializePartialToCodedStream(&output)); -} - -TEST(MessageTest, FindInitializationErrors) { - unittest::TestRequired message; - vector<string> errors; - message.FindInitializationErrors(&errors); - ASSERT_EQ(3, errors.size()); - EXPECT_EQ("a", errors[0]); - EXPECT_EQ("b", errors[1]); - EXPECT_EQ("c", errors[2]); -} - -TEST(MessageTest, ParseFailsOnInvalidMessageEnd) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromArray("", 0)); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromArray("\0", 1)); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromArray("\200", 1)); - - // The byte is an endgroup tag, but we aren't parsing a group. - EXPECT_FALSE(message.ParseFromArray("\014", 1)); -} - -TEST(MessageFactoryTest, GeneratedFactoryLookup) { - EXPECT_EQ( - MessageFactory::generated_factory()->GetPrototype( - protobuf_unittest::TestAllTypes::descriptor()), - &protobuf_unittest::TestAllTypes::default_instance()); -} - -TEST(MessageFactoryTest, GeneratedFactoryUnknownType) { - // Construct a new descriptor. - DescriptorPool pool; - FileDescriptorProto file; - file.set_name("foo.proto"); - file.add_message_type()->set_name("Foo"); - const Descriptor* descriptor = pool.BuildFile(file)->message_type(0); - - // Trying to construct it should return NULL. - EXPECT_TRUE( - MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL); -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/package_info.h b/src/google/protobuf/package_info.h deleted file mode 100644 index 0ba6e791..00000000 --- a/src/google/protobuf/package_info.h +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file exists solely to document the google::protobuf namespace. -// It is not compiled into anything, but it may be read by an automated -// documentation generator. - -namespace google { - -// Core components of the Protocol Buffers runtime library. -// -// The files in this package represent the core of the Protocol Buffer -// system. All of them are part of the libprotobuf library. -// -// A note on thread-safety: -// -// Thread-safety in the Protocol Buffer library follows a simple rule: -// unless explicitly noted otherwise, it is always safe to use an object -// from multiple threads simultaneously as long as the object is declared -// const in all threads (or, it is only used in ways that would be allowed -// if it were declared const). However, if an object is accessed in one -// thread in a way that would not be allowed if it were const, then it is -// not safe to access that object in any other thread simultaneously. -// -// Put simply, read-only access to an object can happen in multiple threads -// simultaneously, but write access can only happen in a single thread at -// a time. -// -// The implementation does contain some "const" methods which actually modify -// the object behind the scenes -- e.g., to cache results -- but in these cases -// mutex locking is used to make the access thread-safe. -namespace protobuf {} -} // namespace google diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc deleted file mode 100644 index 9e12658d..00000000 --- a/src/google/protobuf/reflection_ops.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/unknown_field_set.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace internal { - -void ReflectionOps::Copy(const Message& from, Message* to) { - if (&from == to) return; - Clear(to); - Merge(from, to); -} - -void ReflectionOps::Merge(const Message& from, Message* to) { - GOOGLE_CHECK_NE(&from, to); - - const Descriptor* descriptor = from.GetDescriptor(); - GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor) - << "Tried to merge messages of different types."; - - const Reflection* from_reflection = from.GetReflection(); - const Reflection* to_reflection = to->GetReflection(); - - vector<const FieldDescriptor*> fields; - from_reflection->ListFields(from, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - - if (field->is_repeated()) { - int count = from_reflection->FieldSize(from, field); - for (int j = 0; j < count; j++) { - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, METHOD) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - to_reflection->Add##METHOD(to, field, \ - from_reflection->GetRepeated##METHOD(from, field, j)); \ - break; - - HANDLE_TYPE(INT32 , Int32 ); - HANDLE_TYPE(INT64 , Int64 ); - HANDLE_TYPE(UINT32, UInt32); - HANDLE_TYPE(UINT64, UInt64); - HANDLE_TYPE(FLOAT , Float ); - HANDLE_TYPE(DOUBLE, Double); - HANDLE_TYPE(BOOL , Bool ); - HANDLE_TYPE(STRING, String); - HANDLE_TYPE(ENUM , Enum ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->AddMessage(to, field)->MergeFrom( - from_reflection->GetRepeatedMessage(from, field, j)); - break; - } - } - } else { - switch (field->cpp_type()) { -#define HANDLE_TYPE(CPPTYPE, METHOD) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - to_reflection->Set##METHOD(to, field, \ - from_reflection->Get##METHOD(from, field)); \ - break; - - HANDLE_TYPE(INT32 , Int32 ); - HANDLE_TYPE(INT64 , Int64 ); - HANDLE_TYPE(UINT32, UInt32); - HANDLE_TYPE(UINT64, UInt64); - HANDLE_TYPE(FLOAT , Float ); - HANDLE_TYPE(DOUBLE, Double); - HANDLE_TYPE(BOOL , Bool ); - HANDLE_TYPE(STRING, String); - HANDLE_TYPE(ENUM , Enum ); -#undef HANDLE_TYPE - - case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->MutableMessage(to, field)->MergeFrom( - from_reflection->GetMessage(from, field)); - break; - } - } - } - - to_reflection->MutableUnknownFields(to)->MergeFrom( - from_reflection->GetUnknownFields(from)); -} - -void ReflectionOps::Clear(Message* message) { - const Reflection* reflection = message->GetReflection(); - - vector<const FieldDescriptor*> fields; - reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - reflection->ClearField(message, fields[i]); - } - - reflection->MutableUnknownFields(message)->Clear(); -} - -bool ReflectionOps::IsInitialized(const Message& message) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* reflection = message.GetReflection(); - - // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - return false; - } - } - } - - // Check that sub-messages are initialized. - vector<const FieldDescriptor*> fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (field->is_repeated()) { - int size = reflection->FieldSize(message, field); - - for (int i = 0; i < size; i++) { - if (!reflection->GetRepeatedMessage(message, field, i) - .IsInitialized()) { - return false; - } - } - } else { - if (!reflection->GetMessage(message, field).IsInitialized()) { - return false; - } - } - } - } - - return true; -} - -void ReflectionOps::DiscardUnknownFields(Message* message) { - const Reflection* reflection = message->GetReflection(); - - reflection->MutableUnknownFields(message)->Clear(); - - vector<const FieldDescriptor*> fields; - reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (field->is_repeated()) { - int size = reflection->FieldSize(*message, field); - for (int i = 0; i < size; i++) { - reflection->MutableRepeatedMessage(message, field, i) - ->DiscardUnknownFields(); - } - } else { - reflection->MutableMessage(message, field)->DiscardUnknownFields(); - } - } - } -} - -static string SubMessagePrefix(const string& prefix, - const FieldDescriptor* field, - int index) { - string result(prefix); - if (field->is_extension()) { - result.append("("); - result.append(field->full_name()); - result.append(")"); - } else { - result.append(field->name()); - } - if (index != -1) { - result.append("["); - result.append(SimpleItoa(index)); - result.append("]"); - } - result.append("."); - return result; -} - -void ReflectionOps::FindInitializationErrors( - const Message& message, - const string& prefix, - vector<string>* errors) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* reflection = message.GetReflection(); - - // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - errors->push_back(prefix + descriptor->field(i)->name()); - } - } - } - - // Check sub-messages. - vector<const FieldDescriptor*> fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - - if (field->is_repeated()) { - int size = reflection->FieldSize(message, field); - - for (int i = 0; i < size; i++) { - const Message& sub_message = - reflection->GetRepeatedMessage(message, field, i); - FindInitializationErrors(sub_message, - SubMessagePrefix(prefix, field, i), - errors); - } - } else { - const Message& sub_message = reflection->GetMessage(message, field); - FindInitializationErrors(sub_message, - SubMessagePrefix(prefix, field, -1), - errors); - } - } - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h deleted file mode 100644 index b6922a63..00000000 --- a/src/google/protobuf/reflection_ops.h +++ /dev/null @@ -1,66 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ -#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ - -#include <google/protobuf/message.h> - -namespace google { -namespace protobuf { -namespace internal { - -// Basic operations that can be performed using reflection. -// These can be used as a cheap way to implement the corresponding -// methods of the Message interface, though they are likely to be -// slower than implementations tailored for the specific message type. -// -// This class should stay limited to operations needed to implement -// the Message interface. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT ReflectionOps { - public: - static void Copy(const Message& from, Message* to); - static void Merge(const Message& from, Message* to); - static void Clear(Message* message); - static bool IsInitialized(const Message& message); - static void DiscardUnknownFields(Message* message); - - // Finds all unset required fields in the message and adds their full - // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to - // the front of each name. - static void FindInitializationErrors(const Message& message, - const string& prefix, - vector<string>* errors); - - private: - // All methods are static. No need to construct. - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); -}; - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc deleted file mode 100644 index ab587331..00000000 --- a/src/google/protobuf/reflection_ops_unittest.cc +++ /dev/null @@ -1,395 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -TEST(ReflectionOpsTest, SanityCheck) { - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(ReflectionOpsTest, Copy) { - unittest::TestAllTypes message, message2; - - TestUtil::SetAllFields(&message); - - ReflectionOps::Copy(message, &message2); - - TestUtil::ExpectAllFieldsSet(message2); - - // Copying from self should be a no-op. - ReflectionOps::Copy(message2, &message2); - TestUtil::ExpectAllFieldsSet(message2); -} - -TEST(ReflectionOpsTest, CopyExtensions) { - unittest::TestAllExtensions message, message2; - - TestUtil::SetAllExtensions(&message); - - ReflectionOps::Copy(message, &message2); - - TestUtil::ExpectAllExtensionsSet(message2); -} - -TEST(ReflectionOpsTest, Merge) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllTypes message, message2; - - TestUtil::SetAllFields(&message); - - // This field will test merging into an empty spot. - message2.set_optional_int32(message.optional_int32()); - message.clear_optional_int32(); - - // This tests overwriting. - message2.set_optional_string(message.optional_string()); - message.set_optional_string("something else"); - - // This tests concatenating. - message2.add_repeated_int32(message.repeated_int32(1)); - int32 i = message.repeated_int32(0); - message.clear_repeated_int32(); - message.add_repeated_int32(i); - - ReflectionOps::Merge(message2, &message); - - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(ReflectionOpsTest, MergeExtensions) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllExtensions message, message2; - - TestUtil::SetAllExtensions(&message); - - // This field will test merging into an empty spot. - message2.SetExtension(unittest::optional_int32_extension, - message.GetExtension(unittest::optional_int32_extension)); - message.ClearExtension(unittest::optional_int32_extension); - - // This tests overwriting. - message2.SetExtension(unittest::optional_string_extension, - message.GetExtension(unittest::optional_string_extension)); - message.SetExtension(unittest::optional_string_extension, "something else"); - - // This tests concatenating. - message2.AddExtension(unittest::repeated_int32_extension, - message.GetExtension(unittest::repeated_int32_extension, 1)); - int32 i = message.GetExtension(unittest::repeated_int32_extension, 0); - message.ClearExtension(unittest::repeated_int32_extension); - message.AddExtension(unittest::repeated_int32_extension, i); - - ReflectionOps::Merge(message2, &message); - - TestUtil::ExpectAllExtensionsSet(message); -} - -TEST(ReflectionOpsTest, MergeUnknown) { - // Test that the messages' UnknownFieldSets are correctly merged. - unittest::TestEmptyMessage message1, message2; - message1.mutable_unknown_fields()->AddField(1234)->add_varint(1); - message2.mutable_unknown_fields()->AddField(1234)->add_varint(2); - - ReflectionOps::Merge(message2, &message1); - - ASSERT_EQ(1, message1.unknown_fields().field_count()); - const UnknownField& field = message1.unknown_fields().field(0); - ASSERT_EQ(2, field.varint_size()); - EXPECT_EQ(1, field.varint(0)); - EXPECT_EQ(2, field.varint(1)); -} - -#ifdef GTEST_HAS_DEATH_TEST - -TEST(ReflectionOpsTest, MergeFromSelf) { - // Note: Copy is implemented in terms of Merge() so technically the Copy - // test already tested most of this. - - unittest::TestAllTypes message; - - EXPECT_DEATH( - ReflectionOps::Merge(message, &message), - "&from"); -} - -#endif // GTEST_HAS_DEATH_TEST - -TEST(ReflectionOpsTest, Clear) { - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - - ReflectionOps::Clear(&message); - - TestUtil::ExpectClear(message); - - // Check that getting embedded messages returns the objects created during - // SetAllFields() rather than default instances. - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -TEST(ReflectionOpsTest, ClearExtensions) { - unittest::TestAllExtensions message; - - TestUtil::SetAllExtensions(&message); - - ReflectionOps::Clear(&message); - - TestUtil::ExpectExtensionsClear(message); - - // Check that getting embedded messages returns the objects created during - // SetAllExtensions() rather than default instances. - EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(), - &message.GetExtension(unittest::optionalgroup_extension)); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.GetExtension(unittest::optional_nested_message_extension)); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.GetExtension( - unittest::optional_foreign_message_extension)); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.GetExtension(unittest::optional_import_message_extension)); -} - -TEST(ReflectionOpsTest, ClearUnknown) { - // Test that the message's UnknownFieldSet is correctly cleared. - unittest::TestEmptyMessage message; - message.mutable_unknown_fields()->AddField(1234)->add_varint(1); - - ReflectionOps::Clear(&message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, DiscardUnknownFields) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - - // Set some unknown fields in message. - message.mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - message.mutable_optional_nested_message() - ->mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - message.mutable_repeated_nested_message(0) - ->mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - - EXPECT_EQ(1, message.unknown_fields().field_count()); - EXPECT_EQ(1, message.optional_nested_message() - .unknown_fields().field_count()); - EXPECT_EQ(1, message.repeated_nested_message(0) - .unknown_fields().field_count()); - - // Discard them. - ReflectionOps::DiscardUnknownFields(&message); - TestUtil::ExpectAllFieldsSet(message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); - EXPECT_EQ(0, message.optional_nested_message() - .unknown_fields().field_count()); - EXPECT_EQ(0, message.repeated_nested_message(0) - .unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, DiscardUnknownExtensions) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - // Set some unknown fields. - message.mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - message.MutableExtension(unittest::optional_nested_message_extension) - ->mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - message.MutableExtension(unittest::repeated_nested_message_extension, 0) - ->mutable_unknown_fields() - ->AddField(123456) - ->add_varint(654321); - - EXPECT_EQ(1, message.unknown_fields().field_count()); - EXPECT_EQ(1, - message.GetExtension(unittest::optional_nested_message_extension) - .unknown_fields().field_count()); - EXPECT_EQ(1, - message.GetExtension(unittest::repeated_nested_message_extension, 0) - .unknown_fields().field_count()); - - // Discard them. - ReflectionOps::DiscardUnknownFields(&message); - TestUtil::ExpectAllExtensionsSet(message); - - EXPECT_EQ(0, message.unknown_fields().field_count()); - EXPECT_EQ(0, - message.GetExtension(unittest::optional_nested_message_extension) - .unknown_fields().field_count()); - EXPECT_EQ(0, - message.GetExtension(unittest::repeated_nested_message_extension, 0) - .unknown_fields().field_count()); -} - -TEST(ReflectionOpsTest, IsInitialized) { - unittest::TestRequired message; - - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_a(1); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_b(2); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - message.set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -TEST(ReflectionOpsTest, ForeignIsInitialized) { - unittest::TestRequiredForeign message; - - // Starts out initialized because the foreign message is itself an optional - // field. - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Once we create that field, the message is no longer initialized. - message.mutable_optional_message(); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize it. Now we're initialized. - message.mutable_optional_message()->set_a(1); - message.mutable_optional_message()->set_b(2); - message.mutable_optional_message()->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Add a repeated version of the message. No longer initialized. - unittest::TestRequired* sub_message = message.add_repeated_message(); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize that repeated version. - sub_message->set_a(1); - sub_message->set_b(2); - sub_message->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -TEST(ReflectionOpsTest, ExtensionIsInitialized) { - unittest::TestAllExtensions message; - - // Starts out initialized because the foreign message is itself an optional - // field. - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Once we create that field, the message is no longer initialized. - message.MutableExtension(unittest::TestRequired::single); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize it. Now we're initialized. - message.MutableExtension(unittest::TestRequired::single)->set_a(1); - message.MutableExtension(unittest::TestRequired::single)->set_b(2); - message.MutableExtension(unittest::TestRequired::single)->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); - - // Add a repeated version of the message. No longer initialized. - message.AddExtension(unittest::TestRequired::multi); - EXPECT_FALSE(ReflectionOps::IsInitialized(message)); - - // Initialize that repeated version. - message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); - message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); - EXPECT_TRUE(ReflectionOps::IsInitialized(message)); -} - -static string FindInitializationErrors(const Message& message) { - vector<string> errors; - ReflectionOps::FindInitializationErrors(message, "", &errors); - return JoinStrings(errors, ","); -} - -TEST(ReflectionOpsTest, FindInitializationErrors) { - unittest::TestRequired message; - EXPECT_EQ("a,b,c", FindInitializationErrors(message)); -} - -TEST(ReflectionOpsTest, FindForeignInitializationErrors) { - unittest::TestRequiredForeign message; - message.mutable_optional_message(); - message.add_repeated_message(); - message.add_repeated_message(); - EXPECT_EQ("optional_message.a," - "optional_message.b," - "optional_message.c," - "repeated_message[0].a," - "repeated_message[0].b," - "repeated_message[0].c," - "repeated_message[1].a," - "repeated_message[1].b," - "repeated_message[1].c", - FindInitializationErrors(message)); -} - -TEST(ReflectionOpsTest, FindExtensionInitializationErrors) { - unittest::TestAllExtensions message; - message.MutableExtension(unittest::TestRequired::single); - message.AddExtension(unittest::TestRequired::multi); - message.AddExtension(unittest::TestRequired::multi); - EXPECT_EQ("(protobuf_unittest.TestRequired.single).a," - "(protobuf_unittest.TestRequired.single).b," - "(protobuf_unittest.TestRequired.single).c," - "(protobuf_unittest.TestRequired.multi)[0].a," - "(protobuf_unittest.TestRequired.multi)[0].b," - "(protobuf_unittest.TestRequired.multi)[0].c," - "(protobuf_unittest.TestRequired.multi)[1].a," - "(protobuf_unittest.TestRequired.multi)[1].b," - "(protobuf_unittest.TestRequired.multi)[1].c", - FindInitializationErrors(message)); -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc deleted file mode 100644 index 53a3c958..00000000 --- a/src/google/protobuf/repeated_field.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/repeated_field.h> - -namespace google { -namespace protobuf { -namespace internal { - -GenericRepeatedField::~GenericRepeatedField() {} - -} // namespace internal - -template <> -void RepeatedPtrField<string>::Clear() { - for (int i = 0; i < current_size_; i++) { - elements_[i]->clear(); - } - current_size_ = 0; -} - -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h deleted file mode 100644 index 3368e8b7..00000000 --- a/src/google/protobuf/repeated_field.h +++ /dev/null @@ -1,782 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// RepeatedField and RepeatedPtrField are used by generated protocol message -// classes to manipulate repeated fields. These classes are very similar to -// STL's vector, but include a number of optimizations found to be useful -// specifically in the case of Protocol Buffers. RepeatedPtrField is -// particularly different from STL vector as it manages ownership of the -// pointers that it contains. -// -// Typically, clients should not need to access RepeatedField objects directly, -// but should instead use the accessor functions generated automatically by the -// protocol compiler. - -#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__ -#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__ - -#include <string> -#include <iterator> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/message.h> - - -namespace google { -namespace protobuf { - -namespace internal { - -// DO NOT USE GenericRepeatedField; it should be considered a private detail -// of RepeatedField/RepeatedPtrField that may be removed in the future. -// GeneratedMessageReflection needs to manipulate repeated fields in a -// generic way, so we have them implement this interface. This should ONLY -// be used by GeneratedMessageReflection. This would normally be very bad -// design but GeneratedMessageReflection is a big efficiency hack anyway. -// -// TODO(kenton): Implement something like Jeff's ProtoVoidPtrArray change. -// Then, get rid of GenericRepeatedField. -class LIBPROTOBUF_EXPORT GenericRepeatedField { - public: - inline GenericRepeatedField() {} - virtual ~GenericRepeatedField(); - - private: - // We only want GeneratedMessageReflection to see and use these, so we - // make them private. Yes, it is valid C++ for a subclass to implement - // a virtual method which is private in the superclass. Crazy, huh? - friend class GeneratedMessageReflection; - - virtual const void* GenericGet(int index) const = 0; - virtual void* GenericMutable(int index) = 0; - virtual void* GenericAdd() = 0; - virtual void GenericClear() = 0; - virtual int GenericSize() const = 0; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GenericRepeatedField); -}; - -} // namespace internal - -// RepeatedField is used to represent repeated fields of a primitive type (in -// other words, everything except strings and nested Messages). Most users will -// not ever use a RepeatedField directly; they will use the get-by-index, -// set-by-index, and add accessors that are generated for all repeated fields. -template <typename Element> -class RepeatedField : public internal::GenericRepeatedField { - public: - RepeatedField(); - ~RepeatedField(); - - int size() const; - - Element Get(int index) const; - Element* Mutable(int index); - void Set(int index, Element value); - void Add(Element value); - // Remove the last element in the array. - // We don't provide a way to remove any element other than the last - // because it invites inefficient use, such as O(n^2) filtering loops - // that should have been O(n). If you want to remove an element other - // than the last, the best way to do it is to re-arrange the elements - // so that the one you want removed is at the end, then call RemoveLast(). - void RemoveLast(); - void Clear(); - void MergeFrom(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. - void Reserve(int new_size); - - // Gets the underlying array. This pointer is possibly invalidated by - // any add or remove operation. - Element* mutable_data(); - const Element* data() const; - - // Swap entire contents with "other". - void Swap(RepeatedField* other); - - // STL-like iterator support - typedef Element* iterator; - typedef const Element* const_iterator; - - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - - private: // See GenericRepeatedField for why this is private. - // implements GenericRepeatedField --------------------------------- - const void* GenericGet(int index) const; - void* GenericMutable(int index); - void* GenericAdd(); - void GenericClear(); - int GenericSize() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField); - - static const int kInitialSize = 4; - - Element* elements_; - int current_size_; - int total_size_; - - Element initial_space_[kInitialSize]; -}; - -namespace internal { -template <typename It> class RepeatedPtrIterator; -} // namespace internal - -// RepeatedPtrField is like RepeatedField, but used for repeated strings or -// Messages. -template <typename Element> -class RepeatedPtrField : public internal::GenericRepeatedField { - public: - RepeatedPtrField(); - - // This constructor is only defined for RepeatedPtrField<Message>. - // When a RepeatedPtrField is created using this constructor, - // prototype->New() will be called to allocate new elements, rather than - // just using the "new" operator. This is useful for the implementation - // of DynamicMessage, but is not used by normal generated messages. - explicit RepeatedPtrField(const Message* prototype); - - ~RepeatedPtrField(); - - // Returns the prototype if one was passed to the constructor. - const Message* prototype() const; - - int size() const; - - const Element& Get(int index) const; - Element* Mutable(int index); - Element* Add(); - void RemoveLast(); // Remove the last element in the array. - void Clear(); - void MergeFrom(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 - // array is grown, it will always be at least doubled in size. - void Reserve(int new_size); - - // Gets the underlying array. This pointer is possibly invalidated by - // any add or remove operation. - Element** mutable_data(); - const Element* const* data() const; - - // Swap entire contents with "other". - void Swap(RepeatedPtrField* other); - - // STL-like iterator support - typedef internal::RepeatedPtrIterator<Element**> iterator; - typedef internal::RepeatedPtrIterator<const Element* const*> const_iterator; - - iterator begin(); - const_iterator begin() const; - iterator end(); - const_iterator end() const; - - // Advanced memory management -------------------------------------- - // When hardcore memory management becomes necessary -- as it often - // does here at Google -- the following methods may be useful. - - // Add an already-allocated object, passing ownership to the - // RepeatedPtrField. - void AddAllocated(Element* value); - // Remove the last element and return it, passing ownership to the - // caller. - // Requires: size() > 0 - Element* ReleaseLast(); - - // When elements are removed by calls to RemoveLast() or Clear(), they - // are not actually freed. Instead, they are cleared and kept so that - // they can be reused later. This can save lots of CPU time when - // repeatedly reusing a protocol message for similar purposes. - // - // Really, extremely hardcore programs may actually want to manipulate - // these objects to better-optimize memory management. These methods - // allow that. - - // Get the number of cleared objects that are currently being kept - // around for reuse. - int ClearedCount(); - // Add an element to the pool of cleared objects, passing ownership to - // the RepeatedPtrField. The element must be cleared prior to calling - // this method. - void AddCleared(Element* value); - // Remove a single element from the cleared pool and return it, passing - // ownership to the caller. The element is guaranteed to be cleared. - // Requires: ClearedCount() > 0 - Element* ReleaseCleared(); - - private: // See GenericRepeatedField for why this is private. - // implements GenericRepeatedField --------------------------------- - const void* GenericGet(int index) const; - void* GenericMutable(int index); - void* GenericAdd(); - void GenericClear(); - int GenericSize() const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); - - static const int kInitialSize = 4; - - // prototype_ is used for RepeatedPtrField<Message> only (see constructor). - const Message* prototype_; - - Element** elements_; - int current_size_; - int allocated_size_; - int total_size_; - - Element* initial_space_[kInitialSize]; - - Element* NewElement(); -}; - -// implementation ==================================================== - -template <typename Element> -inline RepeatedField<Element>::RepeatedField() - : elements_(initial_space_), - current_size_(0), - total_size_(kInitialSize) { -} - -template <typename Element> -RepeatedField<Element>::~RepeatedField() { - if (elements_ != initial_space_) { - delete [] elements_; - } -} - -template <typename Element> -inline int RepeatedField<Element>::size() const { - return current_size_; -} - - -template <typename Element> -inline Element RepeatedField<Element>::Get(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return elements_[index]; -} - -template <typename Element> -inline Element* RepeatedField<Element>::Mutable(int index) { - GOOGLE_DCHECK_LT(index, size()); - return elements_ + index; -} - -template <typename Element> -inline void RepeatedField<Element>::Set(int index, Element value) { - GOOGLE_DCHECK_LT(index, size()); - elements_[index] = value; -} - -template <typename Element> -inline void RepeatedField<Element>::Add(Element value) { - if (current_size_ == total_size_) Reserve(total_size_ + 1); - elements_[current_size_++] = value; -} - -template <typename Element> -inline void RepeatedField<Element>::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - --current_size_; -} - -template <typename Element> -inline void RepeatedField<Element>::Clear() { - current_size_ = 0; -} - -template <typename Element> -void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { - Reserve(current_size_ + other.current_size_); - memcpy(elements_ + current_size_, other.elements_, - sizeof(Element) * other.current_size_); - current_size_ += other.current_size_; -} - -template <typename Element> -inline Element* RepeatedField<Element>::mutable_data() { - return elements_; -} - -template <typename Element> -inline const Element* RepeatedField<Element>::data() const { - return elements_; -} - - -template <typename Element> -void RepeatedField<Element>::Swap(RepeatedField* other) { - Element* swap_elements = elements_; - int swap_current_size = current_size_; - int swap_total_size = total_size_; - // We may not be using initial_space_ but it's not worth checking. Just - // copy it anyway. - Element swap_initial_space[kInitialSize]; - memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); - - elements_ = other->elements_; - current_size_ = other->current_size_; - total_size_ = other->total_size_; - memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); - - other->elements_ = swap_elements; - other->current_size_ = swap_current_size; - other->total_size_ = swap_total_size; - memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); - - if (elements_ == other->initial_space_) { - elements_ = initial_space_; - } - if (other->elements_ == initial_space_) { - other->elements_ = other->initial_space_; - } -} - -template <typename Element> -inline typename RepeatedField<Element>::iterator -RepeatedField<Element>::begin() { - return elements_; -} -template <typename Element> -inline typename RepeatedField<Element>::const_iterator -RepeatedField<Element>::begin() const { - return elements_; -} -template <typename Element> -inline typename RepeatedField<Element>::iterator -RepeatedField<Element>::end() { - return elements_ + current_size_; -} -template <typename Element> -inline typename RepeatedField<Element>::const_iterator -RepeatedField<Element>::end() const { - return elements_ + current_size_; -} - - -template <typename Element> -const void* RepeatedField<Element>::GenericGet(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return elements_ + index; -} - -template <typename Element> -void* RepeatedField<Element>::GenericMutable(int index) { - return Mutable(index); -} - -template <typename Element> -void* RepeatedField<Element>::GenericAdd() { - Add(Element()); - return Mutable(current_size_ - 1); -} - -template <typename Element> -void RepeatedField<Element>::GenericClear() { - Clear(); -} - -template <typename Element> -int RepeatedField<Element>::GenericSize() const { - return size(); -} - -template <typename Element> -inline void RepeatedField<Element>::Reserve(int new_size) { - if (total_size_ >= new_size) return; - - Element* old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new Element[total_size_]; - memcpy(elements_, old_elements, current_size_ * sizeof(elements_[0])); - if (old_elements != initial_space_) { - delete [] old_elements; - } -} - -// ------------------------------------------------------------------- - -template <typename Element> -inline RepeatedPtrField<Element>::RepeatedPtrField() - : prototype_(NULL), - elements_(initial_space_), - current_size_(0), - allocated_size_(0), - total_size_(kInitialSize) { -} - -template <> -inline RepeatedPtrField<Message>::RepeatedPtrField(const Message* prototype) - : prototype_(prototype), - elements_(initial_space_), - current_size_(0), - allocated_size_(0), - total_size_(kInitialSize) { -} - -template <typename Element> -RepeatedPtrField<Element>::~RepeatedPtrField() { - for (int i = 0; i < allocated_size_; i++) { - delete elements_[i]; - } - if (elements_ != initial_space_) { - delete [] elements_; - } -} - -template <> -inline const Message* RepeatedPtrField<Message>::prototype() const { - return prototype_; -} - - -template <typename Element> -inline int RepeatedPtrField<Element>::size() const { - return current_size_; -} - - -template <typename Element> -inline const Element& RepeatedPtrField<Element>::Get(int index) const { - GOOGLE_DCHECK_LT(index, size()); - return *elements_[index]; -} - -template <typename Element> -inline Element* RepeatedPtrField<Element>::Mutable(int index) { - GOOGLE_DCHECK_LT(index, size()); - return elements_[index]; -} - -template <typename Element> -inline Element* RepeatedPtrField<Element>::Add() { - if (current_size_ < allocated_size_) return elements_[current_size_++]; - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - ++allocated_size_; - return elements_[current_size_++] = NewElement(); -} - -template <typename Element> -inline void RepeatedPtrField<Element>::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - elements_[--current_size_]->Clear(); -} - -template <> -inline void RepeatedPtrField<string>::RemoveLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - elements_[--current_size_]->clear(); -} - -template <typename Element> -void RepeatedPtrField<Element>::Clear() { - for (int i = 0; i < current_size_; i++) { - elements_[i]->Clear(); - } - current_size_ = 0; -} - -// Specialization defined in repeated_field.cc. -template <> -void LIBPROTOBUF_EXPORT RepeatedPtrField<string>::Clear(); - -template <typename Element> -void RepeatedPtrField<Element>::MergeFrom(const RepeatedPtrField& other) { - Reserve(current_size_ + other.current_size_); - for (int i = 0; i < other.current_size_; i++) { - Add()->MergeFrom(other.Get(i)); - } -} - -template <> -inline void RepeatedPtrField<string>::MergeFrom(const RepeatedPtrField& other) { - Reserve(current_size_ + other.current_size_); - for (int i = 0; i < other.current_size_; i++) { - Add()->assign(other.Get(i)); - } -} - - -template <typename Element> -inline Element** RepeatedPtrField<Element>::mutable_data() { - return elements_; -} - -template <typename Element> -inline const Element* const* RepeatedPtrField<Element>::data() const { - return elements_; -} - - -template <typename Element> -void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) { - Element** swap_elements = elements_; - int swap_current_size = current_size_; - int swap_allocated_size = allocated_size_; - int swap_total_size = total_size_; - // We may not be using initial_space_ but it's not worth checking. Just - // copy it anyway. - Element* swap_initial_space[kInitialSize]; - memcpy(swap_initial_space, initial_space_, sizeof(initial_space_)); - - elements_ = other->elements_; - current_size_ = other->current_size_; - allocated_size_ = other->allocated_size_; - total_size_ = other->total_size_; - memcpy(initial_space_, other->initial_space_, sizeof(initial_space_)); - - other->elements_ = swap_elements; - other->current_size_ = swap_current_size; - other->allocated_size_ = swap_allocated_size; - other->total_size_ = swap_total_size; - memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space)); - - if (elements_ == other->initial_space_) { - elements_ = initial_space_; - } - if (other->elements_ == initial_space_) { - other->elements_ = other->initial_space_; - } -} - - -template <typename Element> -inline void RepeatedPtrField<Element>::AddAllocated(Element* value) { - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - // We don't care about the order of cleared elements, so if there's one - // in the way, just move it to the back of the array. - if (current_size_ < allocated_size_) { - elements_[allocated_size_] = elements_[current_size_]; - } - ++allocated_size_; - elements_[current_size_++] = value; -} - -template <typename Element> -inline Element* RepeatedPtrField<Element>::ReleaseLast() { - GOOGLE_DCHECK_GT(current_size_, 0); - Element* result = elements_[--current_size_]; - --allocated_size_; - if (current_size_ < allocated_size_) { - // There are cleared elements on the end; replace the removed element - // with the last allocated element. - elements_[current_size_] = elements_[allocated_size_]; - } - return result; -} - - -template <typename Element> -inline int RepeatedPtrField<Element>::ClearedCount() { - return allocated_size_ - current_size_; -} - -template <typename Element> -inline void RepeatedPtrField<Element>::AddCleared(Element* value) { - if (allocated_size_ == total_size_) Reserve(total_size_ + 1); - elements_[allocated_size_++] = value; -} - -template <typename Element> -inline Element* RepeatedPtrField<Element>::ReleaseCleared() { - GOOGLE_DCHECK_GT(allocated_size_, current_size_); - return elements_[--allocated_size_]; -} - - -template <typename Element> -const void* RepeatedPtrField<Element>::GenericGet(int index) const { - return &Get(index); -} - -template <typename Element> -void* RepeatedPtrField<Element>::GenericMutable(int index) { - return Mutable(index); -} - -template <typename Element> -void* RepeatedPtrField<Element>::GenericAdd() { - return Add(); -} - -template <typename Element> -void RepeatedPtrField<Element>::GenericClear() { - Clear(); -} - -template <typename Element> -int RepeatedPtrField<Element>::GenericSize() const { - return size(); -} - - -template <typename Element> -inline void RepeatedPtrField<Element>::Reserve(int new_size) { - if (total_size_ >= new_size) return; - - Element** old_elements = elements_; - total_size_ = max(total_size_ * 2, new_size); - elements_ = new Element*[total_size_]; - memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0])); - if (old_elements != initial_space_) { - delete [] old_elements; - } -} - -template <typename Element> -inline Element* RepeatedPtrField<Element>::NewElement() { - return new Element; -} - -// RepeatedPtrField<Message> is alowed but requires a prototype since Message -// is abstract. -template <> -inline Message* RepeatedPtrField<Message>::NewElement() { - return prototype_->New(); -} - -// ------------------------------------------------------------------- - -namespace internal { - -// STL-like iterator implementation for RepeatedPtrField. You should not -// refer to this class directly; use RepeatedPtrField<T>::iterator instead. -// -// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T**>, is -// very similar to iterator_ptr<> in util/gtl/iterator_adaptors-inl.h, -// but adds random-access operators and is slightly more specialized -// for using T** as its base type. I didn't re-use the other class to -// avoid an extra dependency. -// -// This code stolen from net/proto/proto-array-internal.h by Jeffrey Yasskin -// (jyasskin@google.com). -template<typename It> -class RepeatedPtrIterator - : public std::iterator< - std::random_access_iterator_tag, - typename internal::remove_pointer< - typename internal::remove_pointer<It>::type>::type> { - public: - typedef RepeatedPtrIterator<It> iterator; - typedef typename iterator::reference reference; - typedef typename iterator::pointer pointer; - typedef typename iterator::difference_type difference_type; - - RepeatedPtrIterator() : it_(NULL) {} - explicit RepeatedPtrIterator(const It& it) : it_(it) {} - - // Allow "upcasting" from RepeatedPtrIterator<T**> to - // RepeatedPtrIterator<const T*const*>. - template<typename OtherIt> - RepeatedPtrIterator(const RepeatedPtrIterator<OtherIt>& other) - : it_(other.base()) {} - - // Provide access to the wrapped iterator. - const It& base() const { return it_; } - - // dereferenceable - reference operator*() const { return **it_; } - pointer operator->() const { return &(operator*()); } - - // {inc,dec}rementable - iterator& operator++() { ++it_; return *this; } - iterator operator++(int) { return iterator(it_++); } - iterator& operator--() { --it_; return *this; } - iterator operator--(int) { return iterator(it_--); } - - // equality_comparable - bool operator==(const iterator& x) const { return it_ == x.it_; } - bool operator!=(const iterator& x) const { return it_ != x.it_; } - - // less_than_comparable - bool operator<(const iterator& x) const { return it_ < x.it_; } - bool operator<=(const iterator& x) const { return it_ <= x.it_; } - bool operator>(const iterator& x) const { return it_ > x.it_; } - bool operator>=(const iterator& x) const { return it_ >= x.it_; } - - // addable, subtractable - iterator& operator+=(difference_type d) { - it_ += d; - return *this; - } - friend iterator operator+(iterator it, difference_type d) { - it += d; - return it; - } - friend iterator operator+(difference_type d, iterator it) { - it += d; - return it; - } - iterator& operator-=(difference_type d) { - it_ -= d; - return *this; - } - friend iterator operator-(iterator it, difference_type d) { - it -= d; - return it; - } - - // indexable - reference operator[](difference_type d) const { return *(*this + d); } - - // random access iterator - difference_type operator-(const iterator& x) const { return it_ - x.it_; } - - private: - // The internal iterator. - It it_; -}; - -} // namespace internal - -template <typename Element> -inline typename RepeatedPtrField<Element>::iterator -RepeatedPtrField<Element>::begin() { - return iterator(elements_); -} -template <typename Element> -inline typename RepeatedPtrField<Element>::const_iterator -RepeatedPtrField<Element>::begin() const { - return iterator(elements_); -} -template <typename Element> -inline typename RepeatedPtrField<Element>::iterator -RepeatedPtrField<Element>::end() { - return iterator(elements_ + current_size_); -} -template <typename Element> -inline typename RepeatedPtrField<Element>::const_iterator -RepeatedPtrField<Element>::end() const { - return iterator(elements_ + current_size_); -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__ diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc deleted file mode 100644 index eb9b096f..00000000 --- a/src/google/protobuf/repeated_field_unittest.cc +++ /dev/null @@ -1,603 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// TODO(kenton): Improve this unittest to bring it up to the standards of -// other proto2 unittests. - -#include <algorithm> - -#include <google/protobuf/repeated_field.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -// Test operations on a RepeatedField which is small enough that it does -// not allocate a separate array for storage. -TEST(RepeatedField, Small) { - RepeatedField<int> field; - - EXPECT_EQ(field.size(), 0); - - field.Add(5); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Add(42); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 42); - - field.Set(1, 23); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), 5); - EXPECT_EQ(field.Get(1), 23); - - field.RemoveLast(); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), 5); - - field.Clear(); - - EXPECT_EQ(field.size(), 0); -} - -// Test operations on a RepeatedField which is large enough to allocate a -// separate array. -TEST(RepeatedField, Large) { - RepeatedField<int> field; - - for (int i = 0; i < 16; i++) { - field.Add(i * i); - } - - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i), i * i); - } -} - -// Test swapping between various types of RepeatedFields. -TEST(RepeatedField, SwapSmallSmall) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - field1.Add(5); - field1.Add(42); - - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 0); - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); -} - -TEST(RepeatedField, SwapLargeSmall) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - for (int i = 0; i < 16; i++) { - field1.Add(i * i); - } - field2.Add(5); - field2.Add(42); - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), 5); - EXPECT_EQ(field1.Get(1), 42); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i), i * i); - } -} - -TEST(RepeatedField, SwapLargeLarge) { - RepeatedField<int> field1; - RepeatedField<int> field2; - - field1.Add(5); - field1.Add(42); - for (int i = 0; i < 16; i++) { - field1.Add(i); - field2.Add(i * i); - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i), i * i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), 5); - EXPECT_EQ(field2.Get(1), 42); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i), i - 2); - } -} - -// Determines how much space was reserved by the given field by adding elements -// to it until it re-allocates its space. -static int ReservedSpace(RepeatedField<int>* field) { - const int* ptr = field->data(); - do { - field->Add(0); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedField, ReserveMoreThanDouble) { - // Reserve more than double the previous space in the field and expect the - // field to reserve exactly the amount specified. - RepeatedField<int> field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanDouble) { - // Reserve less than double the previous space in the field and expect the - // field to grow by double instead. - RepeatedField<int> field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedField, ReserveLessThanExisting) { - // Reserve less than the previous space in the field and expect the - // field to not re-allocate at all. - RepeatedField<int> field; - field.Reserve(20); - const int* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedField, MergeFrom) { - RepeatedField<int> source, destination; - - source.Add(4); - source.Add(5); - - destination.Add(1); - destination.Add(2); - destination.Add(3); - - destination.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - - EXPECT_EQ(1, destination.Get(0)); - EXPECT_EQ(2, destination.Get(1)); - EXPECT_EQ(3, destination.Get(2)); - EXPECT_EQ(4, destination.Get(3)); - EXPECT_EQ(5, destination.Get(4)); -} - -TEST(RepeatedField, MutableDataIsMutable) { - RepeatedField<int> field; - field.Add(1); - EXPECT_EQ(1, field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - *field.mutable_data() = 2; - EXPECT_EQ(2, field.Get(0)); -} - -// =================================================================== -// RepeatedPtrField tests. These pretty much just mirror the RepeatedField -// tests above. - -TEST(RepeatedPtrField, Small) { - RepeatedPtrField<string> field; - - EXPECT_EQ(field.size(), 0); - - field.Add()->assign("foo"); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Add()->assign("bar"); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "bar"); - - field.Mutable(1)->assign("baz"); - - EXPECT_EQ(field.size(), 2); - EXPECT_EQ(field.Get(0), "foo"); - EXPECT_EQ(field.Get(1), "baz"); - - field.RemoveLast(); - - EXPECT_EQ(field.size(), 1); - EXPECT_EQ(field.Get(0), "foo"); - - field.Clear(); - - EXPECT_EQ(field.size(), 0); -} - -TEST(RepeatedPtrField, Large) { - RepeatedPtrField<string> field; - - for (int i = 0; i < 16; i++) { - *field.Add() += 'a' + i; - } - - EXPECT_EQ(field.size(), 16); - - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field.Get(i).size(), 1); - EXPECT_EQ(field.Get(i)[0], 'a' + i); - } -} - -TEST(RepeatedPtrField, SwapSmallSmall) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 0); - EXPECT_EQ(field2.size(), 2); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); -} - -TEST(RepeatedPtrField, SwapLargeSmall) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - field2.Add()->assign("foo"); - field2.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'a' + i; - } - field1.Swap(&field2); - - EXPECT_EQ(field1.size(), 2); - EXPECT_EQ(field1.Get(0), "foo"); - EXPECT_EQ(field1.Get(1), "bar"); - EXPECT_EQ(field2.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'a' + i); - } -} - -TEST(RepeatedPtrField, SwapLargeLarge) { - RepeatedPtrField<string> field1; - RepeatedPtrField<string> field2; - - field1.Add()->assign("foo"); - field1.Add()->assign("bar"); - for (int i = 0; i < 16; i++) { - *field1.Add() += 'A' + i; - *field2.Add() += 'a' + i; - } - field2.Swap(&field1); - - EXPECT_EQ(field1.size(), 16); - for (int i = 0; i < 16; i++) { - EXPECT_EQ(field1.Get(i).size(), 1); - EXPECT_EQ(field1.Get(i)[0], 'a' + i); - } - EXPECT_EQ(field2.size(), 18); - EXPECT_EQ(field2.Get(0), "foo"); - EXPECT_EQ(field2.Get(1), "bar"); - for (int i = 2; i < 18; i++) { - EXPECT_EQ(field2.Get(i).size(), 1); - EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2); - } -} - -static int ReservedSpace(RepeatedPtrField<string>* field) { - const string* const* ptr = field->data(); - do { - field->Add(); - } while (field->data() == ptr); - - return field->size() - 1; -} - -TEST(RepeatedPtrField, ReserveMoreThanDouble) { - RepeatedPtrField<string> field; - field.Reserve(20); - - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanDouble) { - RepeatedPtrField<string> field; - field.Reserve(20); - field.Reserve(30); - - EXPECT_EQ(40, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveLessThanExisting) { - RepeatedPtrField<string> field; - field.Reserve(20); - const string* const* previous_ptr = field.data(); - field.Reserve(10); - - EXPECT_EQ(previous_ptr, field.data()); - EXPECT_EQ(20, ReservedSpace(&field)); -} - -TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) { - // Check that a bug is fixed: An earlier implementation of Reserve() - // failed to copy pointers to allocated-but-cleared objects, possibly - // leading to segfaults. - RepeatedPtrField<string> field; - string* first = field.Add(); - field.RemoveLast(); - - field.Reserve(20); - EXPECT_EQ(first, field.Add()); -} - -// Clearing elements is tricky with RepeatedPtrFields since the memory for -// the elements is retained and reused. -TEST(RepeatedPtrField, ClearedElements) { - RepeatedPtrField<string> field; - - string* original = field.Add(); - *original = "foo"; - - EXPECT_EQ(field.ClearedCount(), 0); - - field.RemoveLast(); - EXPECT_TRUE(original->empty()); - EXPECT_EQ(field.ClearedCount(), 1); - - EXPECT_EQ(field.Add(), original); // Should return same string for reuse. - - EXPECT_EQ(field.ReleaseLast(), original); // We take ownership. - EXPECT_EQ(field.ClearedCount(), 0); - - EXPECT_NE(field.Add(), original); // Should NOT return the same string. - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddAllocated(original); // Give ownership back. - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_EQ(field.Mutable(1), original); - - field.Clear(); - EXPECT_EQ(field.ClearedCount(), 2); - EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddCleared(original); // Give ownership back, but as a cleared object. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_EQ(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); -} - -TEST(RepeatedPtrField, MergeFrom) { - 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.MergeFrom(source); - - ASSERT_EQ(5, destination.size()); - - EXPECT_EQ("1", destination.Get(0)); - EXPECT_EQ("2", destination.Get(1)); - EXPECT_EQ("3", destination.Get(2)); - EXPECT_EQ("4", destination.Get(3)); - EXPECT_EQ("5", destination.Get(4)); -} - -TEST(RepeatedPtrField, MutableDataIsMutable) { - RepeatedPtrField<string> field; - *field.Add() = "1"; - EXPECT_EQ("1", field.Get(0)); - // The fact that this line compiles would be enough, but we'll check the - // value anyway. - string** data = field.mutable_data(); - **data = "2"; - EXPECT_EQ("2", field.Get(0)); -} - -// =================================================================== - -// Iterator tests stolen from net/proto/proto-array_unittest. -class RepeatedFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - for (int i = 0; i < 3; ++i) { - proto_array_.Add(i); - } - } - - RepeatedField<int> proto_array_; -}; - -TEST_F(RepeatedFieldIteratorTest, Convertible) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - RepeatedField<int>::const_iterator c_iter = iter; - EXPECT_EQ(0, *c_iter); -} - -TEST_F(RepeatedFieldIteratorTest, MutableIteration) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, ConstIteration) { - const RepeatedField<int>& const_proto_array = proto_array_; - RepeatedField<int>::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ(0, *iter); - ++iter; - EXPECT_EQ(1, *iter++); - EXPECT_EQ(2, *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ(2, *(proto_array_.end() - 1)); -} - -TEST_F(RepeatedFieldIteratorTest, Mutation) { - RepeatedField<int>::iterator iter = proto_array_.begin(); - *iter = 7; - EXPECT_EQ(7, proto_array_.Get(0)); -} - -// ------------------------------------------------------------------- - -class RepeatedPtrFieldIteratorTest : public testing::Test { - protected: - virtual void SetUp() { - proto_array_.Add()->assign("foo"); - proto_array_.Add()->assign("bar"); - proto_array_.Add()->assign("baz"); - } - - RepeatedPtrField<string> proto_array_; -}; - -TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::const_iterator c_iter = iter; -} - -TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(proto_array_.end() == iter); - EXPECT_EQ("baz", *(--proto_array_.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) { - const RepeatedPtrField<string>& const_proto_array = proto_array_; - RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin(); - EXPECT_EQ("foo", *iter); - ++iter; - EXPECT_EQ("bar", *(iter++)); - EXPECT_EQ("baz", *iter); - ++iter; - EXPECT_TRUE(const_proto_array.end() == iter); - EXPECT_EQ("baz", *(--const_proto_array.end())); -} - -TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::iterator iter2 = iter; - ++iter2; - ++iter2; - EXPECT_TRUE(iter + 2 == iter2); - EXPECT_TRUE(iter == iter2 - 2); - EXPECT_EQ("baz", iter[2]); - EXPECT_EQ("baz", *(iter + 2)); - EXPECT_EQ(3, proto_array_.end() - proto_array_.begin()); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Comparable) { - RepeatedPtrField<string>::const_iterator iter = proto_array_.begin(); - RepeatedPtrField<string>::const_iterator iter2 = iter + 1; - EXPECT_TRUE(iter == iter); - EXPECT_TRUE(iter != iter2); - EXPECT_TRUE(iter < iter2); - EXPECT_TRUE(iter <= iter2); - EXPECT_TRUE(iter <= iter); - EXPECT_TRUE(iter2 > iter); - EXPECT_TRUE(iter2 >= iter); - EXPECT_TRUE(iter >= iter); -} - -// Uninitialized iterator does not point to any of the RepeatedPtrField. -// Dereferencing an uninitialized iterator crashes the process. -TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) { - RepeatedPtrField<string>::iterator iter; - EXPECT_TRUE(iter != proto_array_.begin()); - EXPECT_TRUE(iter != proto_array_.begin() + 1); - EXPECT_TRUE(iter != proto_array_.begin() + 2); - EXPECT_TRUE(iter != proto_array_.begin() + 3); - EXPECT_TRUE(iter != proto_array_.end()); -#ifdef GTEST_HAS_DEATH_TEST - ASSERT_DEATH(GOOGLE_LOG(INFO) << *iter, ""); -#endif -} - -TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) { - proto_array_.Clear(); - proto_array_.Add()->assign("a"); - proto_array_.Add()->assign("c"); - proto_array_.Add()->assign("d"); - proto_array_.Add()->assign("n"); - proto_array_.Add()->assign("p"); - proto_array_.Add()->assign("x"); - proto_array_.Add()->assign("y"); - - string v = "f"; - RepeatedPtrField<string>::const_iterator it = - lower_bound(proto_array_.begin(), proto_array_.end(), v); - EXPECT_EQ(*it, "n"); - EXPECT_TRUE(it == proto_array_.begin() + 3); -} - -TEST_F(RepeatedPtrFieldIteratorTest, Mutation) { - RepeatedPtrField<string>::iterator iter = proto_array_.begin(); - *iter = "qux"; - EXPECT_EQ("qux", proto_array_.Get(0)); -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/service.cc b/src/google/protobuf/service.cc deleted file mode 100644 index 0c997930..00000000 --- a/src/google/protobuf/service.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/service.h> - -namespace google { -namespace protobuf { - -Service::~Service() {} -RpcChannel::~RpcChannel() {} -RpcController::~RpcController() {} - -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h deleted file mode 100644 index 22edf694..00000000 --- a/src/google/protobuf/service.h +++ /dev/null @@ -1,273 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This module declares the abstract interfaces underlying proto2 RPC -// services. These are intented to be independent of any particular RPC -// implementation, so that proto2 services can be used on top of a variety -// of implementations. -// -// -// When you use the protocol compiler to compile a service definition, it -// generates two classes: An abstract interface for the service (with -// methods matching the service definition) and a "stub" implementation. -// A stub is just a type-safe wrapper around an RpcChannel which emulates a -// local implementation of the service. -// -// For example, the service definition: -// service MyService { -// rpc Foo(MyRequest) returns(MyResponse); -// } -// will generate abstract interface "MyService" and class "MyService::Stub". -// You could implement a MyService as follows: -// class MyServiceImpl : public MyService { -// public: -// MyServiceImpl() {} -// ~MyServiceImpl() {} -// -// // implements MyService --------------------------------------- -// -// void Foo(google::protobuf::RpcController* controller, -// const MyRequest* request, -// MyResponse* response, -// Closure* done) { -// // ... read request and fill in response ... -// done->Run(); -// } -// }; -// You would then register an instance of MyServiceImpl with your RPC server -// implementation. (How to do that depends on the implementation.) -// -// To call a remote MyServiceImpl, first you need an RpcChannel connected to it. -// How to construct a channel depends, again, on your RPC implementation. -// Here we use a hypothentical "MyRpcChannel" as an example: -// MyRpcChannel channel("rpc:hostname:1234/myservice"); -// MyRpcController controller; -// MyServiceImpl::Stub stub(&channel); -// FooRequest request; -// FooRespnose response; -// -// // ... fill in request ... -// -// stub.Foo(&controller, request, &response, NewCallback(HandleResponse)); -// -// On Thread-Safety: -// -// Different RPC implementations may make different guarantees about what -// threads they may run callbacks on, and what threads the application is -// allowed to use to call the RPC system. Portable software should be ready -// for callbacks to be called on any thread, but should not try to call the -// RPC system from any thread except for the ones on which it received the -// callbacks. Realistically, though, simple software will probably want to -// use a single-threaded RPC system while high-end software will want to -// use multiple threads. RPC implementations should provide multiple -// choices. - -#ifndef GOOGLE_PROTOBUF_SERVICE_H__ -#define GOOGLE_PROTOBUF_SERVICE_H__ - -#include <string> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -// Defined in this file. -class Service; -class RpcController; -class RpcChannel; - -// Defined in other files. -class Descriptor; // descriptor.h -class ServiceDescriptor; // descriptor.h -class MethodDescriptor; // descriptor.h -class Message; // message.h - -// Abstract base interface for protocol-buffer-based RPC services. Services -// themselves are abstract interfaces (implemented either by servers or as -// stubs), but they subclass this base interface. The methods of this -// interface can be used to call the methods of the Service without knowing -// its exact type at compile time (analogous to Reflection). -class LIBPROTOBUF_EXPORT Service { - public: - inline Service() {} - virtual ~Service(); - - // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second - // parameter to the constructor to tell it to delete its RpcChannel when - // destroyed. - enum ChannelOwnership { - STUB_OWNS_CHANNEL, - STUB_DOESNT_OWN_CHANNEL - }; - - // Get the ServiceDescriptor describing this service and its methods. - virtual const ServiceDescriptor* GetDescriptor() = 0; - - // Call a method of the service specified by MethodDescriptor. This is - // normally implemented as a simple switch() that calls the standard - // definitions of the service's methods. - // - // Preconditions: - // * method->service() == GetDescriptor() - // * request and response are of the exact same classes as the objects - // returned by GetRequestPrototype(method) and - // GetResponsePrototype(method). - // * After the call has started, the request must not be modified and the - // response must not be accessed at all until "done" is called. - // * "controller" is of the correct type for the RPC implementation being - // used by this Service. For stubs, the "correct type" depends on the - // RpcChannel which the stub is using. Server-side Service - // implementations are expected to accept whatever type of RpcController - // the server-side RPC implementation uses. - // - // Postconditions: - // * "done" will be called when the method is complete. This may be - // before CallMethod() returns or it may be at some point in the future. - // * If the RPC succeeded, "response" contains the response returned by - // the server. - // * If the RPC failed, "response"'s contents are undefined. The - // RpcController can be queried to determine if an error occurred and - // possibly to get more information about the error. - virtual void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) = 0; - - // CallMethod() requires that the request and response passed in are of a - // particular subclass of Message. GetRequestPrototype() and - // GetResponsePrototype() get the default instances of these required types. - // You can then call Message::New() on these instances to construct mutable - // objects which you can then pass to CallMethod(). - // - // Example: - // const MethodDescriptor* method = - // service->GetDescriptor()->FindMethodByName("Foo"); - // Message* request = stub->GetRequestPrototype (method)->New(); - // Message* response = stub->GetResponsePrototype(method)->New(); - // request->ParseFromString(input); - // service->CallMethod(method, *request, response, callback); - virtual const Message& GetRequestPrototype( - const MethodDescriptor* method) const = 0; - virtual const Message& GetResponsePrototype( - const MethodDescriptor* method) const = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service); -}; - -// An RpcController mediates a single method call. The primary purpose of -// the controller is to provide a way to manipulate settings specific to the -// RPC implementation and to find out about RPC-level errors. -// -// The methods provided by the RpcController interface are intended to be a -// "least common denominator" set of features which we expect all -// implementations to support. Specific implementations may provide more -// advanced features (e.g. deadline propagation). -class LIBPROTOBUF_EXPORT RpcController { - public: - inline RpcController() {} - virtual ~RpcController(); - - // Client-side methods --------------------------------------------- - // These calls may be made from the client side only. Their results - // are undefined on the server side (may crash). - - // Resets the RpcController to its initial state so that it may be reused in - // a new call. Must not be called while an RPC is in progress. - virtual void Reset() = 0; - - // After a call has finished, returns true if the call failed. The possible - // reasons for failure depend on the RPC implementation. Failed() must not - // be called before a call has finished. If Failed() returns true, the - // contents of the response message are undefined. - virtual bool Failed() const = 0; - - // If Failed() is true, returns a human-readable description of the error. - virtual string ErrorText() const = 0; - - // Advises the RPC system that the caller desires that the RPC call be - // canceled. The RPC system may cancel it immediately, may wait awhile and - // then cancel it, or may not even cancel the call at all. If the call is - // canceled, the "done" callback will still be called and the RpcController - // will indicate that the call failed at that time. - virtual void StartCancel() = 0; - - // Server-side methods --------------------------------------------- - // These calls may be made from the server side only. Their results - // are undefined on the client side (may crash). - - // Causes Failed() to return true on the client side. "reason" will be - // incorporated into the message returned by ErrorText(). If you find - // you need to return machine-readable information about failures, you - // should incorporate it into your response protocol buffer and should - // NOT call SetFailed(). - virtual void SetFailed(const string& reason) = 0; - - // If true, indicates that the client canceled the RPC, so the server may - // as well give up on replying to it. The server should still call the - // final "done" callback. - virtual bool IsCanceled() const = 0; - - // Asks that the given callback be called when the RPC is canceled. The - // callback will always be called exactly once. If the RPC completes without - // being canceled, the callback will be called after completion. If the RPC - // has already been canceled when NotifyOnCancel() is called, the callback - // will be called immediately. - // - // NotifyOnCancel() must be called no more than once per request. - virtual void NotifyOnCancel(Closure* callback) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController); -}; - -// Abstract interface for an RPC channel. An RpcChannel represents a -// communication line to a Service which can be used to call that Service's -// methods. The Service may be running on another machine. Normally, you -// should not call an RpcChannel directly, but instead construct a stub Service -// wrapping it. Example: -// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234"); -// MyService* service = new MyService::Stub(channel); -// service->MyMethod(request, &response, callback); -class LIBPROTOBUF_EXPORT RpcChannel { - public: - inline RpcChannel() {} - virtual ~RpcChannel(); - - // Call the given method of the remote service. The signature of this - // procedure looks the same as Service::CallMethod(), but the requirements - // are less strict in one important way: the request and response objects - // need not be of any specific class as long as their descriptors are - // method->input_type() and method->output_type(). - virtual void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_SERVICE_H__ diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc deleted file mode 100644 index d7182841..00000000 --- a/src/google/protobuf/stubs/common.cc +++ /dev/null @@ -1,261 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <stdio.h> -#include <errno.h> - -#include "config.h" - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN // We only need minimal includes -#include <windows.h> -#elif defined(HAVE_PTHREAD) -#include <pthread.h> -#else -#error "No suitable threading library available." -#endif - -namespace google { -namespace protobuf { - -namespace internal { - -void VerifyVersion(int headerVersion, - int minLibraryVersion, - const char* filename) { - if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { - // Library is too old for headers. - GOOGLE_LOG(FATAL) - << "This program requires version " << VersionString(minLibraryVersion) - << " of the Protocol Buffer runtime library, but the installed version " - "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update " - "your library. If you compiled the program yourself, make sure that " - "your headers are from the same version of Protocol Buffers as your " - "link-time library. (Version verification failed in \"" - << filename << "\".)"; - } - if (headerVersion < kMinHeaderVersionForLibrary) { - // Headers are too old for library. - GOOGLE_LOG(FATAL) - << "This program was compiled against version " - << VersionString(headerVersion) << " of the Protocol Buffer runtime " - "library, which is not compatible with the installed version (" - << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program " - "author for an update. If you compiled the program yourself, make " - "sure that your headers are from the same version of Protocol Buffers " - "as your link-time library. (Version verification failed in \"" - << filename << "\".)"; - } -} - -string VersionString(int version) { - int major = version / 1000000; - int minor = (version / 1000) % 1000; - int micro = version % 1000; - - return strings::Substitute("$0.$1.$2", major, minor, micro); -} - -} // namespace internal - -// =================================================================== -// emulates google3/base/logging.cc - -namespace internal { - -void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { - static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; - - // We use fprintf() instead of cerr because we want this to work at static - // initialization time. - fprintf(stderr, "libprotobuf %s %s:%d] %s\n", - level_names[level], filename, line, message.c_str()); - fflush(stderr); // Needed on MSVC. -} - -void NullLogHandler(LogLevel level, const char* filename, int line, - const string& message) { - // Nothing. -} - -static LogHandler* log_handler_ = &DefaultLogHandler; -static int log_silencer_count_ = 0; -static Mutex log_silencer_count_mutex_; - -static string SimpleCtoa(char c) { return string(1, c); } - -#undef DECLARE_STREAM_OPERATOR -#define DECLARE_STREAM_OPERATOR(TYPE, TOSTRING) \ - LogMessage& LogMessage::operator<<(TYPE value) { \ - message_ += TOSTRING(value); \ - return *this; \ - } - -DECLARE_STREAM_OPERATOR(const string&, ) -DECLARE_STREAM_OPERATOR(const char* , ) -DECLARE_STREAM_OPERATOR(char , SimpleCtoa) -DECLARE_STREAM_OPERATOR(int , SimpleItoa) -DECLARE_STREAM_OPERATOR(uint , SimpleItoa) -DECLARE_STREAM_OPERATOR(double , SimpleDtoa) -#undef DECLARE_STREAM_OPERATOR - -LogMessage::LogMessage(LogLevel level, const char* filename, int line) - : level_(level), filename_(filename), line_(line) {} -LogMessage::~LogMessage() {} - -void LogMessage::Finish() { - bool suppress = false; - - if (level_ != LOGLEVEL_FATAL) { - MutexLock lock(&internal::log_silencer_count_mutex_); - suppress = internal::log_silencer_count_ > 0; - } - - if (!suppress) { - internal::log_handler_(level_, filename_, line_, message_); - } - - if (level_ == LOGLEVEL_FATAL) { - abort(); - } -} - -void LogFinisher::operator=(LogMessage& other) { - other.Finish(); -} - -} // namespace internal - -LogHandler* SetLogHandler(LogHandler* new_func) { - LogHandler* old = internal::log_handler_; - if (old == &internal::NullLogHandler) { - old = NULL; - } - if (new_func == NULL) { - internal::log_handler_ = &internal::NullLogHandler; - } else { - internal::log_handler_ = new_func; - } - return old; -} - -LogSilencer::LogSilencer() { - MutexLock lock(&internal::log_silencer_count_mutex_); - ++internal::log_silencer_count_; -}; - -LogSilencer::~LogSilencer() { - MutexLock lock(&internal::log_silencer_count_mutex_); - --internal::log_silencer_count_; -}; - -// =================================================================== -// emulates google3/base/callback.cc - -Closure::~Closure() {} - -namespace internal { FunctionClosure0::~FunctionClosure0() {} } - -void DoNothing() {} - -// =================================================================== -// emulates google3/base/mutex.cc - -#ifdef _WIN32 - -struct Mutex::Internal { - CRITICAL_SECTION mutex; -#ifndef NDEBUG - // Used only to implement AssertHeld(). - DWORD thread_id; -#endif -}; - -Mutex::Mutex() - : mInternal(new Internal) { - InitializeCriticalSection(&mInternal->mutex); -} - -Mutex::~Mutex() { - DeleteCriticalSection(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - EnterCriticalSection(&mInternal->mutex); -#ifndef NDEBUG - mInternal->thread_id = GetCurrentThreadId(); -#endif -} - -void Mutex::Unlock() { -#ifndef NDEBUG - mInternal->thread_id = 0; -#endif - LeaveCriticalSection(&mInternal->mutex); -} - -void Mutex::AssertHeld() { -#ifndef NDEBUG - GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); -#endif -} - -#elif defined(HAVE_PTHREAD) - -struct Mutex::Internal { - pthread_mutex_t mutex; -}; - -Mutex::Mutex() - : mInternal(new Internal) { - pthread_mutex_init(&mInternal->mutex, NULL); -} - -Mutex::~Mutex() { - pthread_mutex_destroy(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - int result = pthread_mutex_lock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); - } -} - -void Mutex::Unlock() { - int result = pthread_mutex_unlock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); - } -} - -void Mutex::AssertHeld() { - // pthreads dosn't provide a way to check which thread holds the mutex. - // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? -} - -#endif - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h deleted file mode 100644 index 89070d63..00000000 --- a/src/google/protobuf/stubs/common.h +++ /dev/null @@ -1,1061 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) and others -// -// Contains basic types and utilities used by the rest of the library. - -#ifndef GOOGLE_PROTOBUF_COMMON_H__ -#define GOOGLE_PROTOBUF_COMMON_H__ - -#include <assert.h> -#include <stdlib.h> -#include <cstddef> -#include <string> -#include <string.h> -#ifndef _MSC_VER -#include <stdint.h> -#endif - -namespace std {} - -namespace google { -namespace protobuf { - -using namespace std; // Don't do this at home, kids. - -#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS -#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -#ifdef _MSC_VER - #ifdef LIBPROTOBUF_EXPORTS - #define LIBPROTOBUF_EXPORT __declspec(dllexport) - #else - #define LIBPROTOBUF_EXPORT __declspec(dllimport) - #endif - #ifdef LIBPROTOC_EXPORTS - #define LIBPROTOC_EXPORT __declspec(dllexport) - #else - #define LIBPROTOC_EXPORT __declspec(dllimport) - #endif -#else - #define LIBPROTOBUF_EXPORT - #define LIBPROTOC_EXPORT -#endif - -namespace internal { - -// Some of these constants are macros rather than const ints so that they can -// be used in #if directives. - -// The current version, represented as a single integer to make comparison -// easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2000001 - -// The minimum library version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2000001 - -// The minimum header version which works with the current version of -// the library. This constant should only be used by protoc's C++ code -// generator. -static const int kMinHeaderVersionForLibrary = 2000001; - -// The minimum protoc version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2000001 - -// The minimum header version which works with the current version of -// protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2000001; - -// Verifies that the headers and libraries are compatible. Use the macro -// below to call this. -void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, - const char* filename); - -// Converts a numeric version number to a string. -string LIBPROTOBUF_EXPORT VersionString(int version); - -} // namespace internal - -// Place this macro in your main() function (or somewhere before you attempt -// to use the protobuf library) to verify that the version you link against -// matches the headers you compiled against. If a version mismatch is -// detected, the process will abort. -#define GOOGLE_PROTOBUF_VERIFY_VERSION \ - ::google::protobuf::internal::VerifyVersion( \ - GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \ - __FILE__) - -// =================================================================== -// from google3/base/port.h - -typedef unsigned int uint; - -#ifdef _MSC_VER -typedef __int8 int8; -typedef __int16 int16; -typedef __int32 int32; -typedef __int64 int64; - -typedef unsigned __int8 uint8; -typedef unsigned __int16 uint16; -typedef unsigned __int32 uint32; -typedef unsigned __int64 uint64; -#else -typedef int8_t int8; -typedef int16_t int16; -typedef int32_t int32; -typedef int64_t int64; - -typedef uint8_t uint8; -typedef uint16_t uint16; -typedef uint32_t uint32; -typedef uint64_t uint64; -#endif - -// long long macros to be used because gcc and vc++ use different suffixes, -// and different size specifiers in format strings -#undef GOOGLE_LONGLONG -#undef GOOGLE_ULONGLONG -#undef GOOGLE_LL_FORMAT - -#ifdef _MSC_VER -#define GOOGLE_LONGLONG(x) x##I64 -#define GOOGLE_ULONGLONG(x) x##UI64 -#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...) -#else -#define GOOGLE_LONGLONG(x) x##LL -#define GOOGLE_ULONGLONG(x) x##ULL -#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also. -#endif - -static const int32 kint32max = 0x7FFFFFFF; -static const int32 kint32min = -kint32max - 1; -static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); -static const int64 kint64min = -kint64max - 1; -static const uint32 kuint32max = 0xFFFFFFFFu; -static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); - -#undef GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -// For functions we want to force inline. -// Introduced in gcc 3.1. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) -#else -// Other compilers will have to figure it out for themselves. -#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE -#endif - -// =================================================================== -// from google3/base/basictypes.h - -// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr. -// The expression is a compile-time constant, and therefore can be -// used in defining new arrays, for example. -// -// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error -// -// "warning: division by zero in ..." -// -// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer. -// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays. -// -// The following comments are on the implementation details, and can -// be ignored by the users. -// -// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in -// the array) and sizeof(*(arr)) (the # of bytes in one array -// element). If the former is divisible by the latter, perhaps arr is -// indeed an array, in which case the division result is the # of -// elements in the array. Otherwise, arr cannot possibly be an array, -// and we generate a compiler error to prevent the code from -// compiling. -// -// Since the size of bool is implementation-defined, we need to cast -// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final -// result has type size_t. -// -// This macro is not perfect as it wrongfully accepts certain -// pointers, namely where the pointer size is divisible by the pointee -// size. Since all our code has to go through a 32-bit compiler, -// where a pointer is 4 bytes, this means all pointers to a type whose -// size is 3 or greater than 4 will be (righteously) rejected. -// -// Kudos to Jorg Brown for this simple and elegant implementation. - -#undef GOOGLE_ARRAYSIZE -#define GOOGLE_ARRAYSIZE(a) \ - ((sizeof(a) / sizeof(*(a))) / \ - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) - -namespace internal { - -// Use implicit_cast as a safe version of static_cast or const_cast -// for upcasting in the type hierarchy (i.e. casting a pointer to Foo -// to a pointer to SuperclassOfFoo or casting a pointer to Foo to -// a const pointer to Foo). -// When you use implicit_cast, the compiler checks that the cast is safe. -// Such explicit implicit_casts are necessary in surprisingly many -// situations where C++ demands an exact type match instead of an -// argument type convertable to a target type. -// -// The From type can be inferred, so the preferred syntax for using -// implicit_cast is the same as for static_cast etc.: -// -// implicit_cast<ToType>(expr) -// -// implicit_cast would have been part of the C++ standard library, -// but the proposal was submitted too late. It will probably make -// its way into the language in the future. -template<typename To, typename From> -inline To implicit_cast(From const &f) { - return f; -} - -// When you upcast (that is, cast a pointer from type Foo to type -// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts -// always succeed. When you downcast (that is, cast a pointer from -// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because -// how do you know the pointer is really of type SubclassOfFoo? It -// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, -// when you downcast, you should use this macro. In debug mode, we -// use dynamic_cast<> to double-check the downcast is legal (we die -// if it's not). In normal mode, we do the efficient static_cast<> -// instead. Thus, it's important to test in debug mode to make sure -// the cast is legal! -// This is the only place in the code we should use dynamic_cast<>. -// In particular, you SHOULDN'T be using dynamic_cast<> in order to -// do RTTI (eg code like this: -// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); -// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); -// You should design the code some other way not to need this. - -template<typename To, typename From> // use like this: down_cast<T*>(foo); -inline To down_cast(From* f) { // so we only accept pointers - // Ensures that To is a sub-type of From *. This test is here only - // for compile-time type checking, and has no overhead in an - // optimized build at run-time, as it will be optimized away - // completely. - if (false) { - implicit_cast<From*, To>(0); - } - - assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only! - return static_cast<To>(f); -} - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::implicit_cast; -using internal::down_cast; - -// The COMPILE_ASSERT macro can be used to verify that a compile time -// expression is true. For example, you could use it to verify the -// size of a static array: -// -// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, -// content_type_names_incorrect_size); -// -// or to make sure a struct is smaller than a certain size: -// -// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); -// -// The second argument to the macro is the name of the variable. If -// the expression is false, most compilers will issue a warning/error -// containing the name of the variable. - -namespace internal { - -template <bool> -struct CompileAssert { -}; - -} // namespace internal - -#undef GOOGLE_COMPILE_ASSERT -#define GOOGLE_COMPILE_ASSERT(expr, msg) \ - typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \ - msg[bool(expr) ? 1 : -1] - -// Implementation details of COMPILE_ASSERT: -// -// - COMPILE_ASSERT works by defining an array type that has -1 -// elements (and thus is invalid) when the expression is false. -// -// - The simpler definition -// -// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1] -// -// does not work, as gcc supports variable-length arrays whose sizes -// are determined at run-time (this is gcc's extension and not part -// of the C++ standard). As a result, gcc fails to reject the -// following code with the simple definition: -// -// int foo; -// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is -// // not a compile-time constant. -// -// - By using the type CompileAssert<(bool(expr))>, we ensures that -// expr is a compile-time constant. (Template arguments must be -// determined at compile-time.) -// -// - The outter parentheses in CompileAssert<(bool(expr))> are necessary -// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written -// -// CompileAssert<bool(expr)> -// -// instead, these compilers will refuse to compile -// -// COMPILE_ASSERT(5 > 0, some_message); -// -// (They seem to think the ">" in "5 > 0" marks the end of the -// template argument list.) -// -// - The array size is (bool(expr) ? 1 : -1), instead of simply -// -// ((expr) ? 1 : -1). -// -// This is to avoid running into a bug in MS VC 7.1, which -// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. - -// =================================================================== -// from google3/base/scoped_ptr.h - -namespace internal { - -// This is an implementation designed to match the anticipated future TR2 -// implementation of the scoped_ptr class, and its closely-related brethren, -// scoped_array, scoped_ptr_malloc, and make_scoped_ptr. - -template <class C> class scoped_ptr; -template <class C> class scoped_array; - -// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T> -// automatically deletes the pointer it holds (if any). -// That is, scoped_ptr<T> owns the T object that it points to. -// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object. -// -// The size of a scoped_ptr is small: -// sizeof(scoped_ptr<C>) == sizeof(C*) -template <class C> -class scoped_ptr { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to intializing with NULL. - // There is no way to create an uninitialized scoped_ptr. - // The input parameter must be allocated with new. - explicit scoped_ptr(C* p = NULL) : ptr_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_ptr() { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != ptr_) { - enum { type_must_be_complete = sizeof(C) }; - delete ptr_; - ptr_ = p; - } - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(ptr_ != NULL); - return *ptr_; - } - C* operator->() const { - assert(ptr_ != NULL); - return ptr_; - } - C* get() const { return ptr_; } - - // Comparison operators. - // These return whether two scoped_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return ptr_ == p; } - bool operator!=(C* p) const { return ptr_ != p; } - - // Swap two scoped pointers. - void swap(scoped_ptr& p2) { - C* tmp = ptr_; - ptr_ = p2.ptr_; - p2.ptr_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = ptr_; - ptr_ = NULL; - return retVal; - } - - private: - C* ptr_; - - // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't - // make sense, and if C2 == C, it still doesn't make sense because you should - // never have the same object owned by two different scoped_ptrs. - template <class C2> bool operator==(scoped_ptr<C2> const& p2) const; - template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const; - - // Disallow evil constructors - scoped_ptr(const scoped_ptr&); - void operator=(const scoped_ptr&); -}; - -// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate -// with new [] and the destructor deletes objects with delete []. -// -// As with scoped_ptr<C>, a scoped_array<C> either points to an object -// or is NULL. A scoped_array<C> owns the object that it points to. -// -// Size: sizeof(scoped_array<C>) == sizeof(C*) -template <class C> -class scoped_array { - public: - - // The element type - typedef C element_type; - - // Constructor. Defaults to intializing with NULL. - // There is no way to create an uninitialized scoped_array. - // The input parameter must be allocated with new []. - explicit scoped_array(C* p = NULL) : array_(p) { } - - // Destructor. If there is a C object, delete it. - // We don't need to test ptr_ == NULL because C++ does that for us. - ~scoped_array() { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - } - - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. - // this->reset(this->get()) works. - void reset(C* p = NULL) { - if (p != array_) { - enum { type_must_be_complete = sizeof(C) }; - delete[] array_; - array_ = p; - } - } - - // Get one element of the current object. - // Will assert() if there is no current object, or index i is negative. - C& operator[](std::ptrdiff_t i) const { - assert(i >= 0); - assert(array_ != NULL); - return array_[i]; - } - - // Get a pointer to the zeroth element of the current object. - // If there is no current object, return NULL. - C* get() const { - return array_; - } - - // Comparison operators. - // These return whether two scoped_array refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return array_ == p; } - bool operator!=(C* p) const { return array_ != p; } - - // Swap two scoped arrays. - void swap(scoped_array& p2) { - C* tmp = array_; - array_ = p2.array_; - p2.array_ = tmp; - } - - // Release an array. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* retVal = array_; - array_ = NULL; - return retVal; - } - - private: - C* array_; - - // Forbid comparison of different scoped_array types. - template <class C2> bool operator==(scoped_array<C2> const& p2) const; - template <class C2> bool operator!=(scoped_array<C2> const& p2) const; - - // Disallow evil constructors - scoped_array(const scoped_array&); - void operator=(const scoped_array&); -}; - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::scoped_ptr; -using internal::scoped_array; - -// =================================================================== -// emulates google3/base/logging.h - -enum LogLevel { - LOGLEVEL_INFO, // Informational. This is never actually used by - // libprotobuf. - LOGLEVEL_WARNING, // Warns about issues that, although not technically a - // problem now, could cause problems in the future. For - // example, a // warning will be printed when parsing a - // message that is near the message size limit. - LOGLEVEL_ERROR, // An error occurred which should never happen during - // normal use. - LOGLEVEL_FATAL, // An error occurred from which the library cannot - // recover. This usually indicates a programming error - // in the code which calls the library, especially when - // compiled in debug mode. - -#ifdef NDEBUG - LOGLEVEL_DFATAL = LOGLEVEL_ERROR -#else - LOGLEVEL_DFATAL = LOGLEVEL_FATAL -#endif -}; - -namespace internal { - -class LogFinisher; - -class LIBPROTOBUF_EXPORT LogMessage { - public: - LogMessage(LogLevel level, const char* filename, int line); - ~LogMessage(); - - LogMessage& operator<<(const string& value); - LogMessage& operator<<(const char* value); - LogMessage& operator<<(char value); - LogMessage& operator<<(int value); - LogMessage& operator<<(uint value); - LogMessage& operator<<(double value); - - private: - friend class LogFinisher; - void Finish(); - - LogLevel level_; - const char* filename_; - int line_; - string message_; -}; - -// Used to make the entire "LOG(BLAH) << etc." expression have a void return -// type and print a newline after each message. -class LIBPROTOBUF_EXPORT LogFinisher { - public: - void operator=(LogMessage& other); -}; - -} // namespace internal - -// Undef everything in case we're being mixed with some other Google library -// which already defined them itself. Presumably all Google libraries will -// support the same syntax for these so it should not be a big deal if they -// end up using our definitions instead. -#undef GOOGLE_LOG -#undef GOOGLE_LOG_IF - -#undef GOOGLE_CHECK -#undef GOOGLE_CHECK_EQ -#undef GOOGLE_CHECK_NE -#undef GOOGLE_CHECK_LT -#undef GOOGLE_CHECK_LE -#undef GOOGLE_CHECK_GT -#undef GOOGLE_CHECK_GE - -#undef GOOGLE_DLOG -#undef GOOGLE_DCHECK -#undef GOOGLE_DCHECK_EQ -#undef GOOGLE_DCHECK_NE -#undef GOOGLE_DCHECK_LT -#undef GOOGLE_DCHECK_LE -#undef GOOGLE_DCHECK_GT -#undef GOOGLE_DCHECK_GE - -#define GOOGLE_LOG(LEVEL) \ - ::google::protobuf::internal::LogFinisher() = \ - ::google::protobuf::internal::LogMessage( \ - ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__) -#define GOOGLE_LOG_IF(LEVEL, CONDITION) \ - !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL) - -#define GOOGLE_CHECK(EXPRESSION) \ - GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": " -#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK(A == B) -#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK(A != B) -#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK(A < B) -#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK(A <= B) -#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK(A > B) -#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK(A >= B) - -#ifdef NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG_IF(false, INFO) - -#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION) -#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK(A == B) -#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK(A != B) -#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK(A < B) -#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK(A <= B) -#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK(A > B) -#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK(A >= B) - -#else // NDEBUG - -#define GOOGLE_DLOG GOOGLE_LOG - -#define GOOGLE_DCHECK GOOGLE_CHECK -#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ -#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE -#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT -#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE -#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT -#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE - -#endif // !NDEBUG - -typedef void LogHandler(LogLevel level, const char* filename, int line, - const string& message); - -// The protobuf library sometimes writes warning and error messages to -// stderr. These messages are primarily useful for developers, but may -// also help end users figure out a problem. If you would prefer that -// these messages be sent somewhere other than stderr, call SetLogHandler() -// to set your own handler. This returns the old handler. Set the handler -// to NULL to ignore log messages (but see also LogSilencer, below). -// -// Obviously, SetLogHandler is not thread-safe. You should only call it -// at initialization time, and probably not from library code. If you -// simply want to suppress log messages temporarily (e.g. because you -// have some code that tends to trigger them frequently and you know -// the warnings are not important to you), use the LogSilencer class -// below. -LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func); - -// Create a LogSilencer if you want to temporarily suppress all log -// messages. As long as any LogSilencer objects exist, non-fatal -// log messages will be discarded (the current LogHandler will *not* -// be called). Constructing a LogSilencer is thread-safe. You may -// accidentally suppress log messages occurring in another thread, but -// since messages are generally for debugging purposes only, this isn't -// a big deal. If you want to intercept log messages, use SetLogHandler(). -class LIBPROTOBUF_EXPORT LogSilencer { - public: - LogSilencer(); - ~LogSilencer(); -}; - -// =================================================================== -// emulates google3/base/callback.h - -// Abstract interface for a callback. When calling an RPC, you must provide -// a Closure to call when the procedure completes. See the Service interface -// in service.h. -// -// To automatically construct a Closure which calls a particular function or -// method with a particular set of parameters, use the NewCallback() function. -// Example: -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(&FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// -// Example that calls a method: -// class Handler { -// public: -// ... -// -// void FooDone(const FooResponse* response) { -// ... -// } -// -// void CallFoo() { -// ... -// // When done, call FooDone() and pass it a pointer to the response. -// Closure* callback = NewCallback(this, &Handler::FooDone, response); -// // Make the call. -// service->Foo(controller, request, response, callback); -// } -// }; -// -// Currently NewCallback() supports binding zero, one, or two arguments. -// -// Callbacks created with NewCallback() automatically delete themselves when -// executed. They should be used when a callback is to be called exactly -// once (usually the case with RPC callbacks). If a callback may be called -// a different number of times (including zero), create it with -// NewPermanentCallback() instead. You are then responsible for deleting the -// callback (using the "delete" keyword as normal). -// -// Note that NewCallback() is a bit touchy regarding argument types. Generally, -// the values you provide for the parameter bindings must exactly match the -// types accepted by the callback function. For example: -// void Foo(string s); -// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS -// Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; -// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes. -// However, correctly-typed pointers will work just fine. -class LIBPROTOBUF_EXPORT Closure { - public: - Closure() {} - virtual ~Closure(); - - virtual void Run() = 0; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure); -}; - -namespace internal { - -class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { - public: - typedef void (*FunctionType)(); - - FunctionClosure0(FunctionType function, bool self_deleting) - : function_(function), self_deleting_(self_deleting) {} - ~FunctionClosure0(); - - void Run() { - function_(); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; -}; - -template <typename Class> -class MethodClosure0 : public Closure { - public: - typedef void (Class::*MethodType)(); - - MethodClosure0(Class* object, MethodType method, bool self_deleting) - : object_(object), method_(method), self_deleting_(self_deleting) {} - ~MethodClosure0() {} - - void Run() { - (object_->*method_)(); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; -}; - -template <typename Arg1> -class FunctionClosure1 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1); - - FunctionClosure1(FunctionType function, bool self_deleting, - Arg1 arg1) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1) {} - ~FunctionClosure1() {} - - void Run() { - function_(arg1_); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; -}; - -template <typename Class, typename Arg1> -class MethodClosure1 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1); - - MethodClosure1(Class* object, MethodType method, bool self_deleting, - Arg1 arg1) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1) {} - ~MethodClosure1() {} - - void Run() { - (object_->*method_)(arg1_); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; -}; - -template <typename Arg1, typename Arg2> -class FunctionClosure2 : public Closure { - public: - typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2); - - FunctionClosure2(FunctionType function, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : function_(function), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~FunctionClosure2() {} - - void Run() { - function_(arg1_, arg2_); - if (self_deleting_) delete this; - } - - private: - FunctionType function_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -template <typename Class, typename Arg1, typename Arg2> -class MethodClosure2 : public Closure { - public: - typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2); - - MethodClosure2(Class* object, MethodType method, bool self_deleting, - Arg1 arg1, Arg2 arg2) - : object_(object), method_(method), self_deleting_(self_deleting), - arg1_(arg1), arg2_(arg2) {} - ~MethodClosure2() {} - - void Run() { - (object_->*method_)(arg1_, arg2_); - if (self_deleting_) delete this; - } - - private: - Class* object_; - MethodType method_; - bool self_deleting_; - Arg1 arg1_; - Arg2 arg2_; -}; - -} // namespace internal - -// See Closure. -inline Closure* NewCallback(void (*function)()) { - return new internal::FunctionClosure0(function, true); -} - -// See Closure. -inline Closure* NewPermanentCallback(void (*function)()) { - return new internal::FunctionClosure0(function, false); -} - -// See Closure. -template <typename Class> -inline Closure* NewCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0<Class>(object, method, true); -} - -// See Closure. -template <typename Class> -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) { - return new internal::MethodClosure0<Class>(object, method, false); -} - -// See Closure. -template <typename Arg1> -inline Closure* NewCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1<Arg1>(function, true, arg1); -} - -// See Closure. -template <typename Arg1> -inline Closure* NewPermanentCallback(void (*function)(Arg1), - Arg1 arg1) { - return new internal::FunctionClosure1<Arg1>(function, false, arg1); -} - -// See Closure. -template <typename Class, typename Arg1> -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1); -} - -// See Closure. -template <typename Class, typename Arg1> -inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1), - Arg1 arg1) { - return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1); -} - -// See Closure. -template <typename Arg1, typename Arg2> -inline Closure* NewCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2<Arg1, Arg2>( - function, true, arg1, arg2); -} - -// See Closure. -template <typename Arg1, typename Arg2> -inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::FunctionClosure2<Arg1, Arg2>( - function, false, arg1, arg2); -} - -// See Closure. -template <typename Class, typename Arg1, typename Arg2> -inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2<Class, Arg1, Arg2>( - object, method, true, arg1, arg2); -} - -// See Closure. -template <typename Class, typename Arg1, typename Arg2> -inline Closure* NewPermanentCallback( - Class* object, void (Class::*method)(Arg1, Arg2), - Arg1 arg1, Arg2 arg2) { - return new internal::MethodClosure2<Class, Arg1, Arg2>( - object, method, false, arg1, arg2); -} - -// A function which does nothing. Useful for creating no-op callbacks, e.g.: -// Closure* nothing = NewCallback(&DoNothing); -void LIBPROTOBUF_EXPORT DoNothing(); - -// =================================================================== -// emulates google3/base/mutex.h - -namespace internal { - -// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T -// may hold a mutex at a given time. If T attempts to Lock() the same Mutex -// while holding it, T will deadlock. -class LIBPROTOBUF_EXPORT Mutex { - public: - // Create a Mutex that is not held by anybody. - Mutex(); - - // Destructor - ~Mutex(); - - // Block if necessary until this Mutex is free, then acquire it exclusively. - void Lock(); - - // Release this Mutex. Caller must hold it exclusively. - void Unlock(); - - // Crash if this Mutex is not held exclusively by this thread. - // May fail to crash when it should; will never crash when it should not. - void AssertHeld(); - - private: - struct Internal; - Internal* mInternal; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); -}; - -// MutexLock(mu) acquires mu when constructed and releases it when destroyed. -class LIBPROTOBUF_EXPORT MutexLock { - public: - explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } - ~MutexLock() { this->mu_->Unlock(); } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); -}; - -// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. -class LIBPROTOBUF_EXPORT MutexLockMaybe { - public: - explicit MutexLockMaybe(Mutex *mu) : - mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } - ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } - private: - Mutex *const mu_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); -}; - -} // namespace internal - -// We made these internal so that they would show up as such in the docs, -// but we don't want to stick "internal::" in front of them everywhere. -using internal::Mutex; -using internal::MutexLock; -using internal::MutexLockMaybe; - -// =================================================================== -// from google3/base/type_traits.h - -namespace internal { - -// Specified by TR1 [4.7.4] Pointer modifications. -template<typename T> struct remove_pointer { typedef T type; }; -template<typename T> struct remove_pointer<T*> { typedef T type; }; -template<typename T> struct remove_pointer<T* const> { typedef T type; }; -template<typename T> struct remove_pointer<T* volatile> { typedef T type; }; -template<typename T> struct remove_pointer<T* const volatile> { - typedef T type; }; - -} // namespace internal - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMMON_H__ diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc deleted file mode 100644 index c339c5fd..00000000 --- a/src/google/protobuf/stubs/common_unittest.cc +++ /dev/null @@ -1,330 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <vector> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -#include "config.h" - -namespace google { -namespace protobuf { -namespace { - -// TODO(kenton): More tests. - -#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC - -TEST(VersionTest, VersionMatchesConfig) { - // Verify that the version string specified in config.h matches the one - // in common.h. The config.h version is a string which may have a suffix - // like "beta", so we remove that. - string version = PACKAGE_VERSION; - int pos = version.size(); - while (pos > 0 && !ascii_isdigit(version[pos-1])) { - --pos; - } - version.erase(pos); - - EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION)); -} - -#endif // PACKAGE_VERSION - -TEST(CommonTest, IntMinMaxConstants) { - // kint32min was declared incorrectly in the first release of protobufs. - // Ugh. - EXPECT_LT(kint32min, kint32max); - EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1); - EXPECT_LT(kint64min, kint64max); - EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1); - EXPECT_EQ(0, kuint32max + 1); - EXPECT_EQ(0, kuint64max + 1); -} - -vector<string> captured_messages_; - -void CaptureLog(LogLevel level, const char* filename, int line, - const string& message) { - captured_messages_.push_back( - strings::Substitute("$0 $1:$2: $3", - implicit_cast<int>(level), filename, line, message)); -} - -TEST(LoggingTest, DefaultLogging) { - CaptureTestStderr(); - int line = __LINE__; - GOOGLE_LOG(INFO ) << "A message."; - GOOGLE_LOG(WARNING) << "A warning."; - GOOGLE_LOG(ERROR ) << "An error."; - - string text = GetCapturedTestStderr(); - EXPECT_EQ( - "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n" - "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n" - "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n", - text); -} - -TEST(LoggingTest, NullLogging) { - LogHandler* old_handler = SetLogHandler(NULL); - - CaptureTestStderr(); - GOOGLE_LOG(INFO ) << "A message."; - GOOGLE_LOG(WARNING) << "A warning."; - GOOGLE_LOG(ERROR ) << "An error."; - - EXPECT_TRUE(SetLogHandler(old_handler) == NULL); - - string text = GetCapturedTestStderr(); - EXPECT_EQ("", text); -} - -TEST(LoggingTest, CaptureLogging) { - captured_messages_.clear(); - - LogHandler* old_handler = SetLogHandler(&CaptureLog); - - int start_line = __LINE__; - GOOGLE_LOG(ERROR) << "An error."; - GOOGLE_LOG(WARNING) << "A warning."; - - EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); - - ASSERT_EQ(2, captured_messages_.size()); - EXPECT_EQ( - "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.", - captured_messages_[0]); - EXPECT_EQ( - "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.", - captured_messages_[1]); -} - -TEST(LoggingTest, SilenceLogging) { - captured_messages_.clear(); - - LogHandler* old_handler = SetLogHandler(&CaptureLog); - - int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1"; - LogSilencer* silencer1 = new LogSilencer; - GOOGLE_LOG(INFO) << "Not visible."; - LogSilencer* silencer2 = new LogSilencer; - GOOGLE_LOG(INFO) << "Not visible."; - delete silencer1; - GOOGLE_LOG(INFO) << "Not visible."; - delete silencer2; - int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2"; - - EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog); - - ASSERT_EQ(2, captured_messages_.size()); - EXPECT_EQ( - "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1", - captured_messages_[0]); - EXPECT_EQ( - "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2", - captured_messages_[1]); -} - -class ClosureTest : public testing::Test { - public: - void SetA123Method() { a_ = 123; } - static void SetA123Function() { current_instance_->a_ = 123; } - - void SetAMethod(int a) { a_ = a; } - void SetCMethod(string c) { c_ = c; } - - static void SetAFunction(int a) { current_instance_->a_ = a; } - static void SetCFunction(string c) { current_instance_->c_ = c; } - - void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } - static void SetABFunction(int a, const char* b) { - current_instance_->a_ = a; - current_instance_->b_ = b; - } - - virtual void SetUp() { - current_instance_ = this; - a_ = 0; - b_ = NULL; - c_.clear(); - } - - int a_; - const char* b_; - string c_; - - static ClosureTest* current_instance_; -}; - -ClosureTest* ClosureTest::current_instance_ = NULL; - -TEST_F(ClosureTest, TestClosureFunction0) { - Closure* closure = NewCallback(&SetA123Function); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); -} - -TEST_F(ClosureTest, TestClosureMethod0) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetA123Method); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); -} - -TEST_F(ClosureTest, TestClosureFunction1) { - Closure* closure = NewCallback(&SetAFunction, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); -} - -TEST_F(ClosureTest, TestClosureMethod1) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetAMethod, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); -} - -TEST_F(ClosureTest, TestClosureFunction1String) { - Closure* closure = NewCallback(&SetCFunction, string("test")); - EXPECT_NE("test", c_); - closure->Run(); - EXPECT_EQ("test", c_); -} - -TEST_F(ClosureTest, TestClosureMethod1String) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetCMethod, string("test")); - EXPECT_NE("test", c_); - closure->Run(); - EXPECT_EQ("test", c_); -} - -TEST_F(ClosureTest, TestClosureFunction2) { - const char* cstr = "hello"; - Closure* closure = NewCallback(&SetABFunction, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); -} - -TEST_F(ClosureTest, TestClosureMethod2) { - const char* cstr = "hello"; - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetABMethod, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); -} - -// Repeat all of the above with NewPermanentCallback() - -TEST_F(ClosureTest, TestPermanentClosureFunction0) { - Closure* closure = NewPermanentCallback(&SetA123Function); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(123, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod0) { - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetA123Method); - EXPECT_NE(123, a_); - closure->Run(); - EXPECT_EQ(123, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(123, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureFunction1) { - Closure* closure = NewPermanentCallback(&SetAFunction, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(456, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod1) { - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetAMethod, 456); - EXPECT_NE(456, a_); - closure->Run(); - EXPECT_EQ(456, a_); - a_ = 0; - closure->Run(); - EXPECT_EQ(456, a_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureFunction2) { - const char* cstr = "hello"; - Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - a_ = 0; - b_ = NULL; - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - delete closure; -} - -TEST_F(ClosureTest, TestPermanentClosureMethod2) { - const char* cstr = "hello"; - Closure* closure = NewPermanentCallback(current_instance_, - &ClosureTest::SetABMethod, 789, cstr); - EXPECT_NE(789, a_); - EXPECT_NE(cstr, b_); - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - a_ = 0; - b_ = NULL; - closure->Run(); - EXPECT_EQ(789, a_); - EXPECT_EQ(cstr, b_); - delete closure; -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/hash.cc b/src/google/protobuf/stubs/hash.cc deleted file mode 100644 index 43fb9d73..00000000 --- a/src/google/protobuf/stubs/hash.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <google/protobuf/stubs/hash.h> - -namespace google { -namespace protobuf { - -// Nothing needed here right now. - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h deleted file mode 100644 index a62b3f6e..00000000 --- a/src/google/protobuf/stubs/hash.h +++ /dev/null @@ -1,123 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// -// Deals with the fact that hash_map is not defined everywhere. - -#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ -#define GOOGLE_PROTOBUF_STUBS_HASH_H__ - -#include <string.h> -#include <google/protobuf/stubs/common.h> -#include "config.h" - -#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET) -#include HASH_MAP_H -#include HASH_SET_H -#else -// TODO(kenton): Deal with non-existence of hash_map somehow. Maybe emulate -// it with map? -#error "Your STL implementation lacks hash_map and/or hash_set." -#endif - -namespace google { -namespace protobuf { - -#ifdef _MSC_VER - -template <typename Key> -struct hash : public HASH_NAMESPACE::hash_compare<Key> { -}; - -// MSVC's hash_compare<const char*> hashes based on the string contents but -// compares based on the string pointer. WTF? -class CstringLess { - public: - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) < 0; - } -}; - -template <> -struct hash<const char*> - : public HASH_NAMESPACE::hash_compare<const char*, CstringLess> { -}; - -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = int > -class hash_map : public HASH_NAMESPACE::hash_map< - Key, Data, HashFcn> { -}; - -template <typename Key, - typename HashFcn = hash<Key>, - typename EqualKey = int > -class hash_set : public HASH_NAMESPACE::hash_set< - Key, HashFcn> { -}; - -#else - -template <typename Key> -struct hash : public HASH_NAMESPACE::hash<Key> { -}; - -template <typename Key> -struct hash<const Key*> { - inline size_t operator()(const Key* key) const { - return reinterpret_cast<size_t>(key); - } -}; - -template <> -struct hash<const char*> : public HASH_NAMESPACE::hash<const char*> { -}; - -template <typename Key, typename Data, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_map : public HASH_NAMESPACE::hash_map< - Key, Data, HashFcn, EqualKey> { -}; - -template <typename Key, - typename HashFcn = hash<Key>, - typename EqualKey = std::equal_to<Key> > -class hash_set : public HASH_NAMESPACE::hash_set< - Key, HashFcn, EqualKey> { -}; - -#endif - -template <> -struct hash<string> { - inline size_t operator()(const string& key) const { - return hash<const char*>()(key.c_str()); - } - - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; - inline size_t operator()(const string& a, const string& b) const { - return a < b; - } -}; - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__ diff --git a/src/google/protobuf/stubs/map-util.cc b/src/google/protobuf/stubs/map-util.cc deleted file mode 100644 index af05af30..00000000 --- a/src/google/protobuf/stubs/map-util.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/util/gtl/map-util.cc -// Author: Anton Carver - -#include <google/protobuf/stubs/map-util.h> - -namespace google { -namespace protobuf { - -// Template module. Nothing to see here. - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/map-util.h b/src/google/protobuf/stubs/map-util.h deleted file mode 100644 index ee8073fe..00000000 --- a/src/google/protobuf/stubs/map-util.h +++ /dev/null @@ -1,90 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/util/gtl/map-util.h -// Author: Anton Carver - -#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ -#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ - -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -// Perform a lookup in a map or hash_map. -// If the key is present a const pointer to the associated value is returned, -// otherwise a NULL pointer is returned. -template <class Collection> -const typename Collection::value_type::second_type* -FindOrNull(const Collection& collection, - const typename Collection::value_type::first_type& key) { - typename Collection::const_iterator it = collection.find(key); - if (it == collection.end()) { - return 0; - } - return &it->second; -} - -// Perform a lookup in a map or hash_map whose values are pointers. -// If the key is present a const pointer to the associated value is returned, -// otherwise a NULL pointer is returned. -// This function does not distinguish between a missing key and a key mapped -// to a NULL value. -template <class Collection> -const typename Collection::value_type::second_type -FindPtrOrNull(const Collection& collection, - const typename Collection::value_type::first_type& key) { - typename Collection::const_iterator it = collection.find(key); - if (it == collection.end()) { - return 0; - } - return it->second; -} - -// Change the value associated with a particular key in a map or hash_map. -// If the key is not present in the map the key and value are inserted, -// otherwise the value is updated to be a copy of the value provided. -// True indicates that an insert took place, false indicates an update. -template <class Collection, class Key, class Value> -bool InsertOrUpdate(Collection * const collection, - const Key& key, const Value& value) { - pair<typename Collection::iterator, bool> ret = - collection->insert(typename Collection::value_type(key, value)); - if (!ret.second) { - // update - ret.first->second = value; - return false; - } - return true; -} - -// Insert a new key and value into a map or hash_map. -// If the key is not present in the map the key and value are -// inserted, otherwise nothing happens. True indicates that an insert -// took place, false indicates the key was already present. -template <class Collection, class Key, class Value> -bool InsertIfNotPresent(Collection * const collection, - const Key& key, const Value& value) { - pair<typename Collection::iterator, bool> ret = - collection->insert(typename Collection::value_type(key, value)); - return ret.second; -} - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__ diff --git a/src/google/protobuf/stubs/stl_util-inl.cc b/src/google/protobuf/stubs/stl_util-inl.cc deleted file mode 100644 index 445c646e..00000000 --- a/src/google/protobuf/stubs/stl_util-inl.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/util/gtl/stl_util-inl.cc - -#include <google/protobuf/stubs/stl_util-inl.h> - -namespace google { -namespace protobuf { - -// Template module. Nothing to see here. - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/stl_util-inl.h b/src/google/protobuf/stubs/stl_util-inl.h deleted file mode 100644 index db079a77..00000000 --- a/src/google/protobuf/stubs/stl_util-inl.h +++ /dev/null @@ -1,107 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/util/gtl/stl_util-inl.h - -#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ -#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ - -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -// STLDeleteContainerPointers() -// For a range within a container of pointers, calls delete -// (non-array version) on these pointers. -// NOTE: for these three functions, we could just implement a DeleteObject -// functor and then call for_each() on the range and functor, but this -// requires us to pull in all of algorithm.h, which seems expensive. -// For hash_[multi]set, it is important that this deletes behind the iterator -// because the hash_set may call the hash function on the iterator when it is -// advanced, which could result in the hash function trying to deference a -// stale pointer. -template <class ForwardIterator> -void STLDeleteContainerPointers(ForwardIterator begin, - ForwardIterator end) { - while (begin != end) { - ForwardIterator temp = begin; - ++begin; - delete *temp; - } -} - -// Inside Google, this function implements a horrible, disgusting hack in which -// we reach into the string's private implementation and resize it without -// initializing the new bytes. In some cases doing this can significantly -// improve performance. However, since it's totally non-portable it has no -// place in open source code. Feel free to fill this function in with your -// own disgusting hack if you want the perf boost. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { - s->resize(new_size); -} - -// Return a mutable char* pointing to a string's internal buffer, -// which may not be null-terminated. Writing through this pointer will -// modify the string. -// -// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the -// next call to a string method that invalidates iterators. -// -// As of 2006-04, there is no standard-blessed way of getting a -// mutable reference to a string's internal buffer. However, issue 530 -// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) -// proposes this as the method. According to Matt Austern, this should -// already work on all current implementations. -inline char* string_as_array(string* str) { - // DO NOT USE const_cast<char*>(str->data())! See the unittest for why. - return str->empty() ? NULL : &*str->begin(); -} - -// STLDeleteElements() deletes all the elements in an STL container and clears -// the container. This function is suitable for use with a vector, set, -// hash_set, or any other STL container which defines sensible begin(), end(), -// and clear() methods. -// -// If container is NULL, this function is a no-op. -// -// As an alternative to calling STLDeleteElements() directly, consider -// ElementDeleter (defined below), which ensures that your container's elements -// are deleted when the ElementDeleter goes out of scope. -template <class T> -void STLDeleteElements(T *container) { - if (!container) return; - STLDeleteContainerPointers(container->begin(), container->end()); - container->clear(); -} - -// Given an STL container consisting of (key, value) pairs, STLDeleteValues -// deletes all the "value" components and clears the container. Does nothing -// in the case it's given a NULL pointer. - -template <class T> -void STLDeleteValues(T *v) { - if (!v) return; - for (typename T::iterator i = v->begin(); i != v->end(); ++i) { - delete i->second; - } - v->clear(); -} - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__ diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc deleted file mode 100644 index 07caaf76..00000000 --- a/src/google/protobuf/stubs/strutil.cc +++ /dev/null @@ -1,1121 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/strings/strutil.cc - -#include <google/protobuf/stubs/strutil.h> -#include <errno.h> -#include <float.h> // FLT_DIG and DBL_DIG -#include <limits> -#include <limits.h> - -#ifdef _WIN32 -// MSVC has only _snprintf, not snprintf. -// -// MinGW has both snprintf and _snprintf, but they appear to be different -// functions. The former is buggy. When invoked like so: -// char buffer[32]; -// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f); -// it prints "1.23000e+10". This is plainly wrong: %g should never print -// trailing zeros after the decimal point. For some reason this bug only -// occurs with some input values, not all. In any case, _snprintf does the -// right thing, so we use it. -#define snprintf _snprintf -#endif - -namespace google { -namespace protobuf { - -inline bool IsNaN(double value) { - // NaN is never equal to anything, even itself. - return value != value; -} - -// The definitions of these in ctype.h change based on locale. Since our -// string manipulation is all in relation to the protocol buffer and C++ -// languages, we always want to use the C locale. So, we re-define these -// exactly as we want them. -static bool isxdigit(char c) { - return ('0' <= c && c <= '9') || - ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F'); -} - -static bool isprint(char c) { - return c >= 0x20 && c <= 0x7E; -} - -// ---------------------------------------------------------------------- -// StripString -// Replaces any occurrence of the character 'remove' (or the characters -// in 'remove') with the character 'replacewith'. -// ---------------------------------------------------------------------- -void StripString(string* s, const char* remove, char replacewith) { - const char * str_start = s->c_str(); - const char * str = str_start; - for (str = strpbrk(str, remove); - str != NULL; - str = strpbrk(str + 1, remove)) { - (*s)[str - str_start] = replacewith; - } -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Replace the "old" pattern with the "new" pattern in a string, -// and append the result to "res". If replace_all is false, -// it only replaces the first instance of "old." -// ---------------------------------------------------------------------- - -void StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all, - string* res) { - if (oldsub.empty()) { - res->append(s); // if empty, append the given string. - return; - } - - string::size_type start_pos = 0; - string::size_type pos; - do { - pos = s.find(oldsub, start_pos); - if (pos == string::npos) { - break; - } - res->append(s, start_pos, pos - start_pos); - res->append(newsub); - start_pos = pos + oldsub.size(); // start searching again after the "old" - } while (replace_all); - res->append(s, start_pos, s.length() - start_pos); -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Give me a string and two patterns "old" and "new", and I replace -// the first instance of "old" in the string with "new", if it -// exists. If "global" is true; call this repeatedly until it -// fails. RETURN a new string, regardless of whether the replacement -// happened or not. -// ---------------------------------------------------------------------- - -string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all) { - string ret; - StringReplace(s, oldsub, newsub, replace_all, &ret); - return ret; -} - -// ---------------------------------------------------------------------- -// SplitStringUsing() -// Split a string using a character delimiter. Append the components -// to 'result'. -// -// Note: For multi-character delimiters, this routine will split on *ANY* of -// the characters in the string, not the entire string as a single delimiter. -// ---------------------------------------------------------------------- -template <typename ITR> -static inline -void SplitStringToIteratorUsing(const string& full, - const char* delim, - ITR& result) { - // Optimize the common case where delim is a single character. - if (delim[0] != '\0' && delim[1] == '\0') { - char c = delim[0]; - const char* p = full.data(); - const char* end = p + full.size(); - while (p != end) { - if (*p == c) { - ++p; - } else { - const char* start = p; - while (++p != end && *p != c); - *result++ = string(start, p - start); - } - } - return; - } - - string::size_type begin_index, end_index; - begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { - end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); - return; - } - *result++ = full.substr(begin_index, (end_index - begin_index)); - begin_index = full.find_first_not_of(delim, end_index); - } -} - -void SplitStringUsing(const string& full, - const char* delim, - vector<string>* result) { - back_insert_iterator< vector<string> > it(*result); - SplitStringToIteratorUsing(full, delim, it); -} - -// ---------------------------------------------------------------------- -// JoinStrings() -// This merges a vector of string components with delim inserted -// as separaters between components. -// -// ---------------------------------------------------------------------- -template <class ITERATOR> -static void JoinStringsIterator(const ITERATOR& start, - const ITERATOR& end, - const char* delim, - string* result) { - GOOGLE_CHECK(result != NULL); - result->clear(); - int delim_length = strlen(delim); - - // Precompute resulting length so we can reserve() memory in one shot. - int length = 0; - for (ITERATOR iter = start; iter != end; ++iter) { - if (iter != start) { - length += delim_length; - } - length += iter->size(); - } - result->reserve(length); - - // Now combine everything. - for (ITERATOR iter = start; iter != end; ++iter) { - if (iter != start) { - result->append(delim, delim_length); - } - result->append(iter->data(), iter->size()); - } -} - -void JoinStrings(const vector<string>& components, - const char* delim, - string * result) { - JoinStringsIterator(components.begin(), components.end(), delim, result); -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeSequences() -// This does all the unescaping that C does: \ooo, \r, \n, etc -// Returns length of resulting string. -// The implementation of \x parses any positive number of hex digits, -// but it is an error if the value requires more than 8 bits, and the -// result is truncated to 8 bits. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// ---------------------------------------------------------------------- - -#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7')) - -inline int hex_digit_to_int(char c) { - /* Assume ASCII. */ - assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61); - assert(isxdigit(c)); - int x = static_cast<unsigned char>(c); - if (x > '9') { - x += 9; - } - return x & 0xf; -} - -// Protocol buffers doesn't ever care about errors, but I don't want to remove -// the code. -#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false) - -int UnescapeCEscapeSequences(const char* source, char* dest) { - return UnescapeCEscapeSequences(source, dest, NULL); -} - -int UnescapeCEscapeSequences(const char* source, char* dest, - vector<string> *errors) { - GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented."; - - char* d = dest; - const char* p = source; - - // Small optimization for case where source = dest and there's no escaping - while ( p == d && *p != '\0' && *p != '\\' ) - p++, d++; - - while (*p != '\0') { - if (*p != '\\') { - *d++ = *p++; - } else { - switch ( *++p ) { // skip past the '\\' - case '\0': - LOG_STRING(ERROR, errors) << "String cannot end with \\"; - *d = '\0'; - return d - dest; // we're done with p - case 'a': *d++ = '\a'; break; - case 'b': *d++ = '\b'; break; - case 'f': *d++ = '\f'; break; - case 'n': *d++ = '\n'; break; - case 'r': *d++ = '\r'; break; - case 't': *d++ = '\t'; break; - case 'v': *d++ = '\v'; break; - case '\\': *d++ = '\\'; break; - case '?': *d++ = '\?'; break; // \? Who knew? - case '\'': *d++ = '\''; break; - case '"': *d++ = '\"'; break; - case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits - case '4': case '5': case '6': case '7': { - char ch = *p - '0'; - if ( IS_OCTAL_DIGIT(p[1]) ) - ch = ch * 8 + *++p - '0'; - if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice - ch = ch * 8 + *++p - '0'; // now points at last digit - *d++ = ch; - break; - } - case 'x': case 'X': { - if (!isxdigit(p[1])) { - if (p[1] == '\0') { - LOG_STRING(ERROR, errors) << "String cannot end with \\x"; - } else { - LOG_STRING(ERROR, errors) << - "\\x cannot be followed by non-hex digit: \\" << *p << p[1]; - } - break; - } - unsigned int ch = 0; - const char *hex_start = p; - while (isxdigit(p[1])) // arbitrarily many hex digits - ch = (ch << 4) + hex_digit_to_int(*++p); - if (ch > 0xFF) - LOG_STRING(ERROR, errors) << "Value of " << - "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; - *d++ = ch; - break; - } -#if 0 // TODO(kenton): Support \u and \U? Requires runetochar(). - case 'u': { - // \uhhhh => convert 4 hex digits to UTF-8 - char32 rune = 0; - const char *hex_start = p; - for (int i = 0; i < 4; ++i) { - if (isxdigit(p[1])) { // Look one char ahead. - rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. - } else { - LOG_STRING(ERROR, errors) - << "\\u must be followed by 4 hex digits: \\" - << string(hex_start, p+1-hex_start); - break; - } - } - d += runetochar(d, &rune); - break; - } - case 'U': { - // \Uhhhhhhhh => convert 8 hex digits to UTF-8 - char32 rune = 0; - const char *hex_start = p; - for (int i = 0; i < 8; ++i) { - if (isxdigit(p[1])) { // Look one char ahead. - // Don't change rune until we're sure this - // is within the Unicode limit, but do advance p. - char32 newrune = (rune << 4) + hex_digit_to_int(*++p); - if (newrune > 0x10FFFF) { - LOG_STRING(ERROR, errors) - << "Value of \\" - << string(hex_start, p + 1 - hex_start) - << " exceeds Unicode limit (0x10FFFF)"; - break; - } else { - rune = newrune; - } - } else { - LOG_STRING(ERROR, errors) - << "\\U must be followed by 8 hex digits: \\" - << string(hex_start, p+1-hex_start); - break; - } - } - d += runetochar(d, &rune); - break; - } -#endif - default: - LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p; - } - p++; // read past letter we escaped - } - } - *d = '\0'; - return d - dest; -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeString() -// This does the same thing as UnescapeCEscapeSequences, but creates -// a new string. The caller does not need to worry about allocating -// a dest buffer. This should be used for non performance critical -// tasks such as printing debug messages. It is safe for src and dest -// to be the same. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// -// In the first and second calls, the length of dest is returned. In the -// the third call, the new string is returned. -// ---------------------------------------------------------------------- -int UnescapeCEscapeString(const string& src, string* dest) { - return UnescapeCEscapeString(src, dest, NULL); -} - -int UnescapeCEscapeString(const string& src, string* dest, - vector<string> *errors) { - scoped_array<char> unescaped(new char[src.size() + 1]); - int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); - GOOGLE_CHECK(dest); - dest->assign(unescaped.get(), len); - return len; -} - -string UnescapeCEscapeString(const string& src) { - scoped_array<char> unescaped(new char[src.size() + 1]); - int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL); - return string(unescaped.get(), len); -} - -// ---------------------------------------------------------------------- -// CEscapeString() -// CHexEscapeString() -// Copies 'src' to 'dest', escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses -// hexadecimal rather than octal sequences. -// Returns the number of bytes written to 'dest' (not including the \0) -// or -1 if there was insufficient space. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -static int CEscapeInternal(const char* src, int src_len, char* dest, - int dest_len, bool use_hex) { - const char* src_end = src + src_len; - int used = 0; - bool last_hex_escape = false; // true if last output char was \xNN - - for (; src < src_end; src++) { - if (dest_len - used < 2) // Need space for two letter escape - return -1; - - bool is_hex_escape = false; - switch (*src) { - case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; - case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; - case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; - case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; - case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; - case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; - default: - // Note that if we emit \xNN and the src character after that is a hex - // digit then that digit must be escaped too to prevent it being - // interpreted as part of the character code by C. - if (!isprint(*src) || (last_hex_escape && isxdigit(*src))) { - if (dest_len - used < 4) // need space for 4 letter escape - return -1; - sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), - static_cast<uint8>(*src)); - is_hex_escape = use_hex; - used += 4; - } else { - dest[used++] = *src; break; - } - } - last_hex_escape = is_hex_escape; - } - - if (dest_len - used < 1) // make sure that there is room for \0 - return -1; - - dest[used] = '\0'; // doesn't count towards return value though - return used; -} - -int CEscapeString(const char* src, int src_len, char* dest, int dest_len) { - return CEscapeInternal(src, src_len, dest, dest_len, false); -} - -// ---------------------------------------------------------------------- -// CEscape() -// CHexEscape() -// Copies 'src' to result, escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. The 'Hex' version -// hexadecimal rather than octal sequences. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -string CEscape(const string& src) { - const int dest_length = src.size() * 4 + 1; // Maximum possible expansion - scoped_array<char> dest(new char[dest_length]); - const int len = CEscapeInternal(src.data(), src.size(), - dest.get(), dest_length, false); - GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); -} - -// ---------------------------------------------------------------------- -// strto32_adaptor() -// strtou32_adaptor() -// Implementation of strto[u]l replacements that have identical -// overflow and underflow characteristics for both ILP-32 and LP-64 -// platforms, including errno preservation in error-free calls. -// ---------------------------------------------------------------------- - -int32 strto32_adaptor(const char *nptr, char **endptr, int base) { - const int saved_errno = errno; - errno = 0; - const long result = strtol(nptr, endptr, base); - if (errno == ERANGE && result == LONG_MIN) { - return kint32min; - } else if (errno == ERANGE && result == LONG_MAX) { - return kint32max; - } else if (errno == 0 && result < kint32min) { - errno = ERANGE; - return kint32min; - } else if (errno == 0 && result > kint32max) { - errno = ERANGE; - return kint32max; - } - if (errno == 0) - errno = saved_errno; - return static_cast<int32>(result); -} - -uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { - const int saved_errno = errno; - errno = 0; - const unsigned long result = strtoul(nptr, endptr, base); - if (errno == ERANGE && result == ULONG_MAX) { - return kuint32max; - } else if (errno == 0 && result > kuint32max) { - errno = ERANGE; - return kuint32max; - } - if (errno == 0) - errno = saved_errno; - return static_cast<uint32>(result); -} - -// ---------------------------------------------------------------------- -// FastIntToBuffer() -// FastInt64ToBuffer() -// FastHexToBuffer() -// FastHex64ToBuffer() -// FastHex32ToBuffer() -// ---------------------------------------------------------------------- - -// Offset into buffer where FastInt64ToBuffer places the end of string -// null character. Also used by FastInt64ToBufferLeft. -static const int kFastInt64ToBufferOffset = 21; - -char *FastInt64ToBuffer(int64 i, char* buffer) { - // We could collapse the positive and negative sections, but that - // would be slightly slower for positive numbers... - // 22 bytes is enough to store -2**64, -18446744073709551616. - char* p = buffer + kFastInt64ToBufferOffset; - *p-- = '\0'; - if (i >= 0) { - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; - } else { - // On different platforms, % and / have different behaviors for - // negative numbers, so we need to jump through hoops to make sure - // we don't divide negative numbers. - if (i > -10) { - i = -i; - *p-- = '0' + i; - *p = '-'; - return p; - } else { - // Make sure we aren't at MIN_INT, in which case we can't say i = -i - i = i + 10; - i = -i; - *p-- = '0' + i % 10; - // Undo what we did a moment ago - i = i / 10 + 1; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - *p = '-'; - return p; - } - } -} - -// Offset into buffer where FastInt32ToBuffer places the end of string -// null character. Also used by FastInt32ToBufferLeft -static const int kFastInt32ToBufferOffset = 11; - -// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the -// compiler to generate 32 bit arithmetic instructions. It's much faster, at -// least with 32 bit binaries. -char *FastInt32ToBuffer(int32 i, char* buffer) { - // We could collapse the positive and negative sections, but that - // would be slightly slower for positive numbers... - // 12 bytes is enough to store -2**32, -4294967296. - char* p = buffer + kFastInt32ToBufferOffset; - *p-- = '\0'; - if (i >= 0) { - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - return p + 1; - } else { - // On different platforms, % and / have different behaviors for - // negative numbers, so we need to jump through hoops to make sure - // we don't divide negative numbers. - if (i > -10) { - i = -i; - *p-- = '0' + i; - *p = '-'; - return p; - } else { - // Make sure we aren't at MIN_INT, in which case we can't say i = -i - i = i + 10; - i = -i; - *p-- = '0' + i % 10; - // Undo what we did a moment ago - i = i / 10 + 1; - do { - *p-- = '0' + i % 10; - i /= 10; - } while (i > 0); - *p = '-'; - return p; - } - } -} - -char *FastHexToBuffer(int i, char* buffer) { - GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i; - - static const char *hexdigits = "0123456789abcdef"; - char *p = buffer + 21; - *p-- = '\0'; - do { - *p-- = hexdigits[i & 15]; // mod by 16 - i >>= 4; // divide by 16 - } while (i > 0); - return p + 1; -} - -char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) { - static const char *hexdigits = "0123456789abcdef"; - buffer[num_byte] = '\0'; - for (int i = num_byte - 1; i >= 0; i--) { - buffer[i] = hexdigits[uint32(value) & 0xf]; - value >>= 4; - } - return buffer; -} - -char *FastHex64ToBuffer(uint64 value, char* buffer) { - return InternalFastHexToBuffer(value, buffer, 16); -} - -char *FastHex32ToBuffer(uint32 value, char* buffer) { - return InternalFastHexToBuffer(value, buffer, 8); -} - -static inline char* PlaceNum(char* p, int num, char prev_sep) { - *p-- = '0' + num % 10; - *p-- = '0' + num / 10; - *p-- = prev_sep; - return p; -} - -// ---------------------------------------------------------------------- -// FastInt32ToBufferLeft() -// FastUInt32ToBufferLeft() -// FastInt64ToBufferLeft() -// FastUInt64ToBufferLeft() -// -// Like the Fast*ToBuffer() functions above, these are intended for speed. -// Unlike the Fast*ToBuffer() functions, however, these functions write -// their output to the beginning of the buffer (hence the name, as the -// output is left-aligned). The caller is responsible for ensuring that -// the buffer has enough space to hold the output. -// -// Returns a pointer to the end of the string (i.e. the null character -// terminating the string). -// ---------------------------------------------------------------------- - -static const char two_ASCII_digits[100][2] = { - {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'}, - {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'}, - {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'}, - {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'}, - {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'}, - {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'}, - {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'}, - {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'}, - {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'}, - {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'}, - {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'}, - {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'}, - {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'}, - {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'}, - {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'}, - {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'}, - {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'}, - {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'}, - {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'}, - {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'} -}; - -char* FastUInt32ToBufferLeft(uint32 u, char* buffer) { - int digits; - const char *ASCII_digits = NULL; - // The idea of this implementation is to trim the number of divides to as few - // as possible by using multiplication and subtraction rather than mod (%), - // and by outputting two digits at a time rather than one. - // The huge-number case is first, in the hopes that the compiler will output - // that case in one branch-free block of code, and only output conditional - // branches into it from below. - if (u >= 1000000000) { // >= 1,000,000,000 - digits = u / 100000000; // 100,000,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt100_000_000: - u -= digits * 100000000; // 100,000,000 -lt100_000_000: - digits = u / 1000000; // 1,000,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt1_000_000: - u -= digits * 1000000; // 1,000,000 -lt1_000_000: - digits = u / 10000; // 10,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt10_000: - u -= digits * 10000; // 10,000 -lt10_000: - digits = u / 100; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -sublt100: - u -= digits * 100; -lt100: - digits = u; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; -done: - *buffer = 0; - return buffer; - } - - if (u < 100) { - digits = u; - if (u >= 10) goto lt100; - *buffer++ = '0' + digits; - goto done; - } - if (u < 10000) { // 10,000 - if (u >= 1000) goto lt10_000; - digits = u / 100; - *buffer++ = '0' + digits; - goto sublt100; - } - if (u < 1000000) { // 1,000,000 - if (u >= 100000) goto lt1_000_000; - digits = u / 10000; // 10,000 - *buffer++ = '0' + digits; - goto sublt10_000; - } - if (u < 100000000) { // 100,000,000 - if (u >= 10000000) goto lt100_000_000; - digits = u / 1000000; // 1,000,000 - *buffer++ = '0' + digits; - goto sublt1_000_000; - } - // we already know that u < 1,000,000,000 - digits = u / 100000000; // 100,000,000 - *buffer++ = '0' + digits; - goto sublt100_000_000; -} - -char* FastInt32ToBufferLeft(int32 i, char* buffer) { - uint32 u = i; - if (i < 0) { - *buffer++ = '-'; - u = -i; - } - return FastUInt32ToBufferLeft(u, buffer); -} - -char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) { - int digits; - const char *ASCII_digits = NULL; - - uint32 u = static_cast<uint32>(u64); - if (u == u64) return FastUInt32ToBufferLeft(u, buffer); - - uint64 top_11_digits = u64 / 1000000000; - buffer = FastUInt64ToBufferLeft(top_11_digits, buffer); - u = u64 - (top_11_digits * 1000000000); - - digits = u / 10000000; // 10,000,000 - GOOGLE_DCHECK_LT(digits, 100); - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 10000000; // 10,000,000 - digits = u / 100000; // 100,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 100000; // 100,000 - digits = u / 1000; // 1,000 - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 1000; // 1,000 - digits = u / 10; - ASCII_digits = two_ASCII_digits[digits]; - buffer[0] = ASCII_digits[0]; - buffer[1] = ASCII_digits[1]; - buffer += 2; - u -= digits * 10; - digits = u; - *buffer++ = '0' + digits; - *buffer = 0; - return buffer; -} - -char* FastInt64ToBufferLeft(int64 i, char* buffer) { - uint64 u = i; - if (i < 0) { - *buffer++ = '-'; - u = -i; - } - return FastUInt64ToBufferLeft(u, buffer); -} - -// ---------------------------------------------------------------------- -// SimpleItoa() -// Description: converts an integer to a string. -// -// Return value: string -// ---------------------------------------------------------------------- - -string SimpleItoa(int i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned int i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -string SimpleItoa(long i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned long i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -string SimpleItoa(long long i) { - char buffer[kFastToBufferSize]; - return (sizeof(i) == 4) ? - FastInt32ToBuffer(i, buffer) : - FastInt64ToBuffer(i, buffer); -} - -string SimpleItoa(unsigned long long i) { - char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); -} - -// ---------------------------------------------------------------------- -// SimpleDtoa() -// SimpleFtoa() -// DoubleToBuffer() -// FloatToBuffer() -// We want to print the value without losing precision, but we also do -// not want to print more digits than necessary. This turns out to be -// trickier than it sounds. Numbers like 0.2 cannot be represented -// exactly in binary. If we print 0.2 with a very large precision, -// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167". -// On the other hand, if we set the precision too low, we lose -// significant digits when printing numbers that actually need them. -// It turns out there is no precision value that does the right thing -// for all numbers. -// -// Our strategy is to first try printing with a precision that is never -// over-precise, then parse the result with strtod() to see if it -// matches. If not, we print again with a precision that will always -// give a precise result, but may use more digits than necessary. -// -// An arguably better strategy would be to use the algorithm described -// in "How to Print Floating-Point Numbers Accurately" by Steele & -// White, e.g. as implemented by David M. Gay's dtoa(). It turns out, -// however, that the following implementation is about as fast as -// DMG's code. Furthermore, DMG's code locks mutexes, which means it -// will not scale well on multi-core machines. DMG's code is slightly -// more accurate (in that it will never use more digits than -// necessary), but this is probably irrelevant for most users. -// -// Rob Pike and Ken Thompson also have an implementation of dtoa() in -// third_party/fmt/fltfmt.cc. Their implementation is similar to this -// one in that it makes guesses and then uses strtod() to check them. -// Their implementation is faster because they use their own code to -// generate the digits in the first place rather than use snprintf(), -// thus avoiding format string parsing overhead. However, this makes -// it considerably more complicated than the following implementation, -// and it is embedded in a larger library. If speed turns out to be -// an issue, we could re-implement this in terms of their -// implementation. -// ---------------------------------------------------------------------- - -string SimpleDtoa(double value) { - char buffer[kDoubleToBufferSize]; - return DoubleToBuffer(value, buffer); -} - -string SimpleFtoa(float value) { - char buffer[kFloatToBufferSize]; - return FloatToBuffer(value, buffer); -} - -static inline bool IsValidFloatChar(char c) { - return ('0' <= c && c <= '9') || - c == 'e' || c == 'E' || - c == '+' || c == '-'; -} - -void DelocalizeRadix(char* buffer) { - // Fast check: if the buffer has a normal decimal point, assume no - // translation is needed. - if (strchr(buffer, '.') != NULL) return; - - // Find the first unknown character. - while (IsValidFloatChar(*buffer)) ++buffer; - - if (*buffer == '\0') { - // No radix character found. - return; - } - - // We are now pointing at the locale-specific radix character. Replace it - // with '.'. - *buffer = '.'; - ++buffer; - - if (!IsValidFloatChar(*buffer) && *buffer != '\0') { - // It appears the radix was a multi-byte character. We need to remove the - // extra bytes. - char* target = buffer; - do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); - memmove(target, buffer, strlen(buffer) + 1); - } -} - -char* DoubleToBuffer(double value, char* buffer) { - // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all - // platforms these days. Just in case some system exists where DBL_DIG - // is significantly larger -- and risks overflowing our buffer -- we have - // this assert. - GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); - - if (value == numeric_limits<double>::infinity()) { - strcpy(buffer, "inf"); - return buffer; - } else if (value == -numeric_limits<double>::infinity()) { - strcpy(buffer, "-inf"); - return buffer; - } else if (IsNaN(value)) { - strcpy(buffer, "nan"); - return buffer; - } - - int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); - - // The snprintf should never overflow because the buffer is significantly - // larger than the precision we asked for. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); - - // We need to make parsed_value volatile in order to force the compiler to - // write it out to the stack. Otherwise, it may keep the value in a - // register, and if it does that, it may keep it as a long double instead - // of a double. This long double may have extra bits that make it compare - // unequal to "value" even though it would be exactly equal if it were - // truncated to a double. - volatile double parsed_value = strtod(buffer, NULL); - if (parsed_value != value) { - int snprintf_result = - snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); - - // Should never overflow; see above. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); - } - - DelocalizeRadix(buffer); - return buffer; -} - -bool safe_strtof(const char* str, float* value) { - char* endptr; - errno = 0; // errno only gets set on errors -#ifdef _WIN32 // has no strtof() - *value = strtod(str, &endptr); -#else - *value = strtof(str, &endptr); -#endif - return *str != 0 && *endptr == 0 && errno == 0; -} - -char* FloatToBuffer(float value, char* buffer) { - // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all - // platforms these days. Just in case some system exists where FLT_DIG - // is significantly larger -- and risks overflowing our buffer -- we have - // this assert. - GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); - - if (value == numeric_limits<double>::infinity()) { - strcpy(buffer, "inf"); - return buffer; - } else if (value == -numeric_limits<double>::infinity()) { - strcpy(buffer, "-inf"); - return buffer; - } else if (IsNaN(value)) { - strcpy(buffer, "nan"); - return buffer; - } - - int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); - - // The snprintf should never overflow because the buffer is significantly - // larger than the precision we asked for. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); - - float parsed_value; - if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { - int snprintf_result = - snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); - - // Should never overflow; see above. - GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); - } - - DelocalizeRadix(buffer); - return buffer; -} - -// ---------------------------------------------------------------------- -// NoLocaleStrtod() -// This code will make you cry. -// ---------------------------------------------------------------------- - -// Returns a string identical to *input except that the character pointed to -// by radix_pos (which should be '.') is replaced with the locale-specific -// radix character. -string LocalizeRadix(const char* input, const char* radix_pos) { - // Determine the locale-specific radix character by calling sprintf() to - // print the number 1.5, then stripping off the digits. As far as I can - // tell, this is the only portable, thread-safe way to get the C library - // to divuldge the locale's radix character. No, localeconv() is NOT - // thread-safe. - char temp[16]; - int size = sprintf(temp, "%.1f", 1.5); - GOOGLE_CHECK_EQ(temp[0], '1'); - GOOGLE_CHECK_EQ(temp[size-1], '5'); - GOOGLE_CHECK_LE(size, 6); - - // Now replace the '.' in the input with it. - string result; - result.reserve(strlen(input) + size - 3); - result.append(input, radix_pos); - result.append(temp + 1, size - 2); - result.append(radix_pos + 1); - return result; -} - -double NoLocaleStrtod(const char* text, char** original_endptr) { - // We cannot simply set the locale to "C" temporarily with setlocale() - // as this is not thread-safe. Instead, we try to parse in the current - // locale first. If parsing stops at a '.' character, then this is a - // pretty good hint that we're actually in some other locale in which - // '.' is not the radix character. - - char* temp_endptr; - double result = strtod(text, &temp_endptr); - if (original_endptr != NULL) *original_endptr = temp_endptr; - if (*temp_endptr != '.') return result; - - // Parsing halted on a '.'. Perhaps we're in a different locale? Let's - // try to replace the '.' with a locale-specific radix character and - // try again. - string localized = LocalizeRadix(text, temp_endptr); - const char* localized_cstr = localized.c_str(); - char* localized_endptr; - result = strtod(localized_cstr, &localized_endptr); - if ((localized_endptr - localized_cstr) > - (temp_endptr - text)) { - // This attempt got further, so replacing the decimal must have helped. - // Update original_endptr to point at the right location. - if (original_endptr != NULL) { - // size_diff is non-zero if the localized radix has multiple bytes. - int size_diff = localized.size() - strlen(text); - // const_cast is necessary to match the strtod() interface. - *original_endptr = const_cast<char*>( - text + (localized_endptr - localized_cstr - size_diff)); - } - } - - return result; -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h deleted file mode 100644 index ff919617..00000000 --- a/src/google/protobuf/stubs/strutil.h +++ /dev/null @@ -1,432 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// from google3/strings/strutil.h - -#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ -#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - -#include <vector> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -#ifdef _MSC_VER -#define strtoll _strtoi64 -#define strtoull _strtoui64 -#endif - -// ---------------------------------------------------------------------- -// ascii_isalnum() -// Check if an ASCII character is alphanumeric. We can't use ctype's -// isalnum() because it is affected by locale. This function is applied -// to identifiers in the protocol buffer language, not to natural-language -// strings, so locale should not be taken into account. -// ascii_isdigit() -// Like above, but only accepts digits. -// ---------------------------------------------------------------------- - -inline bool ascii_isalnum(char c) { - return ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9'); -} - -inline bool ascii_isdigit(char c) { - return ('0' <= c && c <= '9'); -} - -// ---------------------------------------------------------------------- -// HasPrefixString() -// Check if a string begins with a given prefix. -// StripPrefixString() -// Given a string and a putative prefix, returns the string minus the -// prefix string if the prefix matches, otherwise the original -// string. -// ---------------------------------------------------------------------- -inline bool HasPrefixString(const string& str, - const string& prefix) { - return str.size() >= prefix.size() && - str.compare(0, prefix.size(), prefix) == 0; -} - -inline string StripPrefixString(const string& str, const string& prefix) { - if (HasPrefixString(str, prefix)) { - return str.substr(prefix.size()); - } else { - return str; - } -} - -// ---------------------------------------------------------------------- -// HasSuffixString() -// Return true if str ends in suffix. -// StripSuffixString() -// Given a string and a putative suffix, returns the string minus the -// suffix string if the suffix matches, otherwise the original -// string. -// ---------------------------------------------------------------------- -inline bool HasSuffixString(const string& str, - const string& suffix) { - return str.size() >= suffix.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; -} - -inline string StripSuffixString(const string& str, const string& suffix) { - if (HasSuffixString(str, suffix)) { - return str.substr(0, str.size() - suffix.size()); - } else { - return str; - } -} - -// ---------------------------------------------------------------------- -// StripString -// Replaces any occurrence of the character 'remove' (or the characters -// in 'remove') with the character 'replacewith'. -// Good for keeping html characters or protocol characters (\t) out -// of places where they might cause a problem. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove, - char replacewith); - -// ---------------------------------------------------------------------- -// LowerString() -// UpperString() -// Convert the characters in "s" to lowercase or uppercase. ASCII-only: -// these functions intentionally ignore locale because they are applied to -// identifiers used in the Protocol Buffer language, not to natural-language -// strings. -// ---------------------------------------------------------------------- - -inline void LowerString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { - // tolower() changes based on locale. We don't want this! - if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; - } -} - -inline void UpperString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { - // toupper() changes based on locale. We don't want this! - if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; - } -} - -// ---------------------------------------------------------------------- -// StringReplace() -// Give me a string and two patterns "old" and "new", and I replace -// the first instance of "old" in the string with "new", if it -// exists. RETURN a new string, regardless of whether the replacement -// happened or not. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); - -// ---------------------------------------------------------------------- -// SplitStringUsing() -// Split a string using a character delimiter. Append the components -// to 'result'. If there are consecutive delimiters, this function skips -// over all of them. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, - vector<string>* res); - -// ---------------------------------------------------------------------- -// JoinStrings() -// These methods concatenate a vector of strings into a C++ string, using -// the C-string "delim" as a separator between components. There are two -// flavors of the function, one flavor returns the concatenated string, -// another takes a pointer to the target string. In the latter case the -// target string is cleared and overwritten. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components, - const char* delim, string* result); - -inline string JoinStrings(const vector<string>& components, - const char* delim) { - string result; - JoinStrings(components, delim, &result); - return result; -} - -// ---------------------------------------------------------------------- -// UnescapeCEscapeSequences() -// Copies "source" to "dest", rewriting C-style escape sequences -// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII -// equivalents. "dest" must be sufficiently large to hold all -// the characters in the rewritten string (i.e. at least as large -// as strlen(source) + 1 should be safe, since the replacements -// are always shorter than the original escaped sequences). It's -// safe for source and dest to be the same. RETURNS the length -// of dest. -// -// It allows hex sequences \xhh, or generally \xhhhhh with an -// arbitrary number of hex digits, but all of them together must -// specify a value of a single byte (e.g. \x0045 is equivalent -// to \x45, and \x1234 is erroneous). -// -// It also allows escape sequences of the form \uhhhh (exactly four -// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight -// hex digits, upper or lower case) to specify a Unicode code -// point. The dest array will contain the UTF8-encoded version of -// that code-point (e.g., if source contains \u2019, then dest will -// contain the three bytes 0xE2, 0x80, and 0x99). For the inverse -// transformation, use UniLib::UTF8EscapeString -// (util/utf8/unilib.h), not CEscapeString. -// -// Errors: In the first form of the call, errors are reported with -// LOG(ERROR). The same is true for the second form of the call if -// the pointer to the string vector is NULL; otherwise, error -// messages are stored in the vector. In either case, the effect on -// the dest array is not defined, but rest of the source will be -// processed. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - vector<string> *errors); - -// ---------------------------------------------------------------------- -// UnescapeCEscapeString() -// This does the same thing as UnescapeCEscapeSequences, but creates -// a new string. The caller does not need to worry about allocating -// a dest buffer. This should be used for non performance critical -// tasks such as printing debug messages. It is safe for src and dest -// to be the same. -// -// The second call stores its errors in a supplied string vector. -// If the string vector pointer is NULL, it reports the errors with LOG(). -// -// In the first and second calls, the length of dest is returned. In the -// the third call, the new string is returned. -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - vector<string> *errors); -LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); - -// ---------------------------------------------------------------------- -// CEscapeString() -// Copies 'src' to 'dest', escaping dangerous characters using -// C-style escape sequences. This is very useful for preparing query -// flags. 'src' and 'dest' should not overlap. -// Returns the number of bytes written to 'dest' (not including the \0) -// or -1 if there was insufficient space. -// -// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len, - char* dest, int dest_len); - -// ---------------------------------------------------------------------- -// CEscape() -// More convenient form of CEscapeString: returns result as a "string". -// This version is slower than CEscapeString() because it does more -// allocation. However, it is much more convenient to use in -// non-speed-critical code like logging messages etc. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string CEscape(const string& src); - -// ---------------------------------------------------------------------- -// strto32() -// strtou32() -// strto64() -// strtou64() -// Architecture-neutral plug compatible replacements for strtol() and -// strtoul(). Long's have different lengths on ILP-32 and LP-64 -// platforms, so using these is safer, from the point of view of -// overflow behavior, than using the standard libc functions. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr, - int base); -LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr, - int base); - -inline int32 strto32(const char *nptr, char **endptr, int base) { - if (sizeof(int32) == sizeof(long)) - return strtol(nptr, endptr, base); - else - return strto32_adaptor(nptr, endptr, base); -} - -inline uint32 strtou32(const char *nptr, char **endptr, int base) { - if (sizeof(uint32) == sizeof(unsigned long)) - return strtoul(nptr, endptr, base); - else - return strtou32_adaptor(nptr, endptr, base); -} - -// For now, long long is 64-bit on all the platforms we care about, so these -// functions can simply pass the call to strto[u]ll. -inline int64 strto64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long), - sizeof_int64_is_not_sizeof_long_long); - return strtoll(nptr, endptr, base); -} - -inline uint64 strtou64(const char *nptr, char **endptr, int base) { - GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), - sizeof_uint64_is_not_sizeof_long_long); - return strtoull(nptr, endptr, base); -} - -// ---------------------------------------------------------------------- -// FastIntToBuffer() -// FastHexToBuffer() -// FastHex64ToBuffer() -// FastHex32ToBuffer() -// FastTimeToBuffer() -// These are intended for speed. FastIntToBuffer() assumes the -// integer is non-negative. FastHexToBuffer() puts output in -// hex rather than decimal. FastTimeToBuffer() puts the output -// into RFC822 format. -// -// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format, -// padded to exactly 16 bytes (plus one byte for '\0') -// -// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format, -// padded to exactly 8 bytes (plus one byte for '\0') -// -// All functions take the output buffer as an arg. -// They all return a pointer to the beginning of the output, -// which may not be the beginning of the input buffer. -// ---------------------------------------------------------------------- - -// Suggested buffer size for FastToBuffer functions. Also works with -// DoubleToBuffer() and FloatToBuffer(). -static const int kFastToBufferSize = 32; - -LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer); -char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below -char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below -LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer); -LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer); - -// at least 22 bytes long -inline char* FastIntToBuffer(int i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); -} -inline char* FastUIntToBuffer(unsigned int i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); -} -inline char* FastLongToBuffer(long i, char* buffer) { - return (sizeof(i) == 4 ? - FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer)); -} -inline char* FastULongToBuffer(unsigned long i, char* buffer) { - return (sizeof(i) == 4 ? - FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer)); -} - -// ---------------------------------------------------------------------- -// FastInt32ToBufferLeft() -// FastUInt32ToBufferLeft() -// FastInt64ToBufferLeft() -// FastUInt64ToBufferLeft() -// -// Like the Fast*ToBuffer() functions above, these are intended for speed. -// Unlike the Fast*ToBuffer() functions, however, these functions write -// their output to the beginning of the buffer (hence the name, as the -// output is left-aligned). The caller is responsible for ensuring that -// the buffer has enough space to hold the output. -// -// Returns a pointer to the end of the string (i.e. the null character -// terminating the string). -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer); -LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer); - -// Just define these in terms of the above. -inline char* FastUInt32ToBuffer(uint32 i, char* buffer) { - FastUInt32ToBufferLeft(i, buffer); - return buffer; -} -inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { - FastUInt64ToBufferLeft(i, buffer); - return buffer; -} - -// ---------------------------------------------------------------------- -// SimpleItoa() -// Description: converts an integer to a string. -// -// Return value: string -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string SimpleItoa(int i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i); -LIBPROTOBUF_EXPORT string SimpleItoa(long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i); -LIBPROTOBUF_EXPORT string SimpleItoa(long long i); -LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i); - -// ---------------------------------------------------------------------- -// SimpleDtoa() -// SimpleFtoa() -// DoubleToBuffer() -// FloatToBuffer() -// Description: converts a double or float to a string which, if -// passed to NoLocaleStrtod(), will produce the exact same original double -// (except in case of NaN; all NaNs are considered the same value). -// We try to keep the string short but it's not guaranteed to be as -// short as possible. -// -// DoubleToBuffer() and FloatToBuffer() write the text to the given -// buffer and return it. The buffer must be at least -// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize -// bytes for floats. kFastToBufferSize is also guaranteed to be large -// enough to hold either. -// -// Return value: string -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT string SimpleDtoa(double value); -LIBPROTOBUF_EXPORT string SimpleFtoa(float value); - -LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); -LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); - -// In practice, doubles should never need more than 24 bytes and floats -// should never need more than 14 (including null terminators), but we -// overestimate to be safe. -static const int kDoubleToBufferSize = 32; -static const int kFloatToBufferSize = 24; - -// ---------------------------------------------------------------------- -// NoLocaleStrtod() -// Exactly like strtod(), except it always behaves as if in the "C" -// locale (i.e. decimal points must be '.'s). -// ---------------------------------------------------------------------- - -LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr); - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ - - diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc deleted file mode 100644 index 58ffd32e..00000000 --- a/src/google/protobuf/stubs/strutil_unittest.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <google/protobuf/stubs/strutil.h> - -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace { - -// TODO(kenton): Copy strutil tests from google3? - -TEST(StringUtilityTest, ImmuneToLocales) { - // Remember the old locale. - char* old_locale_cstr = setlocale(LC_NUMERIC, NULL); - ASSERT_TRUE(old_locale_cstr != NULL); - string old_locale = old_locale_cstr; - - // Set the locale to "C". - ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL); - - EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); - EXPECT_EQ("1.5", SimpleDtoa(1.5)); - EXPECT_EQ("1.5", SimpleFtoa(1.5)); - - // Verify that the endptr is set correctly even if not all text was parsed. - const char* text = "1.5f"; - char* endptr; - EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); - EXPECT_EQ(3, endptr - text); - - if (setlocale(LC_NUMERIC, "es_ES") == NULL && - setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) { - // Some systems may not have the desired locale available. - GOOGLE_LOG(WARNING) - << "Couldn't set locale to es_ES. Skipping this test."; - } else { - EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL)); - EXPECT_EQ("1.5", SimpleDtoa(1.5)); - EXPECT_EQ("1.5", SimpleFtoa(1.5)); - EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr)); - EXPECT_EQ(3, endptr - text); - } - - // Return to original locale. - setlocale(LC_NUMERIC, old_locale.c_str()); -} - -} // anonymous namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc deleted file mode 100644 index 340be5e8..00000000 --- a/src/google/protobuf/stubs/substitute.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) - -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/stl_util-inl.h> - -namespace google { -namespace protobuf { -namespace strings { - -using internal::SubstituteArg; - -// Returns the number of args in arg_array which were passed explicitly -// to Substitute(). -static int CountSubstituteArgs(const SubstituteArg* const* args_array) { - int count = 0; - while (args_array[count] != NULL && args_array[count]->size() != -1) { - ++count; - } - return count; -} - -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - string result; - SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8, arg9); - return result; -} - -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - const SubstituteArg* const args_array[] = { - &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL - }; - - // Determine total size needed. - int size = 0; - for (int i = 0; format[i] != '\0'; i++) { - if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - int index = format[i+1] - '0'; - if (args_array[index]->size() == -1) { - GOOGLE_LOG(DFATAL) - << "strings::Substitute format string invalid: asked for \"$" - << index << "\", but only " << CountSubstituteArgs(args_array) - << " args were given. Full format string was: \"" - << CEscape(format) << "\"."; - return; - } - size += args_array[index]->size(); - ++i; // Skip next char. - } else if (format[i+1] == '$') { - ++size; - ++i; // Skip next char. - } else { - GOOGLE_LOG(DFATAL) - << "Invalid strings::Substitute() format string: \"" - << CEscape(format) << "\"."; - return; - } - } else { - ++size; - } - } - - if (size == 0) return; - - // Build the string. - int original_size = output->size(); - STLStringResizeUninitialized(output, original_size + size); - char* target = string_as_array(output) + original_size; - for (int i = 0; format[i] != '\0'; i++) { - if (format[i] == '$') { - if (ascii_isdigit(format[i+1])) { - const SubstituteArg* src = args_array[format[i+1] - '0']; - memcpy(target, src->data(), src->size()); - target += src->size(); - ++i; // Skip next char. - } else if (format[i+1] == '$') { - *target++ = '$'; - ++i; // Skip next char. - } - } else { - *target++ = format[i]; - } - } - - GOOGLE_DCHECK_EQ(target - output->data(), output->size()); -} - -} // namespace strings -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h deleted file mode 100644 index 143e4828..00000000 --- a/src/google/protobuf/stubs/substitute.h +++ /dev/null @@ -1,156 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// from google3/strings/substitute.h - -#include <string> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> - -#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ -#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ - -namespace google { -namespace protobuf { -namespace strings { - -// ---------------------------------------------------------------------- -// strings::Substitute() -// strings::SubstituteAndAppend() -// Kind of like StringPrintf, but different. -// -// Example: -// string GetMessage(string first_name, string last_name, int age) { -// return strings::Substitute("My name is $0 $1 and I am $2 years old.", -// first_name, last_name, age); -// } -// -// Differences from StringPrintf: -// * The format string does not identify the types of arguments. -// Instead, the magic of C++ deals with this for us. See below -// for a list of accepted types. -// * Substitutions in the format string are identified by a '$' -// followed by a digit. So, you can use arguments out-of-order and -// use the same argument multiple times. -// * It's much faster than StringPrintf. -// -// Supported types: -// * Strings (const char*, const string&) -// * Note that this means you do not have to add .c_str() to all of -// your strings. In fact, you shouldn't; it will be slower. -// * int32, int64, uint32, uint64: Formatted using SimpleItoa(). -// * float, double: Formatted using SimpleFtoa() and SimpleDtoa(). -// * bool: Printed as "true" or "false". -// -// SubstituteAndAppend() is like Substitute() but appends the result to -// *output. Example: -// -// string str; -// strings::SubstituteAndAppend(&str, -// "My name is $0 $1 and I am $2 years old.", -// first_name, last_name, age); -// -// Substitute() is significantly faster than StringPrintf(). For very -// large strings, it may be orders of magnitude faster. -// ---------------------------------------------------------------------- - -namespace internal { // Implementation details. - -class SubstituteArg { - public: - inline SubstituteArg(const char* value) - : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} - - // Indicates that no argument was given. - inline explicit SubstituteArg() - : text_(NULL), size_(-1) {} - - // Primitives - // We don't overload for signed and unsigned char because if people are - // explicitly declaring their chars as signed or unsigned then they are - // probably actually using them as 8-bit integers and would probably - // prefer an integer representation. But, we don't really know. So, we - // make the caller decide what to do. - inline SubstituteArg(char value) - : text_(scratch_), size_(1) { scratch_[0] = value; } - inline SubstituteArg(short value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned short value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(int value) - : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned int value) - : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long value) - : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long value) - : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(long long value) - : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(unsigned long long value) - : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(float value) - : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(double value) - : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} - inline SubstituteArg(bool value) - : text_(value ? "true" : "false"), size_(strlen(text_)) {} - - inline const char* data() const { return text_; } - inline int size() const { return size_; } - - private: - const char* text_; - int size_; - char scratch_[kFastToBufferSize]; -}; - -} // namespace internal - -LIBPROTOBUF_EXPORT string Substitute( - const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); - -LIBPROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); - -} // namespace strings -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc deleted file mode 100644 index 59d98736..00000000 --- a/src/google/protobuf/test_util.cc +++ /dev/null @@ -1,1920 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/test_util.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/message.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -void TestUtil::SetAllFields(unittest::TestAllTypes* message) { - message->set_optional_int32 (101); - message->set_optional_int64 (102); - message->set_optional_uint32 (103); - message->set_optional_uint64 (104); - message->set_optional_sint32 (105); - message->set_optional_sint64 (106); - message->set_optional_fixed32 (107); - message->set_optional_fixed64 (108); - message->set_optional_sfixed32(109); - message->set_optional_sfixed64(110); - message->set_optional_float (111); - message->set_optional_double (112); - message->set_optional_bool (true); - message->set_optional_string ("115"); - message->set_optional_bytes ("116"); - - message->mutable_optionalgroup ()->set_a(117); - message->mutable_optional_nested_message ()->set_bb(118); - message->mutable_optional_foreign_message()->set_c(119); - message->mutable_optional_import_message ()->set_d(120); - - message->set_optional_nested_enum (unittest::TestAllTypes::BAZ); - message->set_optional_foreign_enum(unittest::FOREIGN_BAZ ); - message->set_optional_import_enum (unittest_import::IMPORT_BAZ); - - // StringPiece and Cord fields are only accessible via reflection in the - // open source release; see comments in compiler/cpp/string_field.cc. - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("optional_string_piece"), - "124"); - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("optional_cord"), - "125"); - - // ----------------------------------------------------------------- - - message->add_repeated_int32 (201); - message->add_repeated_int64 (202); - message->add_repeated_uint32 (203); - message->add_repeated_uint64 (204); - message->add_repeated_sint32 (205); - message->add_repeated_sint64 (206); - message->add_repeated_fixed32 (207); - message->add_repeated_fixed64 (208); - message->add_repeated_sfixed32(209); - message->add_repeated_sfixed64(210); - message->add_repeated_float (211); - message->add_repeated_double (212); - message->add_repeated_bool (true); - message->add_repeated_string ("215"); - message->add_repeated_bytes ("216"); - - message->add_repeatedgroup ()->set_a(217); - message->add_repeated_nested_message ()->set_bb(218); - message->add_repeated_foreign_message()->set_c(219); - message->add_repeated_import_message ()->set_d(220); - - message->add_repeated_nested_enum (unittest::TestAllTypes::BAR); - message->add_repeated_foreign_enum(unittest::FOREIGN_BAR ); - message->add_repeated_import_enum (unittest_import::IMPORT_BAR); - - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - "224"); - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - "225"); - - // Add a second one of each field. - message->add_repeated_int32 (301); - message->add_repeated_int64 (302); - message->add_repeated_uint32 (303); - message->add_repeated_uint64 (304); - message->add_repeated_sint32 (305); - message->add_repeated_sint64 (306); - message->add_repeated_fixed32 (307); - message->add_repeated_fixed64 (308); - message->add_repeated_sfixed32(309); - message->add_repeated_sfixed64(310); - message->add_repeated_float (311); - message->add_repeated_double (312); - message->add_repeated_bool (false); - message->add_repeated_string ("315"); - message->add_repeated_bytes ("316"); - - message->add_repeatedgroup ()->set_a(317); - message->add_repeated_nested_message ()->set_bb(318); - message->add_repeated_foreign_message()->set_c(319); - message->add_repeated_import_message ()->set_d(320); - - message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ); - message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ ); - message->add_repeated_import_enum (unittest_import::IMPORT_BAZ); - - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - "324"); - message->GetReflection()->AddString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - "325"); - - // ----------------------------------------------------------------- - - message->set_default_int32 (401); - message->set_default_int64 (402); - message->set_default_uint32 (403); - message->set_default_uint64 (404); - message->set_default_sint32 (405); - message->set_default_sint64 (406); - message->set_default_fixed32 (407); - message->set_default_fixed64 (408); - message->set_default_sfixed32(409); - message->set_default_sfixed64(410); - message->set_default_float (411); - message->set_default_double (412); - message->set_default_bool (false); - message->set_default_string ("415"); - message->set_default_bytes ("416"); - - message->set_default_nested_enum (unittest::TestAllTypes::FOO); - message->set_default_foreign_enum(unittest::FOREIGN_FOO ); - message->set_default_import_enum (unittest_import::IMPORT_FOO); - - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("default_string_piece"), - "424"); - message->GetReflection()->SetString( - message, - message->GetDescriptor()->FindFieldByName("default_cord"), - "425"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) { - message->set_repeated_int32 (1, 501); - message->set_repeated_int64 (1, 502); - message->set_repeated_uint32 (1, 503); - message->set_repeated_uint64 (1, 504); - message->set_repeated_sint32 (1, 505); - message->set_repeated_sint64 (1, 506); - message->set_repeated_fixed32 (1, 507); - message->set_repeated_fixed64 (1, 508); - message->set_repeated_sfixed32(1, 509); - message->set_repeated_sfixed64(1, 510); - message->set_repeated_float (1, 511); - message->set_repeated_double (1, 512); - message->set_repeated_bool (1, true); - message->set_repeated_string (1, "515"); - message->set_repeated_bytes (1, "516"); - - message->mutable_repeatedgroup (1)->set_a(517); - message->mutable_repeated_nested_message (1)->set_bb(518); - message->mutable_repeated_foreign_message(1)->set_c(519); - message->mutable_repeated_import_message (1)->set_d(520); - - message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO); - message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO ); - message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO); - - message->GetReflection()->SetRepeatedString( - message, - message->GetDescriptor()->FindFieldByName("repeated_string_piece"), - 1, "424"); - message->GetReflection()->SetRepeatedString( - message, - message->GetDescriptor()->FindFieldByName("repeated_cord"), - 1, "425"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) { - EXPECT_TRUE(message.has_optional_int32 ()); - EXPECT_TRUE(message.has_optional_int64 ()); - EXPECT_TRUE(message.has_optional_uint32 ()); - EXPECT_TRUE(message.has_optional_uint64 ()); - EXPECT_TRUE(message.has_optional_sint32 ()); - EXPECT_TRUE(message.has_optional_sint64 ()); - EXPECT_TRUE(message.has_optional_fixed32 ()); - EXPECT_TRUE(message.has_optional_fixed64 ()); - EXPECT_TRUE(message.has_optional_sfixed32()); - EXPECT_TRUE(message.has_optional_sfixed64()); - EXPECT_TRUE(message.has_optional_float ()); - EXPECT_TRUE(message.has_optional_double ()); - EXPECT_TRUE(message.has_optional_bool ()); - EXPECT_TRUE(message.has_optional_string ()); - EXPECT_TRUE(message.has_optional_bytes ()); - - EXPECT_TRUE(message.has_optionalgroup ()); - EXPECT_TRUE(message.has_optional_nested_message ()); - EXPECT_TRUE(message.has_optional_foreign_message()); - EXPECT_TRUE(message.has_optional_import_message ()); - - EXPECT_TRUE(message.optionalgroup ().has_a()); - EXPECT_TRUE(message.optional_nested_message ().has_bb()); - EXPECT_TRUE(message.optional_foreign_message().has_c()); - EXPECT_TRUE(message.optional_import_message ().has_d()); - - EXPECT_TRUE(message.has_optional_nested_enum ()); - EXPECT_TRUE(message.has_optional_foreign_enum()); - EXPECT_TRUE(message.has_optional_import_enum ()); - - EXPECT_TRUE(message.has_optional_string_piece()); - EXPECT_TRUE(message.has_optional_cord()); - - EXPECT_EQ(101 , message.optional_int32 ()); - EXPECT_EQ(102 , message.optional_int64 ()); - EXPECT_EQ(103 , message.optional_uint32 ()); - EXPECT_EQ(104 , message.optional_uint64 ()); - EXPECT_EQ(105 , message.optional_sint32 ()); - EXPECT_EQ(106 , message.optional_sint64 ()); - EXPECT_EQ(107 , message.optional_fixed32 ()); - EXPECT_EQ(108 , message.optional_fixed64 ()); - EXPECT_EQ(109 , message.optional_sfixed32()); - EXPECT_EQ(110 , message.optional_sfixed64()); - EXPECT_EQ(111 , message.optional_float ()); - EXPECT_EQ(112 , message.optional_double ()); - EXPECT_EQ(true , message.optional_bool ()); - EXPECT_EQ("115", message.optional_string ()); - EXPECT_EQ("116", message.optional_bytes ()); - - EXPECT_EQ(117, message.optionalgroup ().a()); - EXPECT_EQ(118, message.optional_nested_message ().bb()); - EXPECT_EQ(119, message.optional_foreign_message().c()); - EXPECT_EQ(120, message.optional_import_message ().d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.optional_import_enum ()); - - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - - ASSERT_EQ(2, message.repeated_string_piece_size()); - ASSERT_EQ(2, message.repeated_cord_size()); - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); - - EXPECT_EQ(301 , message.repeated_int32 (1)); - EXPECT_EQ(302 , message.repeated_int64 (1)); - EXPECT_EQ(303 , message.repeated_uint32 (1)); - EXPECT_EQ(304 , message.repeated_uint64 (1)); - EXPECT_EQ(305 , message.repeated_sint32 (1)); - EXPECT_EQ(306 , message.repeated_sint64 (1)); - EXPECT_EQ(307 , message.repeated_fixed32 (1)); - EXPECT_EQ(308 , message.repeated_fixed64 (1)); - EXPECT_EQ(309 , message.repeated_sfixed32(1)); - EXPECT_EQ(310 , message.repeated_sfixed64(1)); - EXPECT_EQ(311 , message.repeated_float (1)); - EXPECT_EQ(312 , message.repeated_double (1)); - EXPECT_EQ(false, message.repeated_bool (1)); - EXPECT_EQ("315", message.repeated_string (1)); - EXPECT_EQ("316", message.repeated_bytes (1)); - - EXPECT_EQ(317, message.repeatedgroup (1).a()); - EXPECT_EQ(318, message.repeated_nested_message (1).bb()); - EXPECT_EQ(319, message.repeated_foreign_message(1).c()); - EXPECT_EQ(320, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (1)); - - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.has_default_int32 ()); - EXPECT_TRUE(message.has_default_int64 ()); - EXPECT_TRUE(message.has_default_uint32 ()); - EXPECT_TRUE(message.has_default_uint64 ()); - EXPECT_TRUE(message.has_default_sint32 ()); - EXPECT_TRUE(message.has_default_sint64 ()); - EXPECT_TRUE(message.has_default_fixed32 ()); - EXPECT_TRUE(message.has_default_fixed64 ()); - EXPECT_TRUE(message.has_default_sfixed32()); - EXPECT_TRUE(message.has_default_sfixed64()); - EXPECT_TRUE(message.has_default_float ()); - EXPECT_TRUE(message.has_default_double ()); - EXPECT_TRUE(message.has_default_bool ()); - EXPECT_TRUE(message.has_default_string ()); - EXPECT_TRUE(message.has_default_bytes ()); - - EXPECT_TRUE(message.has_default_nested_enum ()); - EXPECT_TRUE(message.has_default_foreign_enum()); - EXPECT_TRUE(message.has_default_import_enum ()); - - - EXPECT_EQ(401 , message.default_int32 ()); - EXPECT_EQ(402 , message.default_int64 ()); - EXPECT_EQ(403 , message.default_uint32 ()); - EXPECT_EQ(404 , message.default_uint64 ()); - EXPECT_EQ(405 , message.default_sint32 ()); - EXPECT_EQ(406 , message.default_sint64 ()); - EXPECT_EQ(407 , message.default_fixed32 ()); - EXPECT_EQ(408 , message.default_fixed64 ()); - EXPECT_EQ(409 , message.default_sfixed32()); - EXPECT_EQ(410 , message.default_sfixed64()); - EXPECT_EQ(411 , message.default_float ()); - EXPECT_EQ(412 , message.default_double ()); - EXPECT_EQ(false, message.default_bool ()); - EXPECT_EQ("415", message.default_string ()); - EXPECT_EQ("416", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_FOO , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectClear(const unittest::TestAllTypes& message) { - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.has_optional_int32 ()); - EXPECT_FALSE(message.has_optional_int64 ()); - EXPECT_FALSE(message.has_optional_uint32 ()); - EXPECT_FALSE(message.has_optional_uint64 ()); - EXPECT_FALSE(message.has_optional_sint32 ()); - EXPECT_FALSE(message.has_optional_sint64 ()); - EXPECT_FALSE(message.has_optional_fixed32 ()); - EXPECT_FALSE(message.has_optional_fixed64 ()); - EXPECT_FALSE(message.has_optional_sfixed32()); - EXPECT_FALSE(message.has_optional_sfixed64()); - EXPECT_FALSE(message.has_optional_float ()); - EXPECT_FALSE(message.has_optional_double ()); - EXPECT_FALSE(message.has_optional_bool ()); - EXPECT_FALSE(message.has_optional_string ()); - EXPECT_FALSE(message.has_optional_bytes ()); - - EXPECT_FALSE(message.has_optionalgroup ()); - EXPECT_FALSE(message.has_optional_nested_message ()); - EXPECT_FALSE(message.has_optional_foreign_message()); - EXPECT_FALSE(message.has_optional_import_message ()); - - EXPECT_FALSE(message.has_optional_nested_enum ()); - EXPECT_FALSE(message.has_optional_foreign_enum()); - EXPECT_FALSE(message.has_optional_import_enum ()); - - EXPECT_FALSE(message.has_optional_string_piece()); - EXPECT_FALSE(message.has_optional_cord()); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.optional_int32 ()); - EXPECT_EQ(0 , message.optional_int64 ()); - EXPECT_EQ(0 , message.optional_uint32 ()); - EXPECT_EQ(0 , message.optional_uint64 ()); - EXPECT_EQ(0 , message.optional_sint32 ()); - EXPECT_EQ(0 , message.optional_sint64 ()); - EXPECT_EQ(0 , message.optional_fixed32 ()); - EXPECT_EQ(0 , message.optional_fixed64 ()); - EXPECT_EQ(0 , message.optional_sfixed32()); - EXPECT_EQ(0 , message.optional_sfixed64()); - EXPECT_EQ(0 , message.optional_float ()); - EXPECT_EQ(0 , message.optional_double ()); - EXPECT_EQ(false, message.optional_bool ()); - EXPECT_EQ("" , message.optional_string ()); - EXPECT_EQ("" , message.optional_bytes ()); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.optionalgroup ().has_a()); - EXPECT_FALSE(message.optional_nested_message ().has_bb()); - EXPECT_FALSE(message.optional_foreign_message().has_c()); - EXPECT_FALSE(message.optional_import_message ().has_d()); - - EXPECT_EQ(0, message.optionalgroup ().a()); - EXPECT_EQ(0, message.optional_nested_message ().bb()); - EXPECT_EQ(0, message.optional_foreign_message().c()); - EXPECT_EQ(0, message.optional_import_message ().d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_FOO , message.optional_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.optional_import_enum ()); - - - // Repeated fields are empty. - EXPECT_EQ(0, message.repeated_int32_size ()); - EXPECT_EQ(0, message.repeated_int64_size ()); - EXPECT_EQ(0, message.repeated_uint32_size ()); - EXPECT_EQ(0, message.repeated_uint64_size ()); - EXPECT_EQ(0, message.repeated_sint32_size ()); - EXPECT_EQ(0, message.repeated_sint64_size ()); - EXPECT_EQ(0, message.repeated_fixed32_size ()); - EXPECT_EQ(0, message.repeated_fixed64_size ()); - EXPECT_EQ(0, message.repeated_sfixed32_size()); - EXPECT_EQ(0, message.repeated_sfixed64_size()); - EXPECT_EQ(0, message.repeated_float_size ()); - EXPECT_EQ(0, message.repeated_double_size ()); - EXPECT_EQ(0, message.repeated_bool_size ()); - EXPECT_EQ(0, message.repeated_string_size ()); - EXPECT_EQ(0, message.repeated_bytes_size ()); - - EXPECT_EQ(0, message.repeatedgroup_size ()); - EXPECT_EQ(0, message.repeated_nested_message_size ()); - EXPECT_EQ(0, message.repeated_foreign_message_size()); - EXPECT_EQ(0, message.repeated_import_message_size ()); - EXPECT_EQ(0, message.repeated_nested_enum_size ()); - EXPECT_EQ(0, message.repeated_foreign_enum_size ()); - EXPECT_EQ(0, message.repeated_import_enum_size ()); - - EXPECT_EQ(0, message.repeated_string_piece_size()); - EXPECT_EQ(0, message.repeated_cord_size()); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.has_default_int32 ()); - EXPECT_FALSE(message.has_default_int64 ()); - EXPECT_FALSE(message.has_default_uint32 ()); - EXPECT_FALSE(message.has_default_uint64 ()); - EXPECT_FALSE(message.has_default_sint32 ()); - EXPECT_FALSE(message.has_default_sint64 ()); - EXPECT_FALSE(message.has_default_fixed32 ()); - EXPECT_FALSE(message.has_default_fixed64 ()); - EXPECT_FALSE(message.has_default_sfixed32()); - EXPECT_FALSE(message.has_default_sfixed64()); - EXPECT_FALSE(message.has_default_float ()); - EXPECT_FALSE(message.has_default_double ()); - EXPECT_FALSE(message.has_default_bool ()); - EXPECT_FALSE(message.has_default_string ()); - EXPECT_FALSE(message.has_default_bytes ()); - - EXPECT_FALSE(message.has_default_nested_enum ()); - EXPECT_FALSE(message.has_default_foreign_enum()); - EXPECT_FALSE(message.has_default_import_enum ()); - - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.default_int32 ()); - EXPECT_EQ( 42 , message.default_int64 ()); - EXPECT_EQ( 43 , message.default_uint32 ()); - EXPECT_EQ( 44 , message.default_uint64 ()); - EXPECT_EQ(-45 , message.default_sint32 ()); - EXPECT_EQ( 46 , message.default_sint64 ()); - EXPECT_EQ( 47 , message.default_fixed32 ()); - EXPECT_EQ( 48 , message.default_fixed64 ()); - EXPECT_EQ( 49 , message.default_sfixed32()); - EXPECT_EQ(-50 , message.default_sfixed64()); - EXPECT_EQ( 51.5 , message.default_float ()); - EXPECT_EQ( 52e3 , message.default_double ()); - EXPECT_EQ(true , message.default_bool ()); - EXPECT_EQ("hello", message.default_string ()); - EXPECT_EQ("world", message.default_bytes ()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.default_nested_enum ()); - EXPECT_EQ(unittest::FOREIGN_BAR , message.default_foreign_enum()); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ()); - -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectRepeatedFieldsModified( - const unittest::TestAllTypes& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.repeated_int32_size ()); - ASSERT_EQ(2, message.repeated_int64_size ()); - ASSERT_EQ(2, message.repeated_uint32_size ()); - ASSERT_EQ(2, message.repeated_uint64_size ()); - ASSERT_EQ(2, message.repeated_sint32_size ()); - ASSERT_EQ(2, message.repeated_sint64_size ()); - ASSERT_EQ(2, message.repeated_fixed32_size ()); - ASSERT_EQ(2, message.repeated_fixed64_size ()); - ASSERT_EQ(2, message.repeated_sfixed32_size()); - ASSERT_EQ(2, message.repeated_sfixed64_size()); - ASSERT_EQ(2, message.repeated_float_size ()); - ASSERT_EQ(2, message.repeated_double_size ()); - ASSERT_EQ(2, message.repeated_bool_size ()); - ASSERT_EQ(2, message.repeated_string_size ()); - ASSERT_EQ(2, message.repeated_bytes_size ()); - - ASSERT_EQ(2, message.repeatedgroup_size ()); - ASSERT_EQ(2, message.repeated_nested_message_size ()); - ASSERT_EQ(2, message.repeated_foreign_message_size()); - ASSERT_EQ(2, message.repeated_import_message_size ()); - ASSERT_EQ(2, message.repeated_nested_enum_size ()); - ASSERT_EQ(2, message.repeated_foreign_enum_size ()); - ASSERT_EQ(2, message.repeated_import_enum_size ()); - - ASSERT_EQ(2, message.repeated_string_piece_size()); - ASSERT_EQ(2, message.repeated_cord_size()); - - EXPECT_EQ(201 , message.repeated_int32 (0)); - EXPECT_EQ(202 , message.repeated_int64 (0)); - EXPECT_EQ(203 , message.repeated_uint32 (0)); - EXPECT_EQ(204 , message.repeated_uint64 (0)); - EXPECT_EQ(205 , message.repeated_sint32 (0)); - EXPECT_EQ(206 , message.repeated_sint64 (0)); - EXPECT_EQ(207 , message.repeated_fixed32 (0)); - EXPECT_EQ(208 , message.repeated_fixed64 (0)); - EXPECT_EQ(209 , message.repeated_sfixed32(0)); - EXPECT_EQ(210 , message.repeated_sfixed64(0)); - EXPECT_EQ(211 , message.repeated_float (0)); - EXPECT_EQ(212 , message.repeated_double (0)); - EXPECT_EQ(true , message.repeated_bool (0)); - EXPECT_EQ("215", message.repeated_string (0)); - EXPECT_EQ("216", message.repeated_bytes (0)); - - EXPECT_EQ(217, message.repeatedgroup (0).a()); - EXPECT_EQ(218, message.repeated_nested_message (0).bb()); - EXPECT_EQ(219, message.repeated_foreign_message(0).c()); - EXPECT_EQ(220, message.repeated_import_message (0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0)); - - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.repeated_int32 (1)); - EXPECT_EQ(502 , message.repeated_int64 (1)); - EXPECT_EQ(503 , message.repeated_uint32 (1)); - EXPECT_EQ(504 , message.repeated_uint64 (1)); - EXPECT_EQ(505 , message.repeated_sint32 (1)); - EXPECT_EQ(506 , message.repeated_sint64 (1)); - EXPECT_EQ(507 , message.repeated_fixed32 (1)); - EXPECT_EQ(508 , message.repeated_fixed64 (1)); - EXPECT_EQ(509 , message.repeated_sfixed32(1)); - EXPECT_EQ(510 , message.repeated_sfixed64(1)); - EXPECT_EQ(511 , message.repeated_float (1)); - EXPECT_EQ(512 , message.repeated_double (1)); - EXPECT_EQ(true , message.repeated_bool (1)); - EXPECT_EQ("515", message.repeated_string (1)); - EXPECT_EQ("516", message.repeated_bytes (1)); - - EXPECT_EQ(517, message.repeatedgroup (1).a()); - EXPECT_EQ(518, message.repeated_nested_message (1).bb()); - EXPECT_EQ(519, message.repeated_foreign_message(1).c()); - EXPECT_EQ(520, message.repeated_import_message (1).d()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1)); - EXPECT_EQ(unittest::FOREIGN_FOO , message.repeated_foreign_enum(1)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.repeated_import_enum (1)); - -} - -// =================================================================== -// Extensions -// -// All this code is exactly equivalent to the above code except that it's -// manipulating extension fields instead of normal ones. -// -// I gave up on the 80-char limit here. Sorry. - -void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) { - message->SetExtension(unittest::optional_int32_extension , 101); - message->SetExtension(unittest::optional_int64_extension , 102); - message->SetExtension(unittest::optional_uint32_extension , 103); - message->SetExtension(unittest::optional_uint64_extension , 104); - message->SetExtension(unittest::optional_sint32_extension , 105); - message->SetExtension(unittest::optional_sint64_extension , 106); - message->SetExtension(unittest::optional_fixed32_extension , 107); - message->SetExtension(unittest::optional_fixed64_extension , 108); - message->SetExtension(unittest::optional_sfixed32_extension, 109); - message->SetExtension(unittest::optional_sfixed64_extension, 110); - message->SetExtension(unittest::optional_float_extension , 111); - message->SetExtension(unittest::optional_double_extension , 112); - message->SetExtension(unittest::optional_bool_extension , true); - message->SetExtension(unittest::optional_string_extension , "115"); - message->SetExtension(unittest::optional_bytes_extension , "116"); - - message->MutableExtension(unittest::optionalgroup_extension )->set_a(117); - message->MutableExtension(unittest::optional_nested_message_extension )->set_bb(118); - message->MutableExtension(unittest::optional_foreign_message_extension)->set_c(119); - message->MutableExtension(unittest::optional_import_message_extension )->set_d(120); - - message->SetExtension(unittest::optional_nested_enum_extension , unittest::TestAllTypes::BAZ); - message->SetExtension(unittest::optional_foreign_enum_extension, unittest::FOREIGN_BAZ ); - message->SetExtension(unittest::optional_import_enum_extension , unittest_import::IMPORT_BAZ); - - message->SetExtension(unittest::optional_string_piece_extension, "124"); - message->SetExtension(unittest::optional_cord_extension, "125"); - - // ----------------------------------------------------------------- - - message->AddExtension(unittest::repeated_int32_extension , 201); - message->AddExtension(unittest::repeated_int64_extension , 202); - message->AddExtension(unittest::repeated_uint32_extension , 203); - message->AddExtension(unittest::repeated_uint64_extension , 204); - message->AddExtension(unittest::repeated_sint32_extension , 205); - message->AddExtension(unittest::repeated_sint64_extension , 206); - message->AddExtension(unittest::repeated_fixed32_extension , 207); - message->AddExtension(unittest::repeated_fixed64_extension , 208); - message->AddExtension(unittest::repeated_sfixed32_extension, 209); - message->AddExtension(unittest::repeated_sfixed64_extension, 210); - message->AddExtension(unittest::repeated_float_extension , 211); - message->AddExtension(unittest::repeated_double_extension , 212); - message->AddExtension(unittest::repeated_bool_extension , true); - message->AddExtension(unittest::repeated_string_extension , "215"); - message->AddExtension(unittest::repeated_bytes_extension , "216"); - - message->AddExtension(unittest::repeatedgroup_extension )->set_a(217); - message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218); - message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219); - message->AddExtension(unittest::repeated_import_message_extension )->set_d(220); - - message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR); - message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR ); - message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAR); - - message->AddExtension(unittest::repeated_string_piece_extension, "224"); - message->AddExtension(unittest::repeated_cord_extension, "225"); - - // Add a second one of each field. - message->AddExtension(unittest::repeated_int32_extension , 301); - message->AddExtension(unittest::repeated_int64_extension , 302); - message->AddExtension(unittest::repeated_uint32_extension , 303); - message->AddExtension(unittest::repeated_uint64_extension , 304); - message->AddExtension(unittest::repeated_sint32_extension , 305); - message->AddExtension(unittest::repeated_sint64_extension , 306); - message->AddExtension(unittest::repeated_fixed32_extension , 307); - message->AddExtension(unittest::repeated_fixed64_extension , 308); - message->AddExtension(unittest::repeated_sfixed32_extension, 309); - message->AddExtension(unittest::repeated_sfixed64_extension, 310); - message->AddExtension(unittest::repeated_float_extension , 311); - message->AddExtension(unittest::repeated_double_extension , 312); - message->AddExtension(unittest::repeated_bool_extension , false); - message->AddExtension(unittest::repeated_string_extension , "315"); - message->AddExtension(unittest::repeated_bytes_extension , "316"); - - message->AddExtension(unittest::repeatedgroup_extension )->set_a(317); - message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318); - message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319); - message->AddExtension(unittest::repeated_import_message_extension )->set_d(320); - - message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ); - message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ ); - message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAZ); - - message->AddExtension(unittest::repeated_string_piece_extension, "324"); - message->AddExtension(unittest::repeated_cord_extension, "325"); - - // ----------------------------------------------------------------- - - message->SetExtension(unittest::default_int32_extension , 401); - message->SetExtension(unittest::default_int64_extension , 402); - message->SetExtension(unittest::default_uint32_extension , 403); - message->SetExtension(unittest::default_uint64_extension , 404); - message->SetExtension(unittest::default_sint32_extension , 405); - message->SetExtension(unittest::default_sint64_extension , 406); - message->SetExtension(unittest::default_fixed32_extension , 407); - message->SetExtension(unittest::default_fixed64_extension , 408); - message->SetExtension(unittest::default_sfixed32_extension, 409); - message->SetExtension(unittest::default_sfixed64_extension, 410); - message->SetExtension(unittest::default_float_extension , 411); - message->SetExtension(unittest::default_double_extension , 412); - message->SetExtension(unittest::default_bool_extension , false); - message->SetExtension(unittest::default_string_extension , "415"); - message->SetExtension(unittest::default_bytes_extension , "416"); - - message->SetExtension(unittest::default_nested_enum_extension , unittest::TestAllTypes::FOO); - message->SetExtension(unittest::default_foreign_enum_extension, unittest::FOREIGN_FOO ); - message->SetExtension(unittest::default_import_enum_extension , unittest_import::IMPORT_FOO); - - message->SetExtension(unittest::default_string_piece_extension, "424"); - message->SetExtension(unittest::default_cord_extension, "425"); -} - -// ------------------------------------------------------------------- - -void TestUtil::SetAllFieldsAndExtensions( - unittest::TestFieldOrderings* message) { - GOOGLE_CHECK(message); - message->set_my_int(1); - message->set_my_string("foo"); - message->set_my_float(1.0); - message->SetExtension(unittest::my_extension_int, 23); - message->SetExtension(unittest::my_extension_string, "bar"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) { - message->SetExtension(unittest::repeated_int32_extension , 1, 501); - message->SetExtension(unittest::repeated_int64_extension , 1, 502); - message->SetExtension(unittest::repeated_uint32_extension , 1, 503); - message->SetExtension(unittest::repeated_uint64_extension , 1, 504); - message->SetExtension(unittest::repeated_sint32_extension , 1, 505); - message->SetExtension(unittest::repeated_sint64_extension , 1, 506); - message->SetExtension(unittest::repeated_fixed32_extension , 1, 507); - message->SetExtension(unittest::repeated_fixed64_extension , 1, 508); - message->SetExtension(unittest::repeated_sfixed32_extension, 1, 509); - message->SetExtension(unittest::repeated_sfixed64_extension, 1, 510); - message->SetExtension(unittest::repeated_float_extension , 1, 511); - message->SetExtension(unittest::repeated_double_extension , 1, 512); - message->SetExtension(unittest::repeated_bool_extension , 1, true); - message->SetExtension(unittest::repeated_string_extension , 1, "515"); - message->SetExtension(unittest::repeated_bytes_extension , 1, "516"); - - message->MutableExtension(unittest::repeatedgroup_extension , 1)->set_a(517); - message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518); - message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519); - message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520); - - message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO); - message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO ); - message->SetExtension(unittest::repeated_import_enum_extension , 1, unittest_import::IMPORT_FOO); - - message->SetExtension(unittest::repeated_string_piece_extension, 1, "524"); - message->SetExtension(unittest::repeated_cord_extension, 1, "525"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllExtensionsSet( - const unittest::TestAllExtensions& message) { - EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension )); - - EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); - EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); - EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension).has_c()); - EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); - - EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension )); - EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::optional_string_piece_extension)); - EXPECT_TRUE(message.HasExtension(unittest::optional_cord_extension)); - - EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension )); - EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension )); - EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension )); - EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension )); - EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension )); - EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension )); - EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension )); - EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension )); - EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension)); - EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension)); - EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension )); - EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension )); - EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension )); - EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension )); - EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension )); - - EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension ).a()); - EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension ).bb()); - EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension).c()); - EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension ).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::optional_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::optional_import_enum_extension )); - - EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension)); - EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension)); - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); - - EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 1)); - EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 1)); - EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 1)); - EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 1)); - EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 1)); - EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 1)); - EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); - EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); - EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); - EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); - EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 1)); - EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 1)); - EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 1)); - EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 1)); - EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 1)); - - EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); - EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); - EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); - EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); - EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 1)); - - EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 1)); - EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 1)); - - // ----------------------------------------------------------------- - - EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_float_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_double_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_string_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension )); - EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension )); - - EXPECT_TRUE(message.HasExtension(unittest::default_string_piece_extension)); - EXPECT_TRUE(message.HasExtension(unittest::default_cord_extension)); - - EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension )); - EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension )); - EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension )); - EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension )); - EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension )); - EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension )); - EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension )); - EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension )); - EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension)); - EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension)); - EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension )); - EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension )); - EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension )); - EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension )); - EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension )); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::default_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::default_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::default_import_enum_extension )); - - EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension)); - EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectExtensionsClear( - const unittest::TestAllExtensions& message) { - string serialized; - ASSERT_TRUE(message.SerializeToString(&serialized)); - EXPECT_EQ("", serialized); - EXPECT_EQ(0, message.ByteSize()); - - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension )); - EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::optional_string_piece_extension)); - EXPECT_FALSE(message.HasExtension(unittest::optional_cord_extension)); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension)); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension )); - EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension )); - EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension )); - EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension )); - - // Embedded messages should also be clear. - EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a()); - EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb()); - EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension).has_c()); - EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d()); - - EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension).c()); - EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d()); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::optional_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::optional_import_enum_extension )); - - EXPECT_EQ("", message.GetExtension(unittest::optional_string_piece_extension)); - EXPECT_EQ("", message.GetExtension(unittest::optional_cord_extension)); - - // Repeated fields are empty. - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension )); - - EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_piece_extension)); - EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_cord_extension)); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_float_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_double_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_string_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension )); - EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension )); - - EXPECT_FALSE(message.HasExtension(unittest::default_string_piece_extension)); - EXPECT_FALSE(message.HasExtension(unittest::default_cord_extension)); - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension )); - EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension )); - EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension )); - EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension )); - EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension )); - EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension )); - EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension )); - EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension )); - EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension)); - EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension)); - EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension )); - EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension )); - EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension )); - EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension )); - EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension )); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::default_nested_enum_extension )); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::default_foreign_enum_extension)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::default_import_enum_extension )); - - EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension)); - EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensions& message) { - // ModifyRepeatedFields only sets the second repeated element of each - // field. In addition to verifying this, we also verify that the first - // element and size were *not* modified. - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension )); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension )); - - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension)); - ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension)); - - EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0)); - EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0)); - EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0)); - EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0)); - EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0)); - EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0)); - EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0)); - EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0)); - EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0)); - EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0)); - EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0)); - EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0)); - EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0)); - EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0)); - - EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a()); - EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb()); - EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c()); - EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d()); - - EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0)); - EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0)); - EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0)); - - EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0)); - EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0)); - - // Actually verify the second (modified) elements now. - EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension , 1)); - EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension , 1)); - EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension , 1)); - EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension , 1)); - EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension , 1)); - EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension , 1)); - EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension , 1)); - EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension , 1)); - EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension, 1)); - EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension, 1)); - EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension , 1)); - EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension , 1)); - EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1)); - EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension , 1)); - EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension , 1)); - - EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension , 1).a()); - EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb()); - EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c()); - EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d()); - - EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1)); - EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension, 1)); - EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::repeated_import_enum_extension , 1)); - - EXPECT_EQ("524", message.GetExtension(unittest::repeated_string_piece_extension, 1)); - EXPECT_EQ("525", message.GetExtension(unittest::repeated_cord_extension, 1)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) { - // We set each field individually, serialize separately, and concatenate all - // the strings in canonical order to determine the expected serialization. - string expected; - unittest::TestFieldOrderings message; - message.set_my_int(1); // Field 1. - message.AppendToString(&expected); - message.Clear(); - message.SetExtension(unittest::my_extension_int, 23); // Field 5. - message.AppendToString(&expected); - message.Clear(); - message.set_my_string("foo"); // Field 11. - message.AppendToString(&expected); - message.Clear(); - message.SetExtension(unittest::my_extension_string, "bar"); // Field 50. - message.AppendToString(&expected); - message.Clear(); - message.set_my_float(1.0); // Field 101. - message.AppendToString(&expected); - message.Clear(); - - // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout. - EXPECT_TRUE(serialized == expected); -} - -// =================================================================== - -TestUtil::ReflectionTester::ReflectionTester( - const Descriptor* base_descriptor) - : base_descriptor_(base_descriptor) { - - const DescriptorPool* pool = base_descriptor->file()->pool(); - - nested_b_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.NestedMessage.bb"); - foreign_c_ = - pool->FindFieldByName("protobuf_unittest.ForeignMessage.c"); - import_d_ = - pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d"); - nested_foo_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO"); - nested_bar_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAR"); - nested_baz_ = - pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAZ"); - foreign_foo_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_FOO"); - foreign_bar_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAR"); - foreign_baz_ = - pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAZ"); - import_foo_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_FOO"); - import_bar_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAR"); - import_baz_ = - pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAZ"); - - if (base_descriptor_->name() == "TestAllExtensions") { - group_a_ = - pool->FindFieldByName("protobuf_unittest.OptionalGroup_extension.a"); - repeated_group_a_ = - pool->FindFieldByName("protobuf_unittest.RepeatedGroup_extension.a"); - } else { - group_a_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.OptionalGroup.a"); - repeated_group_a_ = - pool->FindFieldByName("protobuf_unittest.TestAllTypes.RepeatedGroup.a"); - } - - EXPECT_TRUE(group_a_ != NULL); - EXPECT_TRUE(repeated_group_a_ != NULL); - EXPECT_TRUE(nested_b_ != NULL); - EXPECT_TRUE(foreign_c_ != NULL); - EXPECT_TRUE(import_d_ != NULL); - EXPECT_TRUE(nested_foo_ != NULL); - EXPECT_TRUE(nested_bar_ != NULL); - EXPECT_TRUE(nested_baz_ != NULL); - EXPECT_TRUE(foreign_foo_ != NULL); - EXPECT_TRUE(foreign_bar_ != NULL); - EXPECT_TRUE(foreign_baz_ != NULL); - EXPECT_TRUE(import_foo_ != NULL); - EXPECT_TRUE(import_bar_ != NULL); - EXPECT_TRUE(import_baz_ != NULL); -} - -// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes. -const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) { - const FieldDescriptor* result = NULL; - if (base_descriptor_->name() == "TestAllExtensions") { - result = base_descriptor_->file()->FindExtensionByName(name + "_extension"); - } else { - result = base_descriptor_->FindFieldByName(name); - } - GOOGLE_CHECK(result != NULL); - return result; -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message; - - reflection->SetInt32 (message, F("optional_int32" ), 101); - reflection->SetInt64 (message, F("optional_int64" ), 102); - reflection->SetUInt32(message, F("optional_uint32" ), 103); - reflection->SetUInt64(message, F("optional_uint64" ), 104); - reflection->SetInt32 (message, F("optional_sint32" ), 105); - reflection->SetInt64 (message, F("optional_sint64" ), 106); - reflection->SetUInt32(message, F("optional_fixed32" ), 107); - reflection->SetUInt64(message, F("optional_fixed64" ), 108); - reflection->SetInt32 (message, F("optional_sfixed32"), 109); - reflection->SetInt64 (message, F("optional_sfixed64"), 110); - reflection->SetFloat (message, F("optional_float" ), 111); - reflection->SetDouble(message, F("optional_double" ), 112); - reflection->SetBool (message, F("optional_bool" ), true); - reflection->SetString(message, F("optional_string" ), "115"); - reflection->SetString(message, F("optional_bytes" ), "116"); - - sub_message = reflection->MutableMessage(message, F("optionalgroup")); - sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117); - sub_message = reflection->MutableMessage(message, F("optional_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118); - sub_message = reflection->MutableMessage(message, F("optional_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119); - sub_message = reflection->MutableMessage(message, F("optional_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120); - - reflection->SetEnum(message, F("optional_nested_enum" ), nested_baz_); - reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_); - reflection->SetEnum(message, F("optional_import_enum" ), import_baz_); - - reflection->SetString(message, F("optional_string_piece"), "124"); - reflection->SetString(message, F("optional_cord"), "125"); - - // ----------------------------------------------------------------- - - reflection->AddInt32 (message, F("repeated_int32" ), 201); - reflection->AddInt64 (message, F("repeated_int64" ), 202); - reflection->AddUInt32(message, F("repeated_uint32" ), 203); - reflection->AddUInt64(message, F("repeated_uint64" ), 204); - reflection->AddInt32 (message, F("repeated_sint32" ), 205); - reflection->AddInt64 (message, F("repeated_sint64" ), 206); - reflection->AddUInt32(message, F("repeated_fixed32" ), 207); - reflection->AddUInt64(message, F("repeated_fixed64" ), 208); - reflection->AddInt32 (message, F("repeated_sfixed32"), 209); - reflection->AddInt64 (message, F("repeated_sfixed64"), 210); - reflection->AddFloat (message, F("repeated_float" ), 211); - reflection->AddDouble(message, F("repeated_double" ), 212); - reflection->AddBool (message, F("repeated_bool" ), true); - reflection->AddString(message, F("repeated_string" ), "215"); - reflection->AddString(message, F("repeated_bytes" ), "216"); - - sub_message = reflection->AddMessage(message, F("repeatedgroup")); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217); - sub_message = reflection->AddMessage(message, F("repeated_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218); - sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219); - sub_message = reflection->AddMessage(message, F("repeated_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220); - - reflection->AddEnum(message, F("repeated_nested_enum" ), nested_bar_); - reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_); - reflection->AddEnum(message, F("repeated_import_enum" ), import_bar_); - - reflection->AddString(message, F("repeated_string_piece"), "224"); - reflection->AddString(message, F("repeated_cord"), "225"); - - // Add a second one of each field. - reflection->AddInt32 (message, F("repeated_int32" ), 301); - reflection->AddInt64 (message, F("repeated_int64" ), 302); - reflection->AddUInt32(message, F("repeated_uint32" ), 303); - reflection->AddUInt64(message, F("repeated_uint64" ), 304); - reflection->AddInt32 (message, F("repeated_sint32" ), 305); - reflection->AddInt64 (message, F("repeated_sint64" ), 306); - reflection->AddUInt32(message, F("repeated_fixed32" ), 307); - reflection->AddUInt64(message, F("repeated_fixed64" ), 308); - reflection->AddInt32 (message, F("repeated_sfixed32"), 309); - reflection->AddInt64 (message, F("repeated_sfixed64"), 310); - reflection->AddFloat (message, F("repeated_float" ), 311); - reflection->AddDouble(message, F("repeated_double" ), 312); - reflection->AddBool (message, F("repeated_bool" ), false); - reflection->AddString(message, F("repeated_string" ), "315"); - reflection->AddString(message, F("repeated_bytes" ), "316"); - - sub_message = reflection->AddMessage(message, F("repeatedgroup")); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317); - sub_message = reflection->AddMessage(message, F("repeated_nested_message")); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318); - sub_message = reflection->AddMessage(message, F("repeated_foreign_message")); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319); - sub_message = reflection->AddMessage(message, F("repeated_import_message")); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320); - - reflection->AddEnum(message, F("repeated_nested_enum" ), nested_baz_); - reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_); - reflection->AddEnum(message, F("repeated_import_enum" ), import_baz_); - - reflection->AddString(message, F("repeated_string_piece"), "324"); - reflection->AddString(message, F("repeated_cord"), "325"); - - // ----------------------------------------------------------------- - - reflection->SetInt32 (message, F("default_int32" ), 401); - reflection->SetInt64 (message, F("default_int64" ), 402); - reflection->SetUInt32(message, F("default_uint32" ), 403); - reflection->SetUInt64(message, F("default_uint64" ), 404); - reflection->SetInt32 (message, F("default_sint32" ), 405); - reflection->SetInt64 (message, F("default_sint64" ), 406); - reflection->SetUInt32(message, F("default_fixed32" ), 407); - reflection->SetUInt64(message, F("default_fixed64" ), 408); - reflection->SetInt32 (message, F("default_sfixed32"), 409); - reflection->SetInt64 (message, F("default_sfixed64"), 410); - reflection->SetFloat (message, F("default_float" ), 411); - reflection->SetDouble(message, F("default_double" ), 412); - reflection->SetBool (message, F("default_bool" ), false); - reflection->SetString(message, F("default_string" ), "415"); - reflection->SetString(message, F("default_bytes" ), "416"); - - reflection->SetEnum(message, F("default_nested_enum" ), nested_foo_); - reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_); - reflection->SetEnum(message, F("default_import_enum" ), import_foo_); - - reflection->SetString(message, F("default_string_piece"), "424"); - reflection->SetString(message, F("default_cord"), "425"); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - const Message* sub_message; - - EXPECT_TRUE(reflection->HasField(message, F("optional_int32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_int64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_uint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_uint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_float" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_double" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_bool" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_string" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_bytes" ))); - - EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" ))); - - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); - - EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" ))); - EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" ))); - - EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece"))); - EXPECT_TRUE(reflection->HasField(message, F("optional_cord"))); - - EXPECT_EQ(101 , reflection->GetInt32 (message, F("optional_int32" ))); - EXPECT_EQ(102 , reflection->GetInt64 (message, F("optional_int64" ))); - EXPECT_EQ(103 , reflection->GetUInt32(message, F("optional_uint32" ))); - EXPECT_EQ(104 , reflection->GetUInt64(message, F("optional_uint64" ))); - EXPECT_EQ(105 , reflection->GetInt32 (message, F("optional_sint32" ))); - EXPECT_EQ(106 , reflection->GetInt64 (message, F("optional_sint64" ))); - EXPECT_EQ(107 , reflection->GetUInt32(message, F("optional_fixed32" ))); - EXPECT_EQ(108 , reflection->GetUInt64(message, F("optional_fixed64" ))); - EXPECT_EQ(109 , reflection->GetInt32 (message, F("optional_sfixed32"))); - EXPECT_EQ(110 , reflection->GetInt64 (message, F("optional_sfixed64"))); - EXPECT_EQ(111 , reflection->GetFloat (message, F("optional_float" ))); - EXPECT_EQ(112 , reflection->GetDouble(message, F("optional_double" ))); - EXPECT_EQ(true , reflection->GetBool (message, F("optional_bool" ))); - EXPECT_EQ("115", reflection->GetString(message, F("optional_string" ))); - EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes" ))); - - EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch)); - EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); - - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" ))); - EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum"))); - EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" ))); - - EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece"))); - EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); - - EXPECT_EQ("125", reflection->GetString(message, F("optional_cord"))); - EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch)); - - // ----------------------------------------------------------------- - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes" ))); - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum" ))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum" ))); - - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece"))); - ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord"))); - - EXPECT_EQ(201 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 0)); - EXPECT_EQ(202 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 0)); - EXPECT_EQ(203 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 0)); - EXPECT_EQ(204 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 0)); - EXPECT_EQ(205 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 0)); - EXPECT_EQ(206 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 0)); - EXPECT_EQ(207 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0)); - EXPECT_EQ(208 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0)); - EXPECT_EQ(209 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0)); - EXPECT_EQ(210 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0)); - EXPECT_EQ(211 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 0)); - EXPECT_EQ(212 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 0)); - EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("repeated_bool" ), 0)); - EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string" ), 0)); - EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes" ), 0)); - - EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch)); - EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch)); - - sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0); - EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0); - EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0); - EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0); - EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0)); - EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0)); - EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0)); - - EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0)); - EXPECT_EQ("224", reflection->GetRepeatedStringReference( - message, F("repeated_string_piece"), 0, &scratch)); - - EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0)); - EXPECT_EQ("225", reflection->GetRepeatedStringReference( - message, F("repeated_cord"), 0, &scratch)); - - EXPECT_EQ(301 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 1)); - EXPECT_EQ(302 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 1)); - EXPECT_EQ(303 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 1)); - EXPECT_EQ(304 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 1)); - EXPECT_EQ(305 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 1)); - EXPECT_EQ(306 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 1)); - EXPECT_EQ(307 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1)); - EXPECT_EQ(308 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1)); - EXPECT_EQ(309 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1)); - EXPECT_EQ(310 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1)); - EXPECT_EQ(311 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 1)); - EXPECT_EQ(312 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 1)); - EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("repeated_bool" ), 1)); - EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string" ), 1)); - EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes" ), 1)); - - EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"), - 1, &scratch)); - EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), - 1, &scratch)); - - sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1); - EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1); - EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1); - EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1); - EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1)); - EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1)); - EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1)); - - EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1)); - EXPECT_EQ("324", reflection->GetRepeatedStringReference( - message, F("repeated_string_piece"), 1, &scratch)); - - EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1)); - EXPECT_EQ("325", reflection->GetRepeatedStringReference( - message, F("repeated_cord"), 1, &scratch)); - - // ----------------------------------------------------------------- - - EXPECT_TRUE(reflection->HasField(message, F("default_int32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_int64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_uint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_uint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sint32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sint64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32"))); - EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64"))); - EXPECT_TRUE(reflection->HasField(message, F("default_float" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_double" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_bool" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_string" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_bytes" ))); - - EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" ))); - EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum"))); - EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" ))); - - EXPECT_TRUE(reflection->HasField(message, F("default_string_piece"))); - EXPECT_TRUE(reflection->HasField(message, F("default_cord"))); - - EXPECT_EQ(401 , reflection->GetInt32 (message, F("default_int32" ))); - EXPECT_EQ(402 , reflection->GetInt64 (message, F("default_int64" ))); - EXPECT_EQ(403 , reflection->GetUInt32(message, F("default_uint32" ))); - EXPECT_EQ(404 , reflection->GetUInt64(message, F("default_uint64" ))); - EXPECT_EQ(405 , reflection->GetInt32 (message, F("default_sint32" ))); - EXPECT_EQ(406 , reflection->GetInt64 (message, F("default_sint64" ))); - EXPECT_EQ(407 , reflection->GetUInt32(message, F("default_fixed32" ))); - EXPECT_EQ(408 , reflection->GetUInt64(message, F("default_fixed64" ))); - EXPECT_EQ(409 , reflection->GetInt32 (message, F("default_sfixed32"))); - EXPECT_EQ(410 , reflection->GetInt64 (message, F("default_sfixed64"))); - EXPECT_EQ(411 , reflection->GetFloat (message, F("default_float" ))); - EXPECT_EQ(412 , reflection->GetDouble(message, F("default_double" ))); - EXPECT_EQ(false, reflection->GetBool (message, F("default_bool" ))); - EXPECT_EQ("415", reflection->GetString(message, F("default_string" ))); - EXPECT_EQ("416", reflection->GetString(message, F("default_bytes" ))); - - EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch)); - EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); - - EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" ))); - EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum"))); - EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" ))); - - EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece"))); - EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"), - &scratch)); - - EXPECT_EQ("425", reflection->GetString(message, F("default_cord"))); - EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ExpectClearViaReflection( - const Message& message) { - const Reflection* reflection = message.GetReflection(); - string scratch; - const Message* sub_message; - - // has_blah() should initially be false for all optional fields. - EXPECT_FALSE(reflection->HasField(message, F("optional_int32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_int64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_uint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_uint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_float" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_double" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_bool" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_string" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_bytes" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optionalgroup" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" ))); - EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" ))); - - EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece"))); - EXPECT_FALSE(reflection->HasField(message, F("optional_cord"))); - - // Optional fields without defaults are set to zero or something like it. - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_int32" ))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_int64" ))); - EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_uint32" ))); - EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_uint64" ))); - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sint32" ))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sint64" ))); - EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_fixed32" ))); - EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_fixed64" ))); - EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sfixed32"))); - EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sfixed64"))); - EXPECT_EQ(0 , reflection->GetFloat (message, F("optional_float" ))); - EXPECT_EQ(0 , reflection->GetDouble(message, F("optional_double" ))); - EXPECT_EQ(false, reflection->GetBool (message, F("optional_bool" ))); - EXPECT_EQ("" , reflection->GetString(message, F("optional_string" ))); - EXPECT_EQ("" , reflection->GetString(message, F("optional_bytes" ))); - - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch)); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch)); - - // Embedded messages should also be clear. - sub_message = &reflection->GetMessage(message, F("optionalgroup")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_)); - sub_message = &reflection->GetMessage(message, F("optional_nested_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_)); - sub_message = &reflection->GetMessage(message, F("optional_foreign_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_)); - sub_message = &reflection->GetMessage(message, F("optional_import_message")); - EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_)); - EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_)); - - // Enums without defaults are set to the first value in the enum. - EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" ))); - EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum"))); - EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" ))); - - EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece"))); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch)); - - EXPECT_EQ("", reflection->GetString(message, F("optional_cord"))); - EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch)); - - // Repeated fields are empty. - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes" ))); - - EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum" ))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum" ))); - - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece"))); - EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord"))); - - // has_blah() should also be false for all default fields. - EXPECT_FALSE(reflection->HasField(message, F("default_int32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_int64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_uint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_uint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sint32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sint64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32"))); - EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64"))); - EXPECT_FALSE(reflection->HasField(message, F("default_float" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_double" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_bool" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_string" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_bytes" ))); - - EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" ))); - EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum"))); - EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" ))); - - EXPECT_FALSE(reflection->HasField(message, F("default_string_piece"))); - EXPECT_FALSE(reflection->HasField(message, F("default_cord"))); - - // Fields with defaults have their default values (duh). - EXPECT_EQ( 41 , reflection->GetInt32 (message, F("default_int32" ))); - EXPECT_EQ( 42 , reflection->GetInt64 (message, F("default_int64" ))); - EXPECT_EQ( 43 , reflection->GetUInt32(message, F("default_uint32" ))); - EXPECT_EQ( 44 , reflection->GetUInt64(message, F("default_uint64" ))); - EXPECT_EQ(-45 , reflection->GetInt32 (message, F("default_sint32" ))); - EXPECT_EQ( 46 , reflection->GetInt64 (message, F("default_sint64" ))); - EXPECT_EQ( 47 , reflection->GetUInt32(message, F("default_fixed32" ))); - EXPECT_EQ( 48 , reflection->GetUInt64(message, F("default_fixed64" ))); - EXPECT_EQ( 49 , reflection->GetInt32 (message, F("default_sfixed32"))); - EXPECT_EQ(-50 , reflection->GetInt64 (message, F("default_sfixed64"))); - EXPECT_EQ( 51.5 , reflection->GetFloat (message, F("default_float" ))); - EXPECT_EQ( 52e3 , reflection->GetDouble(message, F("default_double" ))); - EXPECT_EQ(true , reflection->GetBool (message, F("default_bool" ))); - EXPECT_EQ("hello", reflection->GetString(message, F("default_string" ))); - EXPECT_EQ("world", reflection->GetString(message, F("default_bytes" ))); - - EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch)); - EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch)); - - EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" ))); - EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum"))); - EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" ))); - - EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece"))); - EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch)); - - EXPECT_EQ("123", reflection->GetString(message, F("default_cord"))); - EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch)); -} - -// ------------------------------------------------------------------- - -void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection( - Message* message) { - const Reflection* reflection = message->GetReflection(); - Message* sub_message; - - reflection->SetRepeatedInt32 (message, F("repeated_int32" ), 1, 501); - reflection->SetRepeatedInt64 (message, F("repeated_int64" ), 1, 502); - reflection->SetRepeatedUInt32(message, F("repeated_uint32" ), 1, 503); - reflection->SetRepeatedUInt64(message, F("repeated_uint64" ), 1, 504); - reflection->SetRepeatedInt32 (message, F("repeated_sint32" ), 1, 505); - reflection->SetRepeatedInt64 (message, F("repeated_sint64" ), 1, 506); - reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507); - reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508); - reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509); - reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510); - reflection->SetRepeatedFloat (message, F("repeated_float" ), 1, 511); - reflection->SetRepeatedDouble(message, F("repeated_double" ), 1, 512); - reflection->SetRepeatedBool (message, F("repeated_bool" ), 1, true); - reflection->SetRepeatedString(message, F("repeated_string" ), 1, "515"); - reflection->SetRepeatedString(message, F("repeated_bytes" ), 1, "516"); - - sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1); - sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519); - sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1); - sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520); - - reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1, nested_foo_); - reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_); - reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1, import_foo_); - - reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524"); - reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525"); -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/test_util.h b/src/google/protobuf/test_util.h deleted file mode 100644 index 4c578bcd..00000000 --- a/src/google/protobuf/test_util.h +++ /dev/null @@ -1,117 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_TEST_UTIL_H__ -#define GOOGLE_PROTOBUF_TEST_UTIL_H__ - -#include <stack> -#include <string> -#include <google/protobuf/message.h> -#include <google/protobuf/unittest.pb.h> - -namespace google { -namespace protobuf { - -namespace unittest = protobuf_unittest; -namespace unittest_import = protobuf_unittest_import; - -class TestUtil { - public: - // Set every field in the message to a unique value. - static void SetAllFields(unittest::TestAllTypes* message); - static void SetAllExtensions(unittest::TestAllExtensions* message); - static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message); - - // Use the repeated versions of the set_*() accessors to modify all the - // repeated fields of the messsage (which should already have been - // initialized with SetAllFields()). SetAllFields() itself only tests - // the add_*() accessors. - static void ModifyRepeatedFields(unittest::TestAllTypes* message); - static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message); - - // Check that all fields have the values that they should have after - // SetAllFields() is called. - static void ExpectAllFieldsSet(const unittest::TestAllTypes& message); - static void ExpectAllExtensionsSet( - const unittest::TestAllExtensions& message); - - // Expect that the message is modified as would be expected from - // ModifyRepeatedFields(). - static void ExpectRepeatedFieldsModified( - const unittest::TestAllTypes& message); - static void ExpectRepeatedExtensionsModified( - const unittest::TestAllExtensions& message); - - // Check that all fields have their default values. - static void ExpectClear(const unittest::TestAllTypes& message); - static void ExpectExtensionsClear(const unittest::TestAllExtensions& message); - - // Check that the passed-in serialization is the canonical serialization we - // expect for a TestFieldOrderings message filled in by - // SetAllFieldsAndExtensions(). - static void ExpectAllFieldsAndExtensionsInOrder(const string& serialized); - - // Like above, but use the reflection interface. - class ReflectionTester { - public: - // base_descriptor must be a descriptor for TestAllTypes or - // TestAllExtensions. In the former case, ReflectionTester fetches from - // it the FieldDescriptors needed to use the reflection interface. In - // the latter case, ReflectionTester searches for extension fields in - // its file. - explicit ReflectionTester(const Descriptor* base_descriptor); - - void SetAllFieldsViaReflection(Message* message); - void ModifyRepeatedFieldsViaReflection(Message* message); - void ExpectAllFieldsSetViaReflection(const Message& message); - void ExpectClearViaReflection(const Message& message); - - private: - const FieldDescriptor* F(const string& name); - - const Descriptor* base_descriptor_; - - const FieldDescriptor* group_a_; - const FieldDescriptor* repeated_group_a_; - const FieldDescriptor* nested_b_; - const FieldDescriptor* foreign_c_; - const FieldDescriptor* import_d_; - - const EnumValueDescriptor* nested_foo_; - const EnumValueDescriptor* nested_bar_; - const EnumValueDescriptor* nested_baz_; - const EnumValueDescriptor* foreign_foo_; - const EnumValueDescriptor* foreign_bar_; - const EnumValueDescriptor* foreign_baz_; - const EnumValueDescriptor* import_foo_; - const EnumValueDescriptor* import_bar_; - const EnumValueDescriptor* import_baz_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester); - }; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_TEST_UTIL_H__ diff --git a/src/google/protobuf/testdata/golden_message b/src/google/protobuf/testdata/golden_message Binary files differdeleted file mode 100644 index 94898e49..00000000 --- a/src/google/protobuf/testdata/golden_message +++ /dev/null diff --git a/src/google/protobuf/testdata/text_format_unittest_data.txt b/src/google/protobuf/testdata/text_format_unittest_data.txt deleted file mode 100644 index feea8f7b..00000000 --- a/src/google/protobuf/testdata/text_format_unittest_data.txt +++ /dev/null @@ -1,116 +0,0 @@ -optional_int32: 101 -optional_int64: 102 -optional_uint32: 103 -optional_uint64: 104 -optional_sint32: 105 -optional_sint64: 106 -optional_fixed32: 107 -optional_fixed64: 108 -optional_sfixed32: 109 -optional_sfixed64: 110 -optional_float: 111 -optional_double: 112 -optional_bool: true -optional_string: "115" -optional_bytes: "116" -OptionalGroup { - a: 117 -} -optional_nested_message { - bb: 118 -} -optional_foreign_message { - c: 119 -} -optional_import_message { - d: 120 -} -optional_nested_enum: BAZ -optional_foreign_enum: FOREIGN_BAZ -optional_import_enum: IMPORT_BAZ -optional_string_piece: "124" -optional_cord: "125" -repeated_int32: 201 -repeated_int32: 301 -repeated_int64: 202 -repeated_int64: 302 -repeated_uint32: 203 -repeated_uint32: 303 -repeated_uint64: 204 -repeated_uint64: 304 -repeated_sint32: 205 -repeated_sint32: 305 -repeated_sint64: 206 -repeated_sint64: 306 -repeated_fixed32: 207 -repeated_fixed32: 307 -repeated_fixed64: 208 -repeated_fixed64: 308 -repeated_sfixed32: 209 -repeated_sfixed32: 309 -repeated_sfixed64: 210 -repeated_sfixed64: 310 -repeated_float: 211 -repeated_float: 311 -repeated_double: 212 -repeated_double: 312 -repeated_bool: true -repeated_bool: false -repeated_string: "215" -repeated_string: "315" -repeated_bytes: "216" -repeated_bytes: "316" -RepeatedGroup { - a: 217 -} -RepeatedGroup { - a: 317 -} -repeated_nested_message { - bb: 218 -} -repeated_nested_message { - bb: 318 -} -repeated_foreign_message { - c: 219 -} -repeated_foreign_message { - c: 319 -} -repeated_import_message { - d: 220 -} -repeated_import_message { - d: 320 -} -repeated_nested_enum: BAR -repeated_nested_enum: BAZ -repeated_foreign_enum: FOREIGN_BAR -repeated_foreign_enum: FOREIGN_BAZ -repeated_import_enum: IMPORT_BAR -repeated_import_enum: IMPORT_BAZ -repeated_string_piece: "224" -repeated_string_piece: "324" -repeated_cord: "225" -repeated_cord: "325" -default_int32: 401 -default_int64: 402 -default_uint32: 403 -default_uint64: 404 -default_sint32: 405 -default_sint64: 406 -default_fixed32: 407 -default_fixed64: 408 -default_sfixed32: 409 -default_sfixed64: 410 -default_float: 411 -default_double: 412 -default_bool: false -default_string: "415" -default_bytes: "416" -default_nested_enum: FOO -default_foreign_enum: FOREIGN_FOO -default_import_enum: IMPORT_FOO -default_string_piece: "424" -default_cord: "425" diff --git a/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt deleted file mode 100644 index 057beae8..00000000 --- a/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt +++ /dev/null @@ -1,116 +0,0 @@ -[protobuf_unittest.optional_int32_extension]: 101 -[protobuf_unittest.optional_int64_extension]: 102 -[protobuf_unittest.optional_uint32_extension]: 103 -[protobuf_unittest.optional_uint64_extension]: 104 -[protobuf_unittest.optional_sint32_extension]: 105 -[protobuf_unittest.optional_sint64_extension]: 106 -[protobuf_unittest.optional_fixed32_extension]: 107 -[protobuf_unittest.optional_fixed64_extension]: 108 -[protobuf_unittest.optional_sfixed32_extension]: 109 -[protobuf_unittest.optional_sfixed64_extension]: 110 -[protobuf_unittest.optional_float_extension]: 111 -[protobuf_unittest.optional_double_extension]: 112 -[protobuf_unittest.optional_bool_extension]: true -[protobuf_unittest.optional_string_extension]: "115" -[protobuf_unittest.optional_bytes_extension]: "116" -[protobuf_unittest.optionalgroup_extension] { - a: 117 -} -[protobuf_unittest.optional_nested_message_extension] { - bb: 118 -} -[protobuf_unittest.optional_foreign_message_extension] { - c: 119 -} -[protobuf_unittest.optional_import_message_extension] { - d: 120 -} -[protobuf_unittest.optional_nested_enum_extension]: BAZ -[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ -[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ -[protobuf_unittest.optional_string_piece_extension]: "124" -[protobuf_unittest.optional_cord_extension]: "125" -[protobuf_unittest.repeated_int32_extension]: 201 -[protobuf_unittest.repeated_int32_extension]: 301 -[protobuf_unittest.repeated_int64_extension]: 202 -[protobuf_unittest.repeated_int64_extension]: 302 -[protobuf_unittest.repeated_uint32_extension]: 203 -[protobuf_unittest.repeated_uint32_extension]: 303 -[protobuf_unittest.repeated_uint64_extension]: 204 -[protobuf_unittest.repeated_uint64_extension]: 304 -[protobuf_unittest.repeated_sint32_extension]: 205 -[protobuf_unittest.repeated_sint32_extension]: 305 -[protobuf_unittest.repeated_sint64_extension]: 206 -[protobuf_unittest.repeated_sint64_extension]: 306 -[protobuf_unittest.repeated_fixed32_extension]: 207 -[protobuf_unittest.repeated_fixed32_extension]: 307 -[protobuf_unittest.repeated_fixed64_extension]: 208 -[protobuf_unittest.repeated_fixed64_extension]: 308 -[protobuf_unittest.repeated_sfixed32_extension]: 209 -[protobuf_unittest.repeated_sfixed32_extension]: 309 -[protobuf_unittest.repeated_sfixed64_extension]: 210 -[protobuf_unittest.repeated_sfixed64_extension]: 310 -[protobuf_unittest.repeated_float_extension]: 211 -[protobuf_unittest.repeated_float_extension]: 311 -[protobuf_unittest.repeated_double_extension]: 212 -[protobuf_unittest.repeated_double_extension]: 312 -[protobuf_unittest.repeated_bool_extension]: true -[protobuf_unittest.repeated_bool_extension]: false -[protobuf_unittest.repeated_string_extension]: "215" -[protobuf_unittest.repeated_string_extension]: "315" -[protobuf_unittest.repeated_bytes_extension]: "216" -[protobuf_unittest.repeated_bytes_extension]: "316" -[protobuf_unittest.repeatedgroup_extension] { - a: 217 -} -[protobuf_unittest.repeatedgroup_extension] { - a: 317 -} -[protobuf_unittest.repeated_nested_message_extension] { - bb: 218 -} -[protobuf_unittest.repeated_nested_message_extension] { - bb: 318 -} -[protobuf_unittest.repeated_foreign_message_extension] { - c: 219 -} -[protobuf_unittest.repeated_foreign_message_extension] { - c: 319 -} -[protobuf_unittest.repeated_import_message_extension] { - d: 220 -} -[protobuf_unittest.repeated_import_message_extension] { - d: 320 -} -[protobuf_unittest.repeated_nested_enum_extension]: BAR -[protobuf_unittest.repeated_nested_enum_extension]: BAZ -[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR -[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ -[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR -[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ -[protobuf_unittest.repeated_string_piece_extension]: "224" -[protobuf_unittest.repeated_string_piece_extension]: "324" -[protobuf_unittest.repeated_cord_extension]: "225" -[protobuf_unittest.repeated_cord_extension]: "325" -[protobuf_unittest.default_int32_extension]: 401 -[protobuf_unittest.default_int64_extension]: 402 -[protobuf_unittest.default_uint32_extension]: 403 -[protobuf_unittest.default_uint64_extension]: 404 -[protobuf_unittest.default_sint32_extension]: 405 -[protobuf_unittest.default_sint64_extension]: 406 -[protobuf_unittest.default_fixed32_extension]: 407 -[protobuf_unittest.default_fixed64_extension]: 408 -[protobuf_unittest.default_sfixed32_extension]: 409 -[protobuf_unittest.default_sfixed64_extension]: 410 -[protobuf_unittest.default_float_extension]: 411 -[protobuf_unittest.default_double_extension]: 412 -[protobuf_unittest.default_bool_extension]: false -[protobuf_unittest.default_string_extension]: "415" -[protobuf_unittest.default_bytes_extension]: "416" -[protobuf_unittest.default_nested_enum_extension]: FOO -[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO -[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO -[protobuf_unittest.default_string_piece_extension]: "424" -[protobuf_unittest.default_cord_extension]: "425" diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc deleted file mode 100644 index 473d6919..00000000 --- a/src/google/protobuf/testing/file.cc +++ /dev/null @@ -1,157 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// emulates google3/file/base/file.cc - -#include <google/protobuf/testing/file.h> -#include <stdio.h> -#include <sys/stat.h> -#include <sys/types.h> -#ifdef _MSC_VER -#define WIN32_LEAN_AND_MEAN // yeah, right -#include <windows.h> // Find*File(). :( -#include <io.h> -#include <direct.h> -#else -#include <dirent.h> -#include <unistd.h> -#endif -#include <errno.h> - -namespace google { -namespace protobuf { - -#ifdef _WIN32 -#define mkdir(name, mode) mkdir(name) -// Windows doesn't have symbolic links. -#define lstat stat -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#endif - -bool File::Exists(const string& name) { - return access(name.c_str(), F_OK) == 0; -} - -bool File::ReadFileToString(const string& name, string* output) { - char buffer[1024]; - FILE* file = fopen(name.c_str(), "rb"); - if (file == NULL) return false; - - while (true) { - size_t n = fread(buffer, 1, sizeof(buffer), file); - if (n <= 0) break; - output->append(buffer, n); - } - - int error = ferror(file); - if (fclose(file) != 0) return false; - return error == 0; -} - -void File::ReadFileToStringOrDie(const string& name, string* output) { - GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name; -} - -void File::WriteStringToFileOrDie(const string& contents, const string& name) { - FILE* file = fopen(name.c_str(), "wb"); - GOOGLE_CHECK(file != NULL); - GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file), - contents.size()); - GOOGLE_CHECK(fclose(file) == 0); -} - -bool File::CreateDir(const string& name, int mode) { - return mkdir(name.c_str(), mode) == 0; -} - -bool File::RecursivelyCreateDir(const string& path, int mode) { - if (CreateDir(path, mode)) return true; - - // Try creating the parent. - string::size_type slashpos = path.find_first_of('/'); - if (slashpos == string::npos) { - // No parent given. - return false; - } - - return RecursivelyCreateDir(path.substr(0, slashpos), mode) && - CreateDir(path, mode); -} - -void File::DeleteRecursively(const string& name, - void* dummy1, void* dummy2) { - // We don't care too much about error checking here since this is only used - // in tests to delete temporary directories that are under /tmp anyway. - -#ifdef _MSC_VER - // This interface is so weird. - WIN32_FIND_DATA find_data; - HANDLE find_handle = FindFirstFile((name + "/*").c_str(), &find_data); - if (find_handle == INVALID_HANDLE_VALUE) { - // Just delete it, whatever it is. - DeleteFile(name.c_str()); - RemoveDirectory(name.c_str()); - return; - } - - do { - string entry_name = find_data.cFileName; - if (entry_name != "." && entry_name != "..") { - string path = name + "/" + entry_name; - if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - DeleteRecursively(path, NULL, NULL); - RemoveDirectory(path.c_str()); - } else { - DeleteFile(path.c_str()); - } - } - } while(FindNextFile(find_handle, &find_data)); - FindClose(find_handle); - - RemoveDirectory(name.c_str()); -#else - // Use opendir()! Yay! - // lstat = Don't follow symbolic links. - struct stat stats; - if (lstat(name.c_str(), &stats) != 0) return; - - if (S_ISDIR(stats.st_mode)) { - DIR* dir = opendir(name.c_str()); - if (dir != NULL) { - while (true) { - struct dirent* entry = readdir(dir); - if (entry == NULL) break; - string entry_name = entry->d_name; - if (entry_name != "." && entry_name != "..") { - DeleteRecursively(name + "/" + entry_name, NULL, NULL); - } - } - } - - closedir(dir); - rmdir(name.c_str()); - - } else if (S_ISREG(stats.st_mode)) { - remove(name.c_str()); - } -#endif -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h deleted file mode 100644 index 93335f1a..00000000 --- a/src/google/protobuf/testing/file.h +++ /dev/null @@ -1,69 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// emulates google3/file/base/file.h - -#ifndef GOOGLE_PROTOBUF_TESTING_FILE_H__ -#define GOOGLE_PROTOBUF_TESTING_FILE_H__ - -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -const int DEFAULT_FILE_MODE = 0777; - -// Protocol buffer code only uses a couple static methods of File, and only -// in tests. -class File { - public: - // Check if the file exists. - static bool Exists(const string& name); - - // Read an entire file to a string. Return true if successful, false - // otherwise. - static bool ReadFileToString(const string& name, string* output); - - // Same as above, but crash on failure. - static void ReadFileToStringOrDie(const string& name, string* output); - - // Create a file and write a string to it. - static void WriteStringToFileOrDie(const string& contents, - const string& name); - - // Create a directory. - static bool CreateDir(const string& name, int mode); - - // Create a directory and all parent directories if necessary. - static bool RecursivelyCreateDir(const string& path, int mode); - - // If "name" is a file, we delete it. If it is a directory, we - // call DeleteRecursively() for each file or directory (other than - // dot and double-dot) within it, and then delete the directory itself. - // The "dummy" parameters have a meaning in the original version of this - // method but they are not used anywhere in protocol buffers. - static void DeleteRecursively(const string& name, - void* dummy1, void* dummy2); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File); -}; - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_TESTING_FILE_H__ diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc deleted file mode 100644 index 65c1154f..00000000 --- a/src/google/protobuf/testing/googletest.cc +++ /dev/null @@ -1,223 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// emulates google3/testing/base/public/googletest.cc - -#include <google/protobuf/testing/googletest.h> -#include <google/protobuf/testing/file.h> -#include <google/protobuf/stubs/strutil.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <errno.h> -#include <stdlib.h> -#ifdef _MSC_VER -#include <io.h> -#include <direct.h> -#else -#include <unistd.h> -#endif -#include <stdio.h> -#include <fcntl.h> - -namespace google { -namespace protobuf { - -#ifdef _WIN32 -#define mkdir(name, mode) mkdir(name) -#endif - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY _O_BINARY -#else -#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. -#endif -#endif - -string TestSourceDir() { -#ifdef _MSC_VER - // Look for the "src" directory. - string prefix = "."; - - while (!File::Exists(prefix + "/src/google/protobuf")) { - if (!File::Exists(prefix)) { - GOOGLE_LOG(FATAL) - << "Could not find protobuf source code. Please run tests from " - "somewhere within the protobuf source package."; - } - prefix += "/.."; - } - return prefix + "/src"; -#else - // automake sets the "srcdir" environment variable. - char* result = getenv("srcdir"); - if (result == NULL) { - // Otherwise, the test must be run from the source directory. - return "."; - } else { - return result; - } -#endif -} - -namespace { - -string GetTemporaryDirectoryName() { - // tmpnam() is generally not considered safe but we're only using it for - // testing. We cannot use tmpfile() or mkstemp() since we're creating a - // directory. - string result = tmpnam(NULL); -#ifdef _WIN32 - // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed - // to be used in the current working directory. WTF? - if (HasPrefixString(result, "\\")) { - result.erase(0, 1); - } -#endif // _WIN32 - return result; -} - -// Creates a temporary directory on demand and deletes it when the process -// quits. -class TempDirDeleter { - public: - TempDirDeleter() {} - ~TempDirDeleter() { - if (!name_.empty()) { - File::DeleteRecursively(name_, NULL, NULL); - } - } - - string GetTempDir() { - if (name_.empty()) { - name_ = GetTemporaryDirectoryName(); - GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); - - // Stick a file in the directory that tells people what this is, in case - // we abort and don't get a chance to delete it. - File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS"); - } - return name_; - } - - private: - string name_; -}; - -TempDirDeleter temp_dir_deleter_; - -} // namespace - -string TestTempDir() { - return temp_dir_deleter_.GetTempDir(); -} - -// TODO(kenton): Share duplicated code below. Too busy/lazy for now. - -static string stdout_capture_filename_; -static string stderr_capture_filename_; -static int original_stdout_ = -1; -static int original_stderr_ = -1; - -void CaptureTestStdout() { - GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing."; - - stdout_capture_filename_ = TestTempDir() + "/captured_stdout"; - - int fd = open(stdout_capture_filename_.c_str(), - O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); - GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); - - original_stdout_ = dup(1); - close(1); - dup2(fd, 1); - close(fd); -} - -void CaptureTestStderr() { - GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing."; - - stderr_capture_filename_ = TestTempDir() + "/captured_stderr"; - - int fd = open(stderr_capture_filename_.c_str(), - O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777); - GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno); - - original_stderr_ = dup(2); - close(2); - dup2(fd, 2); - close(fd); -} - -string GetCapturedTestStdout() { - GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; - - close(1); - dup2(original_stdout_, 1); - original_stdout_ = -1; - - string result; - File::ReadFileToStringOrDie(stdout_capture_filename_, &result); - - remove(stdout_capture_filename_.c_str()); - - return result; -} - -string GetCapturedTestStderr() { - GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; - - close(2); - dup2(original_stderr_, 2); - original_stderr_ = -1; - - string result; - File::ReadFileToStringOrDie(stderr_capture_filename_, &result); - - remove(stderr_capture_filename_.c_str()); - - return result; -} - -ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL; - -ScopedMemoryLog::ScopedMemoryLog() { - GOOGLE_CHECK(active_log_ == NULL); - active_log_ = this; - old_handler_ = SetLogHandler(&HandleLog); -} - -ScopedMemoryLog::~ScopedMemoryLog() { - SetLogHandler(old_handler_); - active_log_ = NULL; -} - -const vector<string>& ScopedMemoryLog::GetMessages(LogLevel dummy) const { - GOOGLE_CHECK_EQ(dummy, ERROR); - return messages_; -} - -void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, - int line, const string& message) { - GOOGLE_CHECK(active_log_ != NULL); - if (level == ERROR) { - active_log_->messages_.push_back(message); - } -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h deleted file mode 100644 index bb4aafab..00000000 --- a/src/google/protobuf/testing/googletest.h +++ /dev/null @@ -1,83 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// emulates google3/testing/base/public/googletest.h - -#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__ -#define GOOGLE_PROTOBUF_GOOGLETEST_H__ - -#include <vector> -#include <google/protobuf/stubs/common.h> - -namespace google { -namespace protobuf { - -// When running unittests, get the directory containing the source code. -string TestSourceDir(); - -// When running unittests, get a directory where temporary files may be -// placed. -string TestTempDir(); - -// Capture all text written to stdout or stderr. -void CaptureTestStdout(); -void CaptureTestStderr(); - -// Stop capturing stdout or stderr and return the text captured. -string GetCapturedTestStdout(); -string GetCapturedTestStderr(); - -// For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel -// constants don't have the LOGLEVEL_ prefix, so the code that used -// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR. -static const LogLevel ERROR = LOGLEVEL_ERROR; - -// Receives copies of all LOG(ERROR) messages while in scope. Sample usage: -// { -// ScopedMemoryLog log; // constructor registers object as a log sink -// SomeRoutineThatMayLogMessages(); -// const vector<string>& warnings = log.GetMessages(ERROR); -// } // destructor unregisters object as a log sink -// This is a dummy implementation which covers only what is used by protocol -// buffer unit tests. -class ScopedMemoryLog { - public: - ScopedMemoryLog(); - virtual ~ScopedMemoryLog(); - - // Fetches all messages logged. The internal version of this class - // would only fetch messages at the given security level, but the protobuf - // open source version ignores the argument since we always pass ERROR - // anyway. - const vector<string>& GetMessages(LogLevel dummy) const; - - private: - vector<string> messages_; - LogHandler* old_handler_; - - static void HandleLog(LogLevel level, const char* filename, int line, - const string& message); - - static ScopedMemoryLog* active_log_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedMemoryLog); -}; - -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_GOOGLETEST_H__ diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc deleted file mode 100644 index a2318678..00000000 --- a/src/google/protobuf/text_format.cc +++ /dev/null @@ -1,979 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <float.h> -#include <math.h> -#include <stack> -#include <limits> - -#include <google/protobuf/text_format.h> - -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/unknown_field_set.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { - -string Message::DebugString() const { - string debug_string; - io::StringOutputStream output_stream(&debug_string); - - TextFormat::Print(*this, &output_stream); - - return debug_string; -} - -string Message::ShortDebugString() const { - // TODO(kenton): Make TextFormat support this natively instead of using - // DebugString() and munging the result. - string result = DebugString(); - - // Replace each contiguous range of whitespace (including newlines) with a - // single space. - for (int i = 0; i < result.size(); i++) { - int pos = i; - while (isspace(result[pos])) ++pos; - if (pos > i) result.replace(i, pos - i, " "); - } - - return result; -} - -void Message::PrintDebugString() const { - printf("%s", DebugString().c_str()); -} - -// =========================================================================== -// Internal class for parsing an ASCII representation of a Protocol Message. -// This class makes use of the Protocol Message compiler's tokenizer found -// in //google/protobuf/io/tokenizer.h. Note that class's Parse -// method is *not* thread-safe and should only be used in a single thread at -// a time. - -// Makes code slightly more readable. The meaning of "DO(foo)" is -// "Execute foo and fail if it fails.", where failure is indicated by -// returning false. Borrowed from parser.cc (Thanks Kenton!). -#define DO(STATEMENT) if (STATEMENT) {} else return false - -class TextFormat::ParserImpl { - public: - ParserImpl(io::ZeroCopyInputStream* input_stream, - io::ErrorCollector* error_collector) - : error_collector_(error_collector), - tokenizer_error_collector_(this), - tokenizer_(input_stream, &tokenizer_error_collector_), - root_message_type_(NULL) { - // For backwards-compatibility with proto1, we need to allow the 'f' suffix - // for floats. - tokenizer_.set_allow_f_after_float(true); - - // '#' starts a comment. - tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); - - // Consume the starting token. - tokenizer_.Next(); - } - ~ParserImpl() { } - - // Parses the ASCII representation specified in input and saves the - // information into the output pointer (a Message). Returns - // false if an error occurs (an error will also be logged to - // GOOGLE_LOG(ERROR)). - bool Parse(Message* output) { - root_message_type_ = output->GetDescriptor(); - - // Consume fields until we cannot do so anymore. - while(true) { - if (LookingAtType(io::Tokenizer::TYPE_END)) { - return true; - } - - DO(ConsumeField(output)); - } - } - - void ReportError(int line, int col, const string& message) { - if (error_collector_ == NULL) { - if (line >= 0) { - GOOGLE_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() - << ": " << (line + 1) << ":" - << (col + 1) << ": " << message; - } else { - GOOGLE_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() - << ": " << message; - } - } else { - error_collector_->AddError(line, col, message); - } - } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); - - // Reports an error with the given message with information indicating - // the position (as derived from the current token). - void ReportError(const string& message) { - ReportError(tokenizer_.current().line, tokenizer_.current().column, - message); - } - - // Consumes the specified message with the given starting delimeter. - // This method checks to see that the end delimeter at the conclusion of - // the consumption matches the starting delimeter passed in here. - bool ConsumeMessage(Message* message, const string delimeter) { - while (!LookingAt(">") && !LookingAt("}")) { - DO(ConsumeField(message)); - } - - // Confirm that we have a valid ending delimeter. - DO(Consume(delimeter)); - - return true; - } - - // Consumes the current field (as returned by the tokenizer) on the - // passed in message. - bool ConsumeField(Message* message) { - const Reflection* reflection = message->GetReflection(); - const Descriptor* descriptor = message->GetDescriptor(); - - string field_name; - - const FieldDescriptor* field = NULL; - - if (TryConsume("[")) { - // Extension. - DO(ConsumeIdentifier(&field_name)); - while (TryConsume(".")) { - string part; - DO(ConsumeIdentifier(&part)); - field_name += "."; - field_name += part; - } - DO(Consume("]")); - - field = reflection->FindKnownExtensionByName(field_name); - - if (field == NULL) { - ReportError("Extension \"" + field_name + "\" is not defined or " - "is not an extension of \"" + - descriptor->full_name() + "\"."); - return false; - } - } else { - DO(ConsumeIdentifier(&field_name)); - - field = descriptor->FindFieldByName(field_name); - // Group names are expected to be capitalized as they appear in the - // .proto file, which actually matches their type names, not their field - // names. - if (field == NULL) { - string lower_field_name = field_name; - LowerString(&lower_field_name); - field = descriptor->FindFieldByName(lower_field_name); - // If the case-insensitive match worked but the field is NOT a group, - if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { - field = NULL; - } - } - // Again, special-case group names as described above. - if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP - && field->message_type()->name() != field_name) { - field = NULL; - } - - if (field == NULL) { - ReportError("Message type \"" + descriptor->full_name() + - "\" has no field named \"" + field_name + "\"."); - return false; - } - } - - // Perform special handling for embedded message types. - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - string delimeter; - - // ':' is optional here. - TryConsume(":"); - - if (TryConsume("<")) { - delimeter = ">"; - } else { - DO(Consume("{")); - delimeter = "}"; - } - - if (field->is_repeated()) { - DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); - } else { - DO(ConsumeMessage(reflection->MutableMessage(message, field), - delimeter)); - } - } else { - DO(Consume(":")); - DO(ConsumeFieldValue(message, reflection, field)); - } - - return true; - } - - bool ConsumeFieldValue(Message* message, - const Reflection* reflection, - const FieldDescriptor* field) { - -// Define an easy to use macro for setting fields. This macro checks -// to see if the field is repeated (in which case we need to use the Add -// methods or not (in which case we need to use the Set methods). -#define SET_FIELD(CPPTYPE, VALUE) \ - if (field->is_repeated()) { \ - reflection->Add##CPPTYPE(message, field, VALUE); \ - } else { \ - reflection->Set##CPPTYPE(message, field, VALUE); \ - } \ - - switch(field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: { - int64 value; - DO(ConsumeSignedInteger(&value, kint32max)); - SET_FIELD(Int32, static_cast<int32>(value)); - break; - } - - case FieldDescriptor::CPPTYPE_UINT32: { - uint64 value; - DO(ConsumeUnsignedInteger(&value, kuint32max)); - SET_FIELD(UInt32, static_cast<uint32>(value)); - break; - } - - case FieldDescriptor::CPPTYPE_INT64: { - int64 value; - DO(ConsumeSignedInteger(&value, kint64max)); - SET_FIELD(Int64, value); - break; - } - - case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value; - DO(ConsumeUnsignedInteger(&value, kuint64max)); - SET_FIELD(UInt64, value); - break; - } - - case FieldDescriptor::CPPTYPE_FLOAT: { - double value; - DO(ConsumeDouble(&value)); - SET_FIELD(Float, static_cast<float>(value)); - break; - } - - case FieldDescriptor::CPPTYPE_DOUBLE: { - double value; - DO(ConsumeDouble(&value)); - SET_FIELD(Double, value); - break; - } - - case FieldDescriptor::CPPTYPE_STRING: { - string value; - DO(ConsumeString(&value)); - SET_FIELD(String, value); - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: { - string value; - DO(ConsumeIdentifier(&value)); - - if (value == "true") { - SET_FIELD(Bool, true); - } else if (value == "false") { - 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); - - if (enum_value == NULL) { - ReportError("Unknown enumeration value of \"" + value + "\" for " - "field \"" + field->name() + "\"."); - return false; - } - - SET_FIELD(Enum, enum_value); - break; - } - - case FieldDescriptor::CPPTYPE_MESSAGE: { - // We should never get here. Put here instead of a default - // so that if new types are added, we get a nice compiler warning. - GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; - break; - } - } -#undef SET_FIELD - return true; - } - - // Returns true if the current token's text is equal to that specified. - bool LookingAt(const string& text) { - return tokenizer_.current().text == text; - } - - // Returns true if the current token's type is equal to that specified. - bool LookingAtType(io::Tokenizer::TokenType token_type) { - return tokenizer_.current().type == token_type; - } - - // Consumes an identifier and saves its value in the identifier parameter. - // Returns false if the token is not of type IDENTFIER. - bool ConsumeIdentifier(string* identifier) { - if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - ReportError("Expected identifier."); - return false; - } - - *identifier = tokenizer_.current().text; - - tokenizer_.Next(); - return true; - } - - // Consumes a string and saves its value in the text parameter. - // Returns false if the token is not of type STRING. - bool ConsumeString(string* text) { - if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { - ReportError("Expected string."); - return false; - } - - io::Tokenizer::ParseString(tokenizer_.current().text, text); - - tokenizer_.Next(); - return true; - } - - // Consumes a uint64 and saves its value in the value parameter. - // Returns false if the token is not of type INTEGER. - bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { - if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - ReportError("Expected integer."); - return false; - } - - if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, - max_value, value)) { - ReportError("Integer out of range."); - return false; - } - - tokenizer_.Next(); - return true; - } - - // Consumes an int64 and saves its value in the value parameter. - // Note that since the tokenizer does not support negative numbers, - // we actually may consume an additional token (for the minus sign) in this - // method. Returns false if the token is not an integer - // (signed or otherwise). - bool ConsumeSignedInteger(int64* value, uint64 max_value) { - bool negative = false; - - if (TryConsume("-")) { - negative = true; - // Two's complement always allows one more negative integer than - // positive. - ++max_value; - } - - uint64 unsigned_value; - - DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); - - *value = static_cast<int64>(unsigned_value); - - if (negative) { - *value = -*value; - } - - return true; - } - - // Consumes a double and saves its value in the value parameter. - // Note that since the tokenizer does not support negative numbers, - // we actually may consume an additional token (for the minus sign) in this - // method. Returns false if the token is not a double - // (signed or otherwise). - bool ConsumeDouble(double* value) { - bool negative = false; - - if (TryConsume("-")) { - negative = true; - } - - // A double can actually be an integer, according to the tokenizer. - // Therefore, we must check both cases here. - if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { - // We have found an integer value for the double. - uint64 integer_value; - DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); - - *value = static_cast<double>(integer_value); - } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { - // We have found a float value for the double. - *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); - - // Mark the current token as consumed. - tokenizer_.Next(); - } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - string text = tokenizer_.current().text; - LowerString(&text); - if (text == "inf" || text == "infinity") { - *value = std::numeric_limits<double>::infinity(); - tokenizer_.Next(); - } else if (text == "nan") { - *value = std::numeric_limits<double>::quiet_NaN(); - tokenizer_.Next(); - } else { - ReportError("Expected double."); - return false; - } - } else { - ReportError("Expected double."); - return false; - } - - if (negative) { - *value = -*value; - } - - return true; - } - - // Consumes a token and confirms that it matches that specified in the - // value parameter. Returns false if the token found does not match that - // which was specified. - bool Consume(const string& value) { - const string& current_value = tokenizer_.current().text; - - if (current_value != value) { - ReportError("Expected \"" + value + "\", found \"" + current_value - + "\"."); - return false; - } - - tokenizer_.Next(); - - return true; - } - - // Attempts to consume the supplied value. Returns false if a the - // token found does not match the value specified. - bool TryConsume(const string& value) { - if (tokenizer_.current().text == value) { - tokenizer_.Next(); - return true; - } else { - return false; - } - } - - // An internal instance of the Tokenizer's error collector, used to - // collect any base-level parse errors and feed them to the ParserImpl. - class ParserErrorCollector : public io::ErrorCollector { - public: - explicit ParserErrorCollector(TextFormat::ParserImpl* parser) : - parser_(parser) { } - - virtual ~ParserErrorCollector() { }; - - virtual void AddError(int line, int column, const string& message) { - parser_->ReportError(line, column, message); - } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); - TextFormat::ParserImpl* parser_; - }; - - io::ErrorCollector* error_collector_; - ParserErrorCollector tokenizer_error_collector_; - io::Tokenizer tokenizer_; - const Descriptor* root_message_type_; -}; - -#undef DO - -// =========================================================================== -// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted -// from the Printer found in //google/protobuf/io/printer.h -class TextFormat::TextGenerator { - public: - explicit TextGenerator(io::ZeroCopyOutputStream* output) - : output_(output), - buffer_(NULL), - buffer_size_(0), - at_start_of_line_(true), - failed_(false), - indent_("") { - } - - ~TextGenerator() { - // Only BackUp() if we're sure we've successfully called Next() at least - // once. - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - } - } - - // Indent text by two spaces. After calling Indent(), two spaces will be - // inserted at the beginning of each line of text. Indent() may be called - // multiple times to produce deeper indents. - void Indent() { - indent_ += " "; - } - - // Reduces the current indent level by two spaces, or crashes if the indent - // level is zero. - void Outdent() { - if (indent_.empty()) { - GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; - return; - } - - indent_.resize(indent_.size() - 2); - } - - // Print text to the output stream. - void Print(const string& str) { - Print(str.c_str()); - } - - // Print text to the output stream. - void Print(const char* text) { - int size = strlen(text); - int pos = 0; // The number of bytes we've written so far. - - for (int i = 0; i < size; i++) { - if (text[i] == '\n') { - // Saw newline. If there is more text, we may need to insert an indent - // here. So, write what we have so far, including the '\n'. - Write(text + pos, i - pos + 1); - pos = i + 1; - - // Setting this true will cause the next Write() to insert an indent - // first. - at_start_of_line_ = true; - } - } - - // Write the rest. - Write(text + pos, size - pos); - } - - // True if any write to the underlying stream failed. (We don't just - // crash in this case because this is an I/O failure, not a programming - // error.) - bool failed() const { return failed_; } - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); - - void Write(const char* data, int size) { - if (failed_) return; - if (size == 0) return; - - if (at_start_of_line_) { - // Insert an indent. - at_start_of_line_ = false; - Write(indent_.data(), indent_.size()); - if (failed_) return; - } - - while (size > buffer_size_) { - // Data exceeds space in the buffer. Copy what we can and request a - // new buffer. - memcpy(buffer_, data, buffer_size_); - data += buffer_size_; - size -= buffer_size_; - void* void_buffer; - failed_ = !output_->Next(&void_buffer, &buffer_size_); - if (failed_) return; - buffer_ = reinterpret_cast<char*>(void_buffer); - } - - // Buffer is big enough to receive the data; copy it. - memcpy(buffer_, data, size); - buffer_ += size; - buffer_size_ -= size; - } - - io::ZeroCopyOutputStream* const output_; - char* buffer_; - int buffer_size_; - bool at_start_of_line_; - bool failed_; - - string indent_; -}; - -// =========================================================================== - -TextFormat::Parser::Parser() - : error_collector_(NULL), - allow_partial_(false) {} - -TextFormat::Parser::~Parser() {} - -bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, - Message* output) { - output->Clear(); - return Merge(input, output); -} - -bool TextFormat::Parser::ParseFromString(const string& input, - Message* output) { - io::ArrayInputStream input_stream(input.data(), input.size()); - return Parse(&input_stream, output); -} - -bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, - Message* output) { - ParserImpl parser(input, error_collector_); - if (!parser.Parse(output)) return false; - if (!allow_partial_ && !output->IsInitialized()) { - vector<string> missing_fields; - output->FindInitializationErrors(&missing_fields); - parser.ReportError(-1, 0, "Message missing required fields: " + - JoinStrings(missing_fields, ", ")); - return false; - } - return true; -} - -bool TextFormat::Parser::MergeFromString(const string& input, - Message* output) { - io::ArrayInputStream input_stream(input.data(), input.size()); - return Merge(&input_stream, output); -} - - -/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, - Message* output) { - return Parser().Parse(input, output); -} - -/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, - Message* output) { - return Parser().Merge(input, output); -} - -/* static */ bool TextFormat::ParseFromString(const string& input, - Message* output) { - return Parser().ParseFromString(input, output); -} - -/* static */ bool TextFormat::MergeFromString(const string& input, - Message* output) { - return Parser().MergeFromString(input, output); -} - -/* static */ bool TextFormat::PrintToString(const Message& message, - string* output) { - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - - bool result = Print(message, &output_stream); - - return result; -} - -/* static */ bool TextFormat::PrintUnknownFieldsToString( - const UnknownFieldSet& unknown_fields, - string* output) { - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - return PrintUnknownFields(unknown_fields, &output_stream); -} - -/* static */ bool TextFormat::Print(const Message& message, - io::ZeroCopyOutputStream* output) { - TextGenerator generator(output); - - Print(message, generator); - - // Output false if the generator failed internally. - return !generator.failed(); -} - -/* static */ bool TextFormat::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output) { - TextGenerator generator(output); - - PrintUnknownFields(unknown_fields, generator); - - // Output false if the generator failed internally. - return !generator.failed(); -} - -/* static */ void TextFormat::Print(const Message& message, - TextGenerator& generator) { - const Reflection* reflection = message.GetReflection(); - vector<const FieldDescriptor*> fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - PrintField(message, reflection, fields[i], generator); - } - PrintUnknownFields(reflection->GetUnknownFields(message), generator); -} - -/* static */ void TextFormat::PrintFieldValueToString( - const Message& message, - const FieldDescriptor* field, - int index, - string* output) { - - GOOGLE_DCHECK(output) << "output specified is NULL"; - - output->clear(); - io::StringOutputStream output_stream(output); - TextGenerator generator(&output_stream); - - PrintFieldValue(message, message.GetReflection(), field, index, generator); -} - -/* static */ void TextFormat::PrintField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) { - int count = 0; - - if (field->is_repeated()) { - count = reflection->FieldSize(message, field); - } else if (reflection->HasField(message, field)) { - count = 1; - } - - for (int j = 0; j < count; ++j) { - if (field->is_extension()) { - generator.Print("["); - // We special-case MessageSet elements for compatibility with proto1. - if (field->containing_type()->options().message_set_wire_format() - && field->type() == FieldDescriptor::TYPE_MESSAGE - && field->is_optional() - && field->extension_scope() == field->message_type()) { - generator.Print(field->message_type()->full_name()); - } else { - generator.Print(field->full_name()); - } - generator.Print("]"); - } else { - if (field->type() == FieldDescriptor::TYPE_GROUP) { - // Groups must be serialized with their original capitalization. - generator.Print(field->message_type()->name()); - } else { - generator.Print(field->name()); - } - } - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - generator.Print(" {\n"); - generator.Indent(); - } else { - generator.Print(": "); - } - - // Write the field value. - int field_index = j; - if (!field->is_repeated()) { - field_index = -1; - } - - PrintFieldValue(message, reflection, field, field_index, generator); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - generator.Outdent(); - generator.Print("}"); - } - - generator.Print("\n"); - } -} - -/* static */ void TextFormat::PrintFieldValue( - const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator) { - GOOGLE_DCHECK(field->is_repeated() || (index == -1)) - << "Index must be -1 for non-repeated fields"; - - switch (field->cpp_type()) { -#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ - case FieldDescriptor::CPPTYPE_##CPPTYPE: \ - generator.Print(TO_STRING(field->is_repeated() ? \ - reflection->GetRepeated##METHOD(message, field, index) : \ - reflection->Get##METHOD(message, field))); \ - break; \ - - OUTPUT_FIELD( INT32, Int32, SimpleItoa); - OUTPUT_FIELD( INT64, Int64, SimpleItoa); - OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); - OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); - OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); - OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); -#undef OUTPUT_FIELD - - case FieldDescriptor::CPPTYPE_STRING: { - string scratch; - const string& value = field->is_repeated() ? - reflection->GetRepeatedStringReference( - message, field, index, &scratch) : - reflection->GetStringReference(message, field, &scratch); - - generator.Print("\""); - generator.Print(CEscape(value)); - generator.Print("\""); - - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: - if (field->is_repeated()) { - generator.Print(reflection->GetRepeatedBool(message, field, index) - ? "true" : "false"); - } else { - generator.Print(reflection->GetBool(message, field) - ? "true" : "false"); - } - break; - - case FieldDescriptor::CPPTYPE_ENUM: - generator.Print(field->is_repeated() ? - reflection->GetRepeatedEnum(message, field, index)->name() : - reflection->GetEnum(message, field)->name()); - break; - - case FieldDescriptor::CPPTYPE_MESSAGE: - Print(field->is_repeated() ? - reflection->GetRepeatedMessage(message, field, index) : - reflection->GetMessage(message, field), - generator); - break; - } -} - -// Prints an integer as hex with a fixed number of digits dependent on the -// integer type. -template<typename IntType> -static string PaddedHex(IntType value) { - string result; - result.reserve(sizeof(value) * 2); - for (int i = sizeof(value) * 2 - 1; i >= 0; i--) { - result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F)); - } - return result; -} - -/* static */ void TextFormat::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, TextGenerator& generator) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - string field_number = SimpleItoa(field.number()); - - for (int j = 0; j < field.varint_size(); j++) { - generator.Print(field_number); - generator.Print(": "); - generator.Print(SimpleItoa(field.varint(j))); - generator.Print("\n"); - } - for (int j = 0; j < field.fixed32_size(); j++) { - generator.Print(field_number); - generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex32ToBuffer(field.fixed32(j), buffer)); - generator.Print("\n"); - } - for (int j = 0; j < field.fixed64_size(); j++) { - generator.Print(field_number); - generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex64ToBuffer(field.fixed64(j), buffer)); - generator.Print("\n"); - } - for (int j = 0; j < field.length_delimited_size(); j++) { - generator.Print(field_number); - const string& value = field.length_delimited(j); - UnknownFieldSet embedded_unknown_fields; - if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { - // This field is parseable as a Message. - // So it is probably an embedded message. - generator.Print(" {\n"); - generator.Indent(); - PrintUnknownFields(embedded_unknown_fields, generator); - generator.Outdent(); - generator.Print("}\n"); - } else { - // This field is not parseable as a Message. - // So it is probably just a plain string. - generator.Print(": \""); - generator.Print(CEscape(value)); - generator.Print("\"\n"); - } - } - for (int j = 0; j < field.group_size(); j++) { - generator.Print(field_number); - generator.Print(" {\n"); - generator.Indent(); - PrintUnknownFields(field.group(j), generator); - generator.Outdent(); - generator.Print("}\n"); - } - } -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h deleted file mode 100644 index cd93c14a..00000000 --- a/src/google/protobuf/text_format.h +++ /dev/null @@ -1,156 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Utilities for printing and parsing protocol messages in a human-readable, -// text-based format. - -#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ -#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ - -#include <string> -#include <google/protobuf/message.h> -#include <google/protobuf/descriptor.h> - -namespace google { -namespace protobuf { - -namespace io { - class ErrorCollector; // tokenizer.h -} - -// This class implements protocol buffer text format. Printing and parsing -// protocol messages in text format is useful for debugging and human editing -// of messages. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT TextFormat { - public: - // Outputs a textual representation of the given message to the given - // output stream. - static bool Print(const Message& message, io::ZeroCopyOutputStream* output); - - // Print the fields in an UnknownFieldSet. They are printed by tag number - // only. Embedded messages are heuristically identified by attempting to - // parse them. - static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output); - - // Like Print(), but outputs directly to a string. - static bool PrintToString(const Message& message, string* output); - - // Like PrintUnknownFields(), but outputs directly to a string. - static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, - string* output); - - // Outputs a textual representation of the value of the field supplied on - // the message supplied. For non-repeated fields, an index of -1 must - // be supplied. Note that this method will print the default value for a - // field if it is not set. - static void PrintFieldValueToString(const Message& message, - const FieldDescriptor* field, - int index, - string* output); - - // Parses a text-format protocol message from the given input stream to - // the given message object. This function parses the format written - // by Print(). - static bool Parse(io::ZeroCopyInputStream* input, Message* output); - // Like Parse(), but reads directly from a string. - static bool ParseFromString(const string& input, Message* output); - - // Like Parse(), but the data is merged into the given message, as if - // using Message::MergeFrom(). - static bool Merge(io::ZeroCopyInputStream* input, Message* output); - // Like Merge(), but reads directly from a string. - static bool MergeFromString(const string& input, Message* output); - - // For more control over parsing, use this class. - class LIBPROTOBUF_EXPORT Parser { - public: - Parser(); - ~Parser(); - - // Like TextFormat::Parse(). - bool Parse(io::ZeroCopyInputStream* input, Message* output); - // Like TextFormat::ParseFromString(). - bool ParseFromString(const string& input, Message* output); - // Like TextFormat::Merge(). - bool Merge(io::ZeroCopyInputStream* input, Message* output); - // Like TextFormat::MergeFromString(). - bool MergeFromString(const string& input, Message* output); - - // Set where to report parse errors. If NULL (the default), errors will - // be printed to stderr. - void RecordErrorsTo(io::ErrorCollector* error_collector) { - error_collector_ = error_collector; - } - - // Normally parsing fails if, after parsing, output->IsInitialized() - // returns false. Call AllowPartialMessage(true) to skip this check. - void AllowPartialMessage(bool allow) { - allow_partial_ = allow; - } - - private: - io::ErrorCollector* error_collector_; - bool allow_partial_; - }; - - private: - // Forward declaration of an internal class used to print the text - // output to the OutputStream (see text_format.cc for implementation). - class TextGenerator; - - // Forward declaration of an internal class used to parse text - // representations (see text_format.cc for implementation). - class ParserImpl; - - // Internal Print method, used for writing to the OutputStream via - // the TextGenerator class. - static void Print(const Message& message, - TextGenerator& generator); - - // Print a single field. - static void PrintField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator); - - // Outputs a textual representation of the value of the field supplied on - // the message supplied or the default value if not set. - static void PrintFieldValue(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - int index, - TextGenerator& generator); - - // Print the fields in an UnknownFieldSet. They are printed by tag number - // only. Embedded messages are heuristically identified by attempting to - // parse them. - static void PrintUnknownFields(const UnknownFieldSet& unknown_fields, - TextGenerator& generator); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat); -}; - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__ diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc deleted file mode 100644 index 63a0c331..00000000 --- a/src/google/protobuf/text_format_unittest.cc +++ /dev/null @@ -1,742 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: jschorr@google.com (Joseph Schorr) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <math.h> -#include <stdlib.h> -#include <limits> - -#include <google/protobuf/text_format.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/unittest_mset.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/file.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> - -namespace google { -namespace protobuf { -namespace { - -inline bool IsNaN(double value) { - // NaN is never equal to anything, even itself. - return value != value; -} - -// A basic string with different escapable characters for testing. -const string kEscapeTestString = - "\"A string with ' characters \n and \r newlines and \t tabs and \001 " - "slashes \\"; - -// A representation of the above string with all the characters escaped. -const string kEscapeTestStringEscaped = - "\"\\\"A string with \\' characters \\n and \\r newlines " - "and \\t tabs and \\001 slashes \\\\\""; - -class TextFormatTest : public testing::Test { - public: - static void SetUpTestCase() { - File::ReadFileToStringOrDie( - TestSourceDir() - + "/google/protobuf/testdata/text_format_unittest_data.txt", - &static_proto_debug_string_); - } - - TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {} - - protected: - // Debug string read from text_format_unittest_data.txt. - const string proto_debug_string_; - unittest::TestAllTypes proto_; - - private: - static string static_proto_debug_string_; -}; -string TextFormatTest::static_proto_debug_string_; - -class TextFormatExtensionsTest : public testing::Test { - public: - static void SetUpTestCase() { - File::ReadFileToStringOrDie( - TestSourceDir() - + "/google/protobuf/testdata/" - "text_format_unittest_extensions_data.txt", - &static_proto_debug_string_); - } - - TextFormatExtensionsTest() - : proto_debug_string_(static_proto_debug_string_) {} - - protected: - // Debug string read from text_format_unittest_data.txt. - const string proto_debug_string_; - unittest::TestAllExtensions proto_; - - private: - static string static_proto_debug_string_; -}; -string TextFormatExtensionsTest::static_proto_debug_string_; - - -TEST_F(TextFormatTest, Basic) { - TestUtil::SetAllFields(&proto_); - EXPECT_EQ(proto_debug_string_, proto_.DebugString()); -} - -TEST_F(TextFormatExtensionsTest, Extensions) { - TestUtil::SetAllExtensions(&proto_); - EXPECT_EQ(proto_debug_string_, proto_.DebugString()); -} - -TEST_F(TextFormatTest, StringEscape) { - // Set the string value to test. - proto_.set_optional_string(kEscapeTestString); - - // Get the DebugString from the proto. - string debug_string = proto_.DebugString(); - - // Hardcode a correct value to test against. - string correct_string = "optional_string: " - + kEscapeTestStringEscaped - + "\n"; - - // Compare. - EXPECT_EQ(correct_string, debug_string); -} - -TEST_F(TextFormatTest, PrintUnknownFields) { - // Test printing of unknown fields in a message. - - unittest::TestEmptyMessage message; - UnknownFieldSet* unknown_fields = message.mutable_unknown_fields(); - UnknownField* field5 = unknown_fields->AddField(5); - - field5->add_varint(1); - field5->add_fixed32(2); - field5->add_fixed64(3); - field5->add_length_delimited("4"); - field5->add_group()->AddField(10)->add_varint(5); - - UnknownField* field8 = unknown_fields->AddField(8); - field8->add_varint(1); - field8->add_varint(2); - field8->add_varint(3); - - EXPECT_EQ( - "5: 1\n" - "5: 0x00000002\n" - "5: 0x0000000000000003\n" - "5: \"4\"\n" - "5 {\n" - " 10: 5\n" - "}\n" - "8: 1\n" - "8: 2\n" - "8: 3\n", - message.DebugString()); -} - -TEST_F(TextFormatTest, PrintUnknownMessage) { - // Test heuristic printing of messages in an UnknownFieldSet. - - protobuf_unittest::TestAllTypes message; - - // Cases which should not be interpreted as sub-messages. - - // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message - // it should be followed by 8 bytes. Since this string only has two - // subsequent bytes, it should be treated as a string. - message.add_repeated_string("abc"); - - // 'd' happens to be a valid ENDGROUP tag. So, - // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but - // the ConsumedEntireMessage() check should fail. - message.add_repeated_string("def"); - - // A zero-length string should never be interpreted as a message even though - // it is technically valid as one. - message.add_repeated_string(""); - - // Case which should be interpreted as a sub-message. - - // An actual nested message with content should always be interpreted as a - // nested message. - message.add_repeated_nested_message()->set_bb(123); - - string data; - message.SerializeToString(&data); - - string text; - UnknownFieldSet unknown_fields; - EXPECT_TRUE(unknown_fields.ParseFromString(data)); - EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text)); - EXPECT_EQ( - "44: \"abc\"\n" - "44: \"def\"\n" - "44: \"\"\n" - "48 {\n" - " 1: 123\n" - "}\n", - text); -} - -TEST_F(TextFormatTest, ParseBasic) { - io::ArrayInputStream input_stream(proto_debug_string_.data(), - proto_debug_string_.size()); - TextFormat::Parse(&input_stream, &proto_); - TestUtil::ExpectAllFieldsSet(proto_); -} - -TEST_F(TextFormatExtensionsTest, ParseExtensions) { - io::ArrayInputStream input_stream(proto_debug_string_.data(), - proto_debug_string_.size()); - TextFormat::Parse(&input_stream, &proto_); - TestUtil::ExpectAllExtensionsSet(proto_); -} - -TEST_F(TextFormatTest, ParseStringEscape) { - // Create a parse string with escpaed characters in it. - string parse_string = "optional_string: " - + kEscapeTestStringEscaped - + "\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(kEscapeTestString, proto_.optional_string()); -} - -TEST_F(TextFormatTest, ParseFloatWithSuffix) { - // Test that we can parse a floating-point value with 'f' appended to the - // end. This is needed for backwards-compatibility with proto1. - - // Have it parse a float with the 'f' suffix. - string parse_string = "optional_float: 1.0f\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(1.0, proto_.optional_float()); -} - -TEST_F(TextFormatTest, Comments) { - // Test that comments are ignored. - - string parse_string = "optional_int32: 1 # a comment\n" - "optional_int64: 2 # another comment"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_EQ(1, proto_.optional_int32()); - EXPECT_EQ(2, proto_.optional_int64()); -} - -TEST_F(TextFormatTest, OptionalColon) { - // Test that we can place a ':' after the field name of a nested message, - // even though we don't have to. - - string parse_string = "optional_nested_message: { bb: 1}\n"; - - io::ArrayInputStream input_stream(parse_string.data(), - parse_string.size()); - - TextFormat::Parse(&input_stream, &proto_); - - // Compare. - EXPECT_TRUE(proto_.has_optional_nested_message()); - EXPECT_EQ(1, proto_.optional_nested_message().bb()); -} - -// Some platforms (e.g. Windows) insist on padding the exponent to three -// digits when one or two would be just fine. -static string RemoveRedundantZeros(string text) { - text = StringReplace(text, "e+0", "e+", true); - text = StringReplace(text, "e-0", "e-", true); - return text; -} - -TEST_F(TextFormatTest, PrintExotic) { - unittest::TestAllTypes message; - - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and - // 9223372036854775808 is outside the range of int64. However, it is not - // outside the range of uint64. Confusingly, this means that everything - // works if we make the literal unsigned, even though we are negating it. - message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808)); - message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615)); - message.add_repeated_double(123.456); - message.add_repeated_double(1.23e21); - message.add_repeated_double(1.23e-18); - message.add_repeated_double(std::numeric_limits<double>::infinity()); - message.add_repeated_double(-std::numeric_limits<double>::infinity()); - message.add_repeated_double(std::numeric_limits<double>::quiet_NaN()); - message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12)); - - // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this - // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of - // the value differed from strtod()'s parsing. That is to say, the - // following assertion fails on MinGW: - // assert(1.23e22 == strtod("1.23e22", NULL)); - // As a result, SimpleDtoa() would print the value as - // "1.2300000000000001e+22" to make sure strtod() produce the exact same - // result. Our goal is to test runtime parsing, not compile-time parsing, - // so this wasn't our problem. It was found that using 1.23e21 did not - // have this problem, so we switched to that instead. - - EXPECT_EQ( - "repeated_int64: -9223372036854775808\n" - "repeated_uint64: 18446744073709551615\n" - "repeated_double: 123.456\n" - "repeated_double: 1.23e+21\n" - "repeated_double: 1.23e-18\n" - "repeated_double: inf\n" - "repeated_double: -inf\n" - "repeated_double: nan\n" - "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n", - RemoveRedundantZeros(message.DebugString())); -} - -TEST_F(TextFormatTest, PrintFloatPrecision) { - unittest::TestAllTypes message; - - message.add_repeated_float(1.2); - message.add_repeated_float(1.23); - message.add_repeated_float(1.234); - message.add_repeated_float(1.2345); - message.add_repeated_float(1.23456); - message.add_repeated_float(1.2e10); - message.add_repeated_float(1.23e10); - message.add_repeated_float(1.234e10); - message.add_repeated_float(1.2345e10); - message.add_repeated_float(1.23456e10); - message.add_repeated_double(1.2); - message.add_repeated_double(1.23); - message.add_repeated_double(1.234); - message.add_repeated_double(1.2345); - message.add_repeated_double(1.23456); - message.add_repeated_double(1.234567); - message.add_repeated_double(1.2345678); - message.add_repeated_double(1.23456789); - message.add_repeated_double(1.234567898); - message.add_repeated_double(1.2345678987); - message.add_repeated_double(1.23456789876); - message.add_repeated_double(1.234567898765); - message.add_repeated_double(1.2345678987654); - message.add_repeated_double(1.23456789876543); - message.add_repeated_double(1.2e100); - message.add_repeated_double(1.23e100); - message.add_repeated_double(1.234e100); - message.add_repeated_double(1.2345e100); - message.add_repeated_double(1.23456e100); - message.add_repeated_double(1.234567e100); - message.add_repeated_double(1.2345678e100); - message.add_repeated_double(1.23456789e100); - message.add_repeated_double(1.234567898e100); - message.add_repeated_double(1.2345678987e100); - message.add_repeated_double(1.23456789876e100); - message.add_repeated_double(1.234567898765e100); - message.add_repeated_double(1.2345678987654e100); - message.add_repeated_double(1.23456789876543e100); - - EXPECT_EQ( - "repeated_float: 1.2\n" - "repeated_float: 1.23\n" - "repeated_float: 1.234\n" - "repeated_float: 1.2345\n" - "repeated_float: 1.23456\n" - "repeated_float: 1.2e+10\n" - "repeated_float: 1.23e+10\n" - "repeated_float: 1.234e+10\n" - "repeated_float: 1.2345e+10\n" - "repeated_float: 1.23456e+10\n" - "repeated_double: 1.2\n" - "repeated_double: 1.23\n" - "repeated_double: 1.234\n" - "repeated_double: 1.2345\n" - "repeated_double: 1.23456\n" - "repeated_double: 1.234567\n" - "repeated_double: 1.2345678\n" - "repeated_double: 1.23456789\n" - "repeated_double: 1.234567898\n" - "repeated_double: 1.2345678987\n" - "repeated_double: 1.23456789876\n" - "repeated_double: 1.234567898765\n" - "repeated_double: 1.2345678987654\n" - "repeated_double: 1.23456789876543\n" - "repeated_double: 1.2e+100\n" - "repeated_double: 1.23e+100\n" - "repeated_double: 1.234e+100\n" - "repeated_double: 1.2345e+100\n" - "repeated_double: 1.23456e+100\n" - "repeated_double: 1.234567e+100\n" - "repeated_double: 1.2345678e+100\n" - "repeated_double: 1.23456789e+100\n" - "repeated_double: 1.234567898e+100\n" - "repeated_double: 1.2345678987e+100\n" - "repeated_double: 1.23456789876e+100\n" - "repeated_double: 1.234567898765e+100\n" - "repeated_double: 1.2345678987654e+100\n" - "repeated_double: 1.23456789876543e+100\n", - RemoveRedundantZeros(message.DebugString())); -} - - -TEST_F(TextFormatTest, AllowPartial) { - unittest::TestRequired message; - TextFormat::Parser parser; - parser.AllowPartialMessage(true); - EXPECT_TRUE(parser.ParseFromString("a: 1", &message)); - EXPECT_EQ(1, message.a()); - EXPECT_FALSE(message.has_b()); - EXPECT_FALSE(message.has_c()); -} - -TEST_F(TextFormatTest, ParseExotic) { - unittest::TestAllTypes message; - ASSERT_TRUE(TextFormat::ParseFromString( - "repeated_int32: -1\n" - "repeated_int32: -2147483648\n" - "repeated_int64: -1\n" - "repeated_int64: -9223372036854775808\n" - "repeated_uint32: 4294967295\n" - "repeated_uint32: 2147483648\n" - "repeated_uint64: 18446744073709551615\n" - "repeated_uint64: 9223372036854775808\n" - "repeated_double: 123.0\n" - "repeated_double: 123.5\n" - "repeated_double: 0.125\n" - "repeated_double: 1.23E17\n" - "repeated_double: 1.235E+22\n" - "repeated_double: 1.235e-18\n" - "repeated_double: 123.456789\n" - "repeated_double: inf\n" - "repeated_double: Infinity\n" - "repeated_double: -inf\n" - "repeated_double: -Infinity\n" - "repeated_double: nan\n" - "repeated_double: NaN\n" - "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n", - &message)); - - ASSERT_EQ(2, message.repeated_int32_size()); - EXPECT_EQ(-1, message.repeated_int32(0)); - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and 2147483648 is - // outside the range of int32. However, it is not outside the range of - // uint32. Confusingly, this means that everything works if we make the - // literal unsigned, even though we are negating it. - EXPECT_EQ(-2147483648u, message.repeated_int32(1)); - - ASSERT_EQ(2, message.repeated_int64_size()); - EXPECT_EQ(-1, message.repeated_int64(0)); - // Note: In C, a negative integer literal is actually the unary negation - // operator being applied to a positive integer literal, and - // 9223372036854775808 is outside the range of int64. However, it is not - // outside the range of uint64. Confusingly, this means that everything - // works if we make the literal unsigned, even though we are negating it. - EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1)); - - ASSERT_EQ(2, message.repeated_uint32_size()); - EXPECT_EQ(4294967295u, message.repeated_uint32(0)); - EXPECT_EQ(2147483648u, message.repeated_uint32(1)); - - ASSERT_EQ(2, message.repeated_uint64_size()); - EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0)); - EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1)); - - ASSERT_EQ(13, message.repeated_double_size()); - EXPECT_EQ(123.0 , message.repeated_double(0)); - EXPECT_EQ(123.5 , message.repeated_double(1)); - EXPECT_EQ(0.125 , message.repeated_double(2)); - EXPECT_EQ(1.23E17 , message.repeated_double(3)); - EXPECT_EQ(1.235E22 , message.repeated_double(4)); - EXPECT_EQ(1.235E-18 , message.repeated_double(5)); - EXPECT_EQ(123.456789, message.repeated_double(6)); - EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity()); - EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity()); - EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity()); - EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity()); - EXPECT_TRUE(IsNaN(message.repeated_double(11))); - EXPECT_TRUE(IsNaN(message.repeated_double(12))); - - // Note: Since these string literals have \0's in them, we must explicitly - // pass their sizes to string's constructor. - ASSERT_EQ(1, message.repeated_string_size()); - EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12), - message.repeated_string(0)); -} - -class TextFormatParserTest : public testing::Test { - protected: - void ExpectFailure(const string& input, const string& message, int line, - int col) { - unittest::TestAllTypes proto; - ExpectFailure(input, message, line, col, &proto); - } - - void ExpectFailure(const string& input, const string& message, int line, - int col, Message* proto) { - TextFormat::Parser parser; - MockErrorCollector error_collector; - parser.RecordErrorsTo(&error_collector); - EXPECT_FALSE(parser.ParseFromString(input, proto)); - EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n", - error_collector.text_); - } - - // An error collector which simply concatenates all its errors into a big - // block of text which can be checked. - class MockErrorCollector : public io::ErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector ------------------------------------- - void AddError(int line, int column, const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", - line + 1, column + 1, message); - } - }; -}; - -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("\"some string\"", "Expected identifier.", 1, 1); -} - -TEST_F(TextFormatParserTest, InvalidFieldName) { - ExpectFailure( - "invalid_field: somevalue\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"invalid_field\".", - 1, 14); -} - -TEST_F(TextFormatParserTest, InvalidCapitalization) { - // We require that group names be exactly as they appear in the .proto. - ExpectFailure( - "optionalgroup {\na: 15\n}\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"optionalgroup\".", - 1, 15); - ExpectFailure( - "OPTIONALgroup {\na: 15\n}\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"OPTIONALgroup\".", - 1, 15); - ExpectFailure( - "Optional_Double: 10.0\n", - "Message type \"protobuf_unittest.TestAllTypes\" has no field named " - "\"Optional_Double\".", - 1, 16); -} - -TEST_F(TextFormatParserTest, InvalidFieldValues) { - // Invalid values for a double/float field. - ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: true\n", "Expected double.", 1, 18); - ExpectFailure("optional_double: !\n", "Expected double.", 1, 18); - ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".", - 1, 17); - - // Invalid values for a signed integer field. - ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17); - ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".", - 1, 16); - ExpectFailure("optional_int32: 0x80000000\n", - "Integer out of range.", 1, 17); - ExpectFailure("optional_int32: -0x80000001\n", - "Integer out of range.", 1, 18); - ExpectFailure("optional_int64: 0x8000000000000000\n", - "Integer out of range.", 1, 17); - ExpectFailure("optional_int64: -0x8000000000000001\n", - "Integer out of range.", 1, 18); - - // Invalid values for an unsigned integer field. - ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18); - ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".", - 1, 17); - ExpectFailure("optional_uint32: 0x100000000\n", - "Integer out of range.", 1, 18); - ExpectFailure("optional_uint64: 0x10000000000000000\n", - "Integer out of range.", 1, 18); - - // 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: -7.5\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); - - ExpectFailure( - "optional_bool: meh\n", - "Invalid value for boolean field \"optional_bool\". Value: \"meh\".", - 2, 1); - - ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".", - 1, 15); - - // Invalid values for a string field. - ExpectFailure("optional_string: true\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18); - ExpectFailure("optional_string: !\n", "Expected string.", 1, 18); - ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".", - 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: grah\n", - "Unknown enumeration value of \"grah\" for field " - "\"optional_nested_enum\".", 2, 1); - - ExpectFailure( - "optional_nested_enum {\n \n}\n", - "Expected \":\", found \"{\".", 1, 22); -} - -TEST_F(TextFormatParserTest, MessageDelimeters) { - // Non-matching delimeters. - ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".", - 3, 1); - - // Invalid delimeters. - ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".", - 1, 15); - - // Unending message. - ExpectFailure("optional_nested_message {\n \nbb: 118\n", - "Expected identifier.", - 4, 1); -} - -TEST_F(TextFormatParserTest, UnknownExtension) { - // Non-matching delimeters. - ExpectFailure("[blahblah]: 123", - "Extension \"blahblah\" is not defined or is not an " - "extension of \"protobuf_unittest.TestAllTypes\".", - 1, 11); -} - -TEST_F(TextFormatParserTest, MissingRequired) { - unittest::TestRequired message; - ExpectFailure("a: 1", - "Message missing required fields: b, c", - 0, 1, &message); -} - -TEST_F(TextFormatParserTest, PrintErrorsToStderr) { - vector<string> errors; - - { - ScopedMemoryLog log; - unittest::TestAllTypes proto; - EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto)); - errors = log.GetMessages(ERROR); - } - - ASSERT_EQ(1, errors.size()); - EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: " - "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field " - "named \"no_such_field\".", - errors[0]); -} - - -class TextFormatMessageSetTest : public testing::Test { - protected: - static const char proto_debug_string_[]; -}; -const char TextFormatMessageSetTest::proto_debug_string_[] = -"message_set {\n" -" [protobuf_unittest.TestMessageSetExtension1] {\n" -" i: 23\n" -" }\n" -" [protobuf_unittest.TestMessageSetExtension2] {\n" -" str: \"foo\"\n" -" }\n" -"}\n"; - - -TEST_F(TextFormatMessageSetTest, Serialize) { - protobuf_unittest::TestMessageSetContainer proto; - protobuf_unittest::TestMessageSetExtension1* item_a = - proto.mutable_message_set()->MutableExtension( - protobuf_unittest::TestMessageSetExtension1::message_set_extension); - item_a->set_i(23); - protobuf_unittest::TestMessageSetExtension2* item_b = - proto.mutable_message_set()->MutableExtension( - protobuf_unittest::TestMessageSetExtension2::message_set_extension); - item_b->set_str("foo"); - EXPECT_EQ(proto_debug_string_, proto.DebugString()); -} - -TEST_F(TextFormatMessageSetTest, Deserialize) { - protobuf_unittest::TestMessageSetContainer proto; - ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto)); - EXPECT_EQ(23, proto.message_set().GetExtension( - protobuf_unittest::TestMessageSetExtension1::message_set_extension).i()); - EXPECT_EQ("foo", proto.message_set().GetExtension( - protobuf_unittest::TestMessageSetExtension2::message_set_extension).str()); - - // Ensure that these are the only entries present. - vector<const FieldDescriptor*> descriptors; - proto.message_set().GetReflection()->ListFields( - proto.message_set(), &descriptors); - EXPECT_EQ(2, descriptors.size()); -} - -} // namespace -} // namespace protobuf - -} // namespace google diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto deleted file mode 100644 index a37fd402..00000000 --- a/src/google/protobuf/unittest.proto +++ /dev/null @@ -1,454 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file we will use for unit testing. - -option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; -option csharp_file_classname = "UnitTestProtoFile"; - -import "google/protobuf/unittest_import.proto"; - -// 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. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; - -option java_outer_classname = "UnittestProto"; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessage optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessage optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnum optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR ]; - optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum = 83 [default = IMPORT_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestAllExtensions { - extensions 1 to max; -} - -extend TestAllExtensions { - // Singular - optional int32 optional_int32_extension = 1; - optional int64 optional_int64_extension = 2; - optional uint32 optional_uint32_extension = 3; - optional uint64 optional_uint64_extension = 4; - optional sint32 optional_sint32_extension = 5; - optional sint64 optional_sint64_extension = 6; - optional fixed32 optional_fixed32_extension = 7; - optional fixed64 optional_fixed64_extension = 8; - optional sfixed32 optional_sfixed32_extension = 9; - optional sfixed64 optional_sfixed64_extension = 10; - optional float optional_float_extension = 11; - optional double optional_double_extension = 12; - optional bool optional_bool_extension = 13; - optional string optional_string_extension = 14; - optional bytes optional_bytes_extension = 15; - - optional group OptionalGroup_extension = 16 { - optional int32 a = 17; - } - - optional TestAllTypes.NestedMessage optional_nested_message_extension = 18; - optional ForeignMessage optional_foreign_message_extension = 19; - optional protobuf_unittest_import.ImportMessage - optional_import_message_extension = 20; - - optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21; - optional ForeignEnum optional_foreign_enum_extension = 22; - optional protobuf_unittest_import.ImportEnum - optional_import_enum_extension = 23; - - optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE]; - optional string optional_cord_extension = 25 [ctype=CORD]; - - // Repeated - repeated int32 repeated_int32_extension = 31; - repeated int64 repeated_int64_extension = 32; - repeated uint32 repeated_uint32_extension = 33; - repeated uint64 repeated_uint64_extension = 34; - repeated sint32 repeated_sint32_extension = 35; - repeated sint64 repeated_sint64_extension = 36; - repeated fixed32 repeated_fixed32_extension = 37; - repeated fixed64 repeated_fixed64_extension = 38; - repeated sfixed32 repeated_sfixed32_extension = 39; - repeated sfixed64 repeated_sfixed64_extension = 40; - repeated float repeated_float_extension = 41; - repeated double repeated_double_extension = 42; - repeated bool repeated_bool_extension = 43; - repeated string repeated_string_extension = 44; - repeated bytes repeated_bytes_extension = 45; - - repeated group RepeatedGroup_extension = 46 { - optional int32 a = 47; - } - - repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48; - repeated ForeignMessage repeated_foreign_message_extension = 49; - repeated protobuf_unittest_import.ImportMessage - repeated_import_message_extension = 50; - - repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51; - repeated ForeignEnum repeated_foreign_enum_extension = 52; - repeated protobuf_unittest_import.ImportEnum - repeated_import_enum_extension = 53; - - repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord_extension = 55 [ctype=CORD]; - - // Singular with defaults - optional int32 default_int32_extension = 61 [default = 41 ]; - optional int64 default_int64_extension = 62 [default = 42 ]; - optional uint32 default_uint32_extension = 63 [default = 43 ]; - optional uint64 default_uint64_extension = 64 [default = 44 ]; - optional sint32 default_sint32_extension = 65 [default = -45 ]; - optional sint64 default_sint64_extension = 66 [default = 46 ]; - optional fixed32 default_fixed32_extension = 67 [default = 47 ]; - optional fixed64 default_fixed64_extension = 68 [default = 48 ]; - optional sfixed32 default_sfixed32_extension = 69 [default = 49 ]; - optional sfixed64 default_sfixed64_extension = 70 [default = -50 ]; - optional float default_float_extension = 71 [default = 51.5 ]; - optional double default_double_extension = 72 [default = 52e3 ]; - optional bool default_bool_extension = 73 [default = true ]; - optional string default_string_extension = 74 [default = "hello"]; - optional bytes default_bytes_extension = 75 [default = "world"]; - - optional TestAllTypes.NestedEnum - default_nested_enum_extension = 81 [default = BAR]; - optional ForeignEnum - default_foreign_enum_extension = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum_extension = 83 [default = IMPORT_BAR]; - - optional string default_string_piece_extension = 84 [ctype=STRING_PIECE, - default="abc"]; - optional string default_cord_extension = 85 [ctype=CORD, default="123"]; -} - -// We have separate messages for testing required fields because it's -// annoying to have to fill in required fields in TestProto in order to -// do anything with it. Note that we don't need to test every type of -// required filed because the code output is basically identical to -// optional fields for all types. -message TestRequired { - required int32 a = 1; - optional int32 dummy2 = 2; - required int32 b = 3; - - extend TestAllExtensions { - optional TestRequired single = 1000; - repeated TestRequired multi = 1001; - } - - // Pad the field count to 32 so that we can test that IsInitialized() - // properly checks multiple elements of has_bits_. - optional int32 dummy4 = 4; - optional int32 dummy5 = 5; - optional int32 dummy6 = 6; - optional int32 dummy7 = 7; - optional int32 dummy8 = 8; - optional int32 dummy9 = 9; - optional int32 dummy10 = 10; - optional int32 dummy11 = 11; - optional int32 dummy12 = 12; - optional int32 dummy13 = 13; - optional int32 dummy14 = 14; - optional int32 dummy15 = 15; - optional int32 dummy16 = 16; - optional int32 dummy17 = 17; - optional int32 dummy18 = 18; - optional int32 dummy19 = 19; - optional int32 dummy20 = 20; - optional int32 dummy21 = 21; - optional int32 dummy22 = 22; - optional int32 dummy23 = 23; - optional int32 dummy24 = 24; - optional int32 dummy25 = 25; - optional int32 dummy26 = 26; - optional int32 dummy27 = 27; - optional int32 dummy28 = 28; - optional int32 dummy29 = 29; - optional int32 dummy30 = 30; - optional int32 dummy31 = 31; - optional int32 dummy32 = 32; - - required int32 c = 33; -} - -message TestRequiredForeign { - optional TestRequired optional_message = 1; - repeated TestRequired repeated_message = 2; - optional int32 dummy = 3; -} - -// Test that we can use NestedMessage from outside TestAllTypes. -message TestForeignNested { - optional TestAllTypes.NestedMessage foreign_nested = 1; -} - -// TestEmptyMessage is used to test unknown field support. -message TestEmptyMessage { -} - -// Like above, but declare all field numbers as potential extensions. No -// actual extensions should ever be defined for this type. -message TestEmptyMessageWithExtensions { - extensions 1 to max; -} - -// Test that really large tag numbers don't break anything. -message TestReallyLargeTagNumber { - // The largest possible tag number is 2^28 - 1, since the wire format uses - // three bits to communicate wire type. - optional int32 a = 1; - optional int32 bb = 268435455; -} - -message TestRecursiveMessage { - optional TestRecursiveMessage a = 1; - optional int32 i = 2; -} - -// Test that mutual recursion works. -message TestMutualRecursionA { - optional TestMutualRecursionB bb = 1; -} - -message TestMutualRecursionB { - optional TestMutualRecursionA a = 1; - optional int32 optional_int32 = 2; -} - -// Test that groups have disjoint field numbers from their siblings and -// parents. This is NOT possible in proto1; only proto2. When outputting -// proto1, the dup fields should be dropped. -message TestDupFieldNumber { - optional int32 a = 1; - optional group Foo = 2 { optional int32 a = 1; } - optional group Bar = 3 { optional int32 a = 1; } -} - - -// Needed for a Python test. -message TestNestedMessageHasBits { - message NestedMessage { - repeated int32 nestedmessage_repeated_int32 = 1; - repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2; - } - optional NestedMessage optional_nested_message = 1; -} - - -// Test an enum that has multiple values with the same number. -enum TestEnumWithDupValue { - FOO1 = 1; - BAR1 = 2; - BAZ = 3; - FOO2 = 1; - BAR2 = 2; -} - -// Test an enum with large, unordered values. -enum TestSparseEnum { - SPARSE_A = 123; - SPARSE_B = 62374; - SPARSE_C = 12589234; - SPARSE_D = -15; - SPARSE_E = -53452; - SPARSE_F = 0; - SPARSE_G = 2; -} - -// Test message with CamelCase field names. This violates Protocol Buffer -// standard style. -message TestCamelCaseFieldNames { - optional int32 PrimitiveField = 1; - optional string StringField = 2; - optional ForeignEnum EnumField = 3; - optional ForeignMessage MessageField = 4; - optional string StringPieceField = 5 [ctype=STRING_PIECE]; - optional string CordField = 6 [ctype=CORD]; - - repeated int32 RepeatedPrimitiveField = 7; - repeated string RepeatedStringField = 8; - repeated ForeignEnum RepeatedEnumField = 9; - repeated ForeignMessage RepeatedMessageField = 10; - repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE]; - repeated string RepeatedCordField = 12 [ctype=CORD]; -} - - -// We list fields out of order, to ensure that we're using field number and not -// field index to determine serialization order. -message TestFieldOrderings { - optional string my_string = 11; - extensions 2 to 10; - optional int64 my_int = 1; - extensions 12 to 100; - optional float my_float = 101; -} - - -extend TestFieldOrderings { - optional string my_extension_string = 50; - optional int32 my_extension_int = 5; -} - - -message TestExtremeDefaultValues { - optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"]; - optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF]; - optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF]; - optional int32 small_int32 = 4 [default = -0x7FFFFFFF]; - optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF]; - - // The default value here is UTF-8 for "\u1234". (We could also just type - // the UTF-8 text directly into this text file rather than escape it, but - // lots of people use editors that would be confused by this.) - optional string utf8_string = 6 [default = "\341\210\264"]; -} - -// Test that RPC services work. -message FooRequest {} -message FooResponse {} - -service TestService { - rpc Foo(FooRequest) returns (FooResponse); - rpc Bar(BarRequest) returns (BarResponse); -} - - -message BarRequest {} -message BarResponse {} diff --git a/src/google/protobuf/unittest_embed_optimize_for.proto b/src/google/protobuf/unittest_embed_optimize_for.proto deleted file mode 100644 index f2b9d815..00000000 --- a/src/google/protobuf/unittest_embed_optimize_for.proto +++ /dev/null @@ -1,39 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which imports a proto file that uses optimize_for = CODE_SIZE. - -import "google/protobuf/unittest_optimize_for.proto"; - -package protobuf_unittest; - -option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; -option csharp_file_classname = "UnitTestEmbedOptimizeForProtoFile"; - -// We optimize for speed here, but we are importing a proto that is optimized -// for code size. -option optimize_for = SPEED; - -message TestEmbedOptimizedForSize { - // Test that embedding a message which has optimize_for = CODE_SIZE into - // one optimized for speed works. - optional TestOptimizedForSize optional_message = 1; - repeated TestOptimizedForSize repeated_message = 2; -} diff --git a/src/google/protobuf/unittest_import.proto b/src/google/protobuf/unittest_import.proto deleted file mode 100644 index 64495c78..00000000 --- a/src/google/protobuf/unittest_import.proto +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which is imported by unittest.proto to test importing. - - -// 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. -// In test_util.h we do -// "using namespace unittest_import = protobuf_unittest_import". -package protobuf_unittest_import; - -option optimize_for = SPEED; - -// Exercise the java_package option. -option java_package = "com.google.protobuf.test"; - -option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; -option csharp_file_classname = "UnitTestImportProtoFile"; - -// Do not set a java_outer_classname here to verify that Proto2 works without -// one. - -message ImportMessage { - optional int32 d = 1; -} - -enum ImportEnum { - IMPORT_FOO = 7; - IMPORT_BAR = 8; - IMPORT_BAZ = 9; -} - diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto deleted file mode 100644 index 4d0b3b1e..00000000 --- a/src/google/protobuf/unittest_mset.proto +++ /dev/null @@ -1,61 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains messages for testing message_set_wire_format. - -package protobuf_unittest; - -option optimize_for = SPEED; - -option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; -option csharp_file_classname = "UnitTestMessageSetProtoFile"; - -// A message with message_set_wire_format. -message TestMessageSet { - option message_set_wire_format = true; - extensions 4 to max; -} - -message TestMessageSetContainer { - optional TestMessageSet message_set = 1; -} - -message TestMessageSetExtension1 { - extend TestMessageSet { - optional TestMessageSetExtension1 message_set_extension = 1545008; - } - optional int32 i = 15; -} - -message TestMessageSetExtension2 { - extend TestMessageSet { - optional TestMessageSetExtension2 message_set_extension = 1547769; - } - optional string str = 25; -} - -// MessageSet wire format is equivalent to this. -message RawMessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required bytes message = 3; - } -} - diff --git a/src/google/protobuf/unittest_optimize_for.proto b/src/google/protobuf/unittest_optimize_for.proto deleted file mode 100644 index cccfe233..00000000 --- a/src/google/protobuf/unittest_optimize_for.proto +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// A proto file which uses optimize_for = CODE_SIZE. - -import "google/protobuf/unittest.proto"; - -package protobuf_unittest; - -option optimize_for = CODE_SIZE; - -option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; -option csharp_file_classname = "UnitTestOptimizeForProtoFile"; - -message TestOptimizedForSize { - optional int32 i = 1; - optional ForeignMessage msg = 19; - - extensions 1000 to max; - - extend TestOptimizedForSize { - optional int32 test_extension = 1234; - } -} - -message TestRequiredOptimizedForSize { - required int32 x = 1; -} - -message TestOptionalOptimizedForSize { - optional TestRequiredOptimizedForSize o = 1; -} diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc deleted file mode 100644 index 3d45002e..00000000 --- a/src/google/protobuf/unknown_field_set.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/unknown_field_set.h> -#include <google/protobuf/stubs/stl_util-inl.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/wire_format.h> - -namespace google { -namespace protobuf { - -UnknownFieldSet::UnknownFieldSet() - : internal_(NULL) {} - -UnknownFieldSet::~UnknownFieldSet() { - if (internal_ != NULL) { - STLDeleteValues(&internal_->fields_); - delete internal_; - } -} - -void UnknownFieldSet::Clear() { - if (internal_ == NULL) return; - - if (internal_->fields_.size() > kMaxInactiveFields) { - STLDeleteValues(&internal_->fields_); - } else { - // Don't delete the UnknownField objects. Just remove them from the active - // set. - for (int i = 0; i < internal_->active_fields_.size(); i++) { - internal_->active_fields_[i]->Clear(); - internal_->active_fields_[i]->index_ = -1; - } - } - - internal_->active_fields_.clear(); -} - -void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { - for (int i = 0; i < other.field_count(); i++) { - AddField(other.field(i).number())->MergeFrom(other.field(i)); - } -} - -bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) { - - UnknownFieldSet other; - if (internal::WireFormat::SkipMessage(input, &other) && - input->ConsumedEntireMessage()) { - MergeFrom(other); - return true; - } else { - return false; - } -} - -bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) { - Clear(); - return MergeFromCodedStream(input); -} - -bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { - io::CodedInputStream coded_input(input); - return ParseFromCodedStream(&coded_input) && - coded_input.ConsumedEntireMessage(); -} - -bool UnknownFieldSet::ParseFromArray(const void* data, int size) { - io::ArrayInputStream input(data, size); - return ParseFromZeroCopyStream(&input); -} - -const UnknownField* UnknownFieldSet::FindFieldByNumber(int number) const { - if (internal_ == NULL) return NULL; - - map<int, UnknownField*>::iterator iter = internal_->fields_.find(number); - if (iter != internal_->fields_.end() && iter->second->index() != -1) { - return iter->second; - } else { - return NULL; - } -} - -UnknownField* UnknownFieldSet::AddField(int number) { - if (internal_ == NULL) internal_ = new Internal; - - UnknownField** map_slot = &internal_->fields_[number]; - if (*map_slot == NULL) { - *map_slot = new UnknownField(number); - } - - UnknownField* field = *map_slot; - if (field->index() == -1) { - field->index_ = internal_->active_fields_.size(); - internal_->active_fields_.push_back(field); - } - return field; -} - -UnknownField::UnknownField(int number) - : number_(number), - index_(-1) { -} - -UnknownField::~UnknownField() { -} - -void UnknownField::Clear() { - clear_varint(); - clear_fixed32(); - clear_fixed64(); - clear_length_delimited(); - clear_group(); -} - -void UnknownField::MergeFrom(const UnknownField& other) { - varint_ .MergeFrom(other.varint_ ); - fixed32_ .MergeFrom(other.fixed32_ ); - fixed64_ .MergeFrom(other.fixed64_ ); - length_delimited_.MergeFrom(other.length_delimited_); - group_ .MergeFrom(other.group_ ); -} - -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h deleted file mode 100644 index a3dce33d..00000000 --- a/src/google/protobuf/unknown_field_set.h +++ /dev/null @@ -1,333 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// Contains classes used to keep track of unrecognized fields seen while -// parsing a protocol message. - -#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ -#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ - -#include <string> -#include <map> -#include <vector> -#include <google/protobuf/repeated_field.h> - -namespace google { -namespace protobuf { - -class Message; // message.h -class UnknownField; // below - -// An UnknownFieldSet contains fields that were encountered while parsing a -// message but were not defined by its type. Keeping track of these can be -// useful, especially in that they may be written if the message is serialized -// again without being cleared in between. This means that software which -// simply receives messages and forwards them to other servers does not need -// to be updated every time a new field is added to the message definition. -// -// To get the UnknownFieldSet attached to any message, call -// Reflection::GetUnknownFields(). -// -// This class is necessarily tied to the protocol buffer wire format, unlike -// the Reflection interface which is independent of any serialization scheme. -class LIBPROTOBUF_EXPORT UnknownFieldSet { - public: - UnknownFieldSet(); - ~UnknownFieldSet(); - - // Remove all fields. - void Clear(); - - // Is this set empty? - inline bool empty() const; - - // Merge the contents of some other UnknownFieldSet with this one. - void MergeFrom(const UnknownFieldSet& other); - - // Returns the number of fields present in the UnknownFieldSet. - inline int field_count() const; - // Get a field in the set, where 0 <= index < field_count(). The fields - // appear in arbitrary order. - inline const UnknownField& field(int index) const; - // Get a mutable pointer to a field in the set, where - // 0 <= index < field_count(). The fields appear in arbitrary order. - inline UnknownField* mutable_field(int index); - - // Find a field by field number. Returns NULL if not found. - const UnknownField* FindFieldByNumber(int number) const; - - // Add a field by field number. If the field number already exists, returns - // the existing UnknownField. - UnknownField* AddField(int number); - - // Parsing helpers ------------------------------------------------- - // These work exactly like the similarly-named methods of Message. - - bool MergeFromCodedStream(io::CodedInputStream* input); - bool ParseFromCodedStream(io::CodedInputStream* input); - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); - bool ParseFromArray(const void* data, int size); - inline bool ParseFromString(const string& data) { - return ParseFromArray(data.data(), data.size()); - } - - private: - // "Active" fields are ones which have been added since the last time Clear() - // was called. Inactive fields are objects we are keeping around incase - // they become active again. - - struct Internal { - // Contains all UnknownFields that have been allocated for this - // UnknownFieldSet, including ones not currently active. Keyed by - // field number. We intentionally try to reuse UnknownField objects for - // the same field number they were used for originally because this makes - // it more likely that the previously-allocated memory will have the right - // layout. - map<int, UnknownField*> fields_; - - // Contains the fields from fields_ that are currently active. - vector<UnknownField*> active_fields_; - }; - - // We want an UnknownFieldSet to use no more space than a single pointer - // until the first field is added. - Internal* internal_; - - // Don't keep more inactive fields than this. - static const int kMaxInactiveFields = 100; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet); -}; - -// Represents one field in an UnknownFieldSet. -// -// UnknownFiled's accessors are similar to those that would be produced by the -// protocol compiler for the fields: -// repeated uint64 varint; -// repeated fixed32 fixed32; -// repeated fixed64 fixed64; -// repeated bytes length_delimited; -// repeated UnknownFieldSet group; -// (OK, so the last one isn't actually a valid field type but you get the -// idea.) -class LIBPROTOBUF_EXPORT UnknownField { - public: - ~UnknownField(); - - // Clears all fields. - void Clear(); - - // Merge the contents of some other UnknownField with this one. For each - // wire type, the values are simply concatenated. - void MergeFrom(const UnknownField& other); - - // The field's tag number, as seen on the wire. - inline int number() const; - - // The index of this UnknownField within the UknownFieldSet (e.g. - // set.field(field.index()) == field). - inline int index() const; - - inline int varint_size () const; - inline int fixed32_size () const; - inline int fixed64_size () const; - inline int length_delimited_size() const; - inline int group_size () const; - - inline uint64 varint (int index) const; - inline uint32 fixed32(int index) const; - inline uint64 fixed64(int index) const; - inline const string& length_delimited(int index) const; - inline const UnknownFieldSet& group(int index) const; - - inline void set_varint (int index, uint64 value); - inline void set_fixed32(int index, uint32 value); - inline void set_fixed64(int index, uint64 value); - inline void set_length_delimited(int index, const string& value); - inline string* mutable_length_delimited(int index); - inline UnknownFieldSet* mutable_group(int index); - - inline void add_varint (uint64 value); - inline void add_fixed32(uint32 value); - inline void add_fixed64(uint64 value); - inline void add_length_delimited(const string& value); - inline string* add_length_delimited(); - inline UnknownFieldSet* add_group(); - - inline void clear_varint (); - inline void clear_fixed32(); - inline void clear_fixed64(); - inline void clear_length_delimited(); - inline void clear_group(); - - inline const RepeatedField <uint64 >& varint () const; - inline const RepeatedField <uint32 >& fixed32 () const; - inline const RepeatedField <uint64 >& fixed64 () const; - inline const RepeatedPtrField<string >& length_delimited() const; - inline const RepeatedPtrField<UnknownFieldSet>& group () const; - - inline RepeatedField <uint64 >* mutable_varint (); - inline RepeatedField <uint32 >* mutable_fixed32 (); - inline RepeatedField <uint64 >* mutable_fixed64 (); - inline RepeatedPtrField<string >* mutable_length_delimited(); - inline RepeatedPtrField<UnknownFieldSet>* mutable_group (); - - private: - friend class UnknownFieldSet; - UnknownField(int number); - - int number_; - int index_; - - RepeatedField <uint64 > varint_; - RepeatedField <uint32 > fixed32_; - RepeatedField <uint64 > fixed64_; - RepeatedPtrField<string > length_delimited_; - RepeatedPtrField<UnknownFieldSet> group_; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownField); -}; - -// =================================================================== -// inline implementations - -inline bool UnknownFieldSet::empty() const { - return internal_ == NULL || internal_->active_fields_.empty(); -} - -inline int UnknownFieldSet::field_count() const { - return (internal_ == NULL) ? 0 : internal_->active_fields_.size(); -} -inline const UnknownField& UnknownFieldSet::field(int index) const { - return *(internal_->active_fields_[index]); -} -inline UnknownField* UnknownFieldSet::mutable_field(int index) { - return internal_->active_fields_[index]; -} - -inline int UnknownField::number() const { return number_; } -inline int UnknownField::index () const { return index_; } - -inline int UnknownField::varint_size () const {return varint_.size();} -inline int UnknownField::fixed32_size () const {return fixed32_.size();} -inline int UnknownField::fixed64_size () const {return fixed64_.size();} -inline int UnknownField::length_delimited_size() const { - return length_delimited_.size(); -} -inline int UnknownField::group_size () const {return group_.size();} - -inline uint64 UnknownField::varint (int index) const { - return varint_.Get(index); -} -inline uint32 UnknownField::fixed32(int index) const { - return fixed32_.Get(index); -} -inline uint64 UnknownField::fixed64(int index) const { - return fixed64_.Get(index); -} -inline const string& UnknownField::length_delimited(int index) const { - return length_delimited_.Get(index); -} -inline const UnknownFieldSet& UnknownField::group(int index) const { - return group_.Get(index); -} - -inline void UnknownField::set_varint (int index, uint64 value) { - varint_.Set(index, value); -} -inline void UnknownField::set_fixed32(int index, uint32 value) { - fixed32_.Set(index, value); -} -inline void UnknownField::set_fixed64(int index, uint64 value) { - fixed64_.Set(index, value); -} -inline void UnknownField::set_length_delimited(int index, const string& value) { - length_delimited_.Mutable(index)->assign(value); -} -inline string* UnknownField::mutable_length_delimited(int index) { - return length_delimited_.Mutable(index); -} -inline UnknownFieldSet* UnknownField::mutable_group(int index) { - return group_.Mutable(index); -} - -inline void UnknownField::add_varint (uint64 value) { - varint_.Add(value); -} -inline void UnknownField::add_fixed32(uint32 value) { - fixed32_.Add(value); -} -inline void UnknownField::add_fixed64(uint64 value) { - fixed64_.Add(value); -} -inline void UnknownField::add_length_delimited(const string& value) { - length_delimited_.Add()->assign(value); -} -inline string* UnknownField::add_length_delimited() { - return length_delimited_.Add(); -} -inline UnknownFieldSet* UnknownField::add_group() { - return group_.Add(); -} - -inline void UnknownField::clear_varint () { varint_.Clear(); } -inline void UnknownField::clear_fixed32() { varint_.Clear(); } -inline void UnknownField::clear_fixed64() { varint_.Clear(); } -inline void UnknownField::clear_length_delimited() { - length_delimited_.Clear(); -} -inline void UnknownField::clear_group() { group_.Clear(); } - -inline const RepeatedField<uint64>& UnknownField::varint () const { - return varint_; -} -inline const RepeatedField<uint32>& UnknownField::fixed32() const { - return fixed32_; -} -inline const RepeatedField<uint64>& UnknownField::fixed64() const { - return fixed64_; -} -inline const RepeatedPtrField<string>& UnknownField::length_delimited() const { - return length_delimited_; -} -inline const RepeatedPtrField<UnknownFieldSet>& UnknownField::group() const { - return group_; -} - -inline RepeatedField<uint64>* UnknownField::mutable_varint () { - return &varint_; -} -inline RepeatedField<uint32>* UnknownField::mutable_fixed32() { - return &fixed32_; -} -inline RepeatedField<uint64>* UnknownField::mutable_fixed64() { - return &fixed64_; -} -inline RepeatedPtrField<string>* UnknownField::mutable_length_delimited() { - return &length_delimited_; -} -inline RepeatedPtrField<UnknownFieldSet>* UnknownField::mutable_group() { - return &group_; -} - -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__ diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc deleted file mode 100644 index 63f1dffd..00000000 --- a/src/google/protobuf/unknown_field_set_unittest.cc +++ /dev/null @@ -1,417 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This test is testing a lot more than just the UnknownFieldSet class. It -// tests handling of unknown fields throughout the system. - -#include <google/protobuf/unknown_field_set.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { - -using internal::WireFormat; - -namespace { - -class UnknownFieldSetTest : public testing::Test { - protected: - virtual void SetUp() { - descriptor_ = unittest::TestAllTypes::descriptor(); - TestUtil::SetAllFields(&all_fields_); - all_fields_.SerializeToString(&all_fields_data_); - ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_)); - unknown_fields_ = empty_message_.mutable_unknown_fields(); - } - - const UnknownField* GetField(const string& name) { - const FieldDescriptor* field = descriptor_->FindFieldByName(name); - if (field == NULL) return NULL; - return unknown_fields_->FindFieldByNumber(field->number()); - } - - // Constructs a protocol buffer which contains fields with all the same - // numbers as all_fields_data_ except that each field is some other wire - // type. - string GetBizarroData() { - unittest::TestEmptyMessage bizarro_message; - UnknownFieldSet* bizarro_unknown_fields = - bizarro_message.mutable_unknown_fields(); - for (int i = 0; i < unknown_fields_->field_count(); i++) { - const UnknownField& unknown_field = unknown_fields_->field(i); - UnknownField* bizarro_field = - bizarro_unknown_fields->AddField(unknown_field.number()); - if (unknown_field.varint_size() == 0) { - bizarro_field->add_varint(1); - } else { - bizarro_field->add_fixed32(1); - } - } - - string data; - EXPECT_TRUE(bizarro_message.SerializeToString(&data)); - return data; - } - - const Descriptor* descriptor_; - unittest::TestAllTypes all_fields_; - string all_fields_data_; - - // An empty message that has been parsed from all_fields_data_. So, it has - // unknown fields of every type. - unittest::TestEmptyMessage empty_message_; - UnknownFieldSet* unknown_fields_; -}; - -TEST_F(UnknownFieldSetTest, Index) { - for (int i = 0; i < unknown_fields_->field_count(); i++) { - EXPECT_EQ(i, unknown_fields_->field(i).index()); - } -} - -TEST_F(UnknownFieldSetTest, FindFieldByNumber) { - // All fields of TestAllTypes should be present. Fields that are not valid - // field numbers of TestAllTypes should NOT be present. - - for (int i = 0; i < 1000; i++) { - if (descriptor_->FindFieldByNumber(i) == NULL) { - EXPECT_TRUE(unknown_fields_->FindFieldByNumber(i) == NULL); - } else { - EXPECT_TRUE(unknown_fields_->FindFieldByNumber(i) != NULL); - } - } -} - -TEST_F(UnknownFieldSetTest, Varint) { - const UnknownField* field = GetField("optional_int32"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(1, field->varint_size()); - EXPECT_EQ(all_fields_.optional_int32(), field->varint(0)); -} - -TEST_F(UnknownFieldSetTest, Fixed32) { - const UnknownField* field = GetField("optional_fixed32"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(1, field->fixed32_size()); - EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32(0)); -} - -TEST_F(UnknownFieldSetTest, Fixed64) { - const UnknownField* field = GetField("optional_fixed64"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(1, field->fixed64_size()); - EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64(0)); -} - -TEST_F(UnknownFieldSetTest, LengthDelimited) { - const UnknownField* field = GetField("optional_string"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(1, field->length_delimited_size()); - EXPECT_EQ(all_fields_.optional_string(), field->length_delimited(0)); -} - -TEST_F(UnknownFieldSetTest, Group) { - const UnknownField* field = GetField("optionalgroup"); - ASSERT_TRUE(field != NULL); - - ASSERT_EQ(1, field->group_size()); - EXPECT_EQ(1, field->group(0).field_count()); - - const UnknownField& nested_field = field->group(0).field(0); - const FieldDescriptor* nested_field_descriptor = - unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a"); - ASSERT_TRUE(nested_field_descriptor != NULL); - - EXPECT_EQ(nested_field_descriptor->number(), nested_field.number()); - EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint(0)); -} - -TEST_F(UnknownFieldSetTest, Serialize) { - // Check that serializing the UnknownFieldSet produces the original data - // again. - - string data; - empty_message_.SerializeToString(&data); - - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(data == all_fields_data_); -} - -TEST_F(UnknownFieldSetTest, ParseViaReflection) { - // Make sure fields are properly parsed to the UnknownFieldSet when parsing - // via reflection. - - unittest::TestEmptyMessage message; - io::ArrayInputStream raw_input(all_fields_data_.data(), - all_fields_data_.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, SerializeViaReflection) { - // Make sure fields are properly written from the UnknownFieldSet when - // serializing via reflection. - - string data; - - { - io::StringOutputStream raw_output(&data); - io::CodedOutputStream output(&raw_output); - int size = WireFormat::ByteSize(empty_message_); - ASSERT_TRUE( - WireFormat::SerializeWithCachedSizes(empty_message_, size, &output)); - } - - // Don't use EXPECT_EQ because we don't want to dump raw binary data to - // stdout. - EXPECT_TRUE(data == all_fields_data_); -} - -TEST_F(UnknownFieldSetTest, CopyFrom) { - unittest::TestEmptyMessage message; - - message.CopyFrom(empty_message_); - - EXPECT_EQ(empty_message_.DebugString(), message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, MergeFrom) { - unittest::TestEmptyMessage source, destination; - - destination.mutable_unknown_fields()->AddField(1)->add_varint(1); - destination.mutable_unknown_fields()->AddField(3)->add_varint(2); - source.mutable_unknown_fields()->AddField(2)->add_varint(3); - source.mutable_unknown_fields()->AddField(3)->add_varint(4); - - destination.MergeFrom(source); - - EXPECT_EQ( - // Note: The ordering of fields here depends on the ordering of adds - // and merging, above. - "1: 1\n" - "3: 2\n" - "3: 4\n" - "2: 3\n", - destination.DebugString()); -} - -TEST_F(UnknownFieldSetTest, Clear) { - // Get a pointer to a contained field object. - const UnknownField* field = GetField("optional_int32"); - ASSERT_TRUE(field != NULL); - ASSERT_EQ(1, field->varint_size()); - int number = field->number(); - - // Clear the set. - empty_message_.Clear(); - EXPECT_EQ(0, unknown_fields_->field_count()); - - // If we add that field again we should get the same object. - ASSERT_EQ(field, unknown_fields_->AddField(number)); - - // But it should be cleared. - EXPECT_EQ(0, field->varint_size()); -} - -TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) { - // Test mixing known and unknown fields when parsing. - - unittest::TestEmptyMessage source; - source.mutable_unknown_fields()->AddField(123456)->add_varint(654321); - string data; - ASSERT_TRUE(source.SerializeToString(&data)); - - unittest::TestAllTypes destination; - ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data)); - - TestUtil::ExpectAllFieldsSet(destination); - ASSERT_EQ(1, destination.unknown_fields().field_count()); - ASSERT_EQ(1, destination.unknown_fields().field(0).varint_size()); - EXPECT_EQ(654321, destination.unknown_fields().field(0).varint(0)); -} - -TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) { - // Test that fields of the wrong wire type are treated like unknown fields - // when parsing. - - unittest::TestAllTypes all_types_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - // All fields should have been interpreted as unknown, so the debug strings - // should be the same. - EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) { - // Same as WrongTypeTreatedAsUnknown but via the reflection interface. - - unittest::TestAllTypes all_types_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownExtensions) { - // Make sure fields are properly parsed to the UnknownFieldSet even when - // they are declared as extension numbers. - - unittest::TestEmptyMessageWithExtensions message; - ASSERT_TRUE(message.ParseFromString(all_fields_data_)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) { - // Same as UnknownExtensions except parsing via reflection. - - unittest::TestEmptyMessageWithExtensions message; - io::ArrayInputStream raw_input(all_fields_data_.data(), - all_fields_data_.size()); - io::CodedInputStream input(&raw_input); - ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message)); - - EXPECT_EQ(message.DebugString(), empty_message_.DebugString()); -} - -TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) { - // Test that fields of the wrong wire type are treated like unknown fields - // when parsing extensions. - - unittest::TestAllExtensions all_extensions_message; - unittest::TestEmptyMessage empty_message; - string bizarro_data = GetBizarroData(); - ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data)); - ASSERT_TRUE(empty_message.ParseFromString(bizarro_data)); - - // All fields should have been interpreted as unknown, so the debug strings - // should be the same. - EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString()); -} - -TEST_F(UnknownFieldSetTest, UnknownEnumValue) { - using unittest::TestAllTypes; - using unittest::TestAllExtensions; - using unittest::TestEmptyMessage; - - const FieldDescriptor* singular_field = - TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum"); - const FieldDescriptor* repeated_field = - TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum"); - ASSERT_TRUE(singular_field != NULL); - ASSERT_TRUE(repeated_field != NULL); - - string data; - - { - TestEmptyMessage empty_message; - UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); - UnknownField* singular_unknown_field = - unknown_fields->AddField(singular_field->number()); - singular_unknown_field->add_varint(TestAllTypes::BAR); - singular_unknown_field->add_varint(5); // not valid - UnknownField* repeated_unknown_field = - unknown_fields->AddField(repeated_field->number()); - repeated_unknown_field->add_varint(TestAllTypes::FOO); - repeated_unknown_field->add_varint(4); // not valid - repeated_unknown_field->add_varint(TestAllTypes::BAZ); - repeated_unknown_field->add_varint(6); // not valid - empty_message.SerializeToString(&data); - } - - { - TestAllTypes message; - ASSERT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum()); - ASSERT_EQ(2, message.repeated_nested_enum_size()); - EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0)); - EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1)); - - const UnknownFieldSet& unknown_fields = message.unknown_fields(); - ASSERT_EQ(2, unknown_fields.field_count()); - - const UnknownField& singular_unknown_field = unknown_fields.field(0); - ASSERT_EQ(singular_field->number(), singular_unknown_field.number()); - ASSERT_EQ(1, singular_unknown_field.varint_size()); - EXPECT_EQ(5, singular_unknown_field.varint(0)); - - const UnknownField& repeated_unknown_field = unknown_fields.field(1); - ASSERT_EQ(repeated_field->number(), repeated_unknown_field.number()); - ASSERT_EQ(2, repeated_unknown_field.varint_size()); - EXPECT_EQ(4, repeated_unknown_field.varint(0)); - EXPECT_EQ(6, repeated_unknown_field.varint(1)); - } - - { - using unittest::optional_nested_enum_extension; - using unittest::repeated_nested_enum_extension; - - TestAllExtensions message; - ASSERT_TRUE(message.ParseFromString(data)); - EXPECT_EQ(TestAllTypes::BAR, - message.GetExtension(optional_nested_enum_extension)); - ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension)); - EXPECT_EQ(TestAllTypes::FOO, - message.GetExtension(repeated_nested_enum_extension, 0)); - EXPECT_EQ(TestAllTypes::BAZ, - message.GetExtension(repeated_nested_enum_extension, 1)); - - const UnknownFieldSet& unknown_fields = message.unknown_fields(); - ASSERT_EQ(2, unknown_fields.field_count()); - - const UnknownField& singular_unknown_field = unknown_fields.field(0); - ASSERT_EQ(singular_field->number(), singular_unknown_field.number()); - ASSERT_EQ(1, singular_unknown_field.varint_size()); - EXPECT_EQ(5, singular_unknown_field.varint(0)); - - const UnknownField& repeated_unknown_field = unknown_fields.field(1); - ASSERT_EQ(repeated_field->number(), repeated_unknown_field.number()); - ASSERT_EQ(2, repeated_unknown_field.varint_size()); - EXPECT_EQ(4, repeated_unknown_field.varint(0)); - EXPECT_EQ(6, repeated_unknown_field.varint(1)); - } -} - -} // namespace -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc deleted file mode 100644 index 5f87c103..00000000 --- a/src/google/protobuf/wire_format.cc +++ /dev/null @@ -1,824 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <stack> -#include <string> -#include <vector> - -#include <google/protobuf/wire_format_inl.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/unknown_field_set.h> - -namespace google { -namespace protobuf { -namespace internal { - -namespace { - -// This function turns out to be convenient when using some macros later. -inline int GetEnumNumber(const EnumValueDescriptor* descriptor) { - return descriptor->number(); -} - -// These are the tags for the old MessageSet format, which was defined as: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// } -// } -const int kMessageSetItemStartTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_START_GROUP); -const int kMessageSetItemEndTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(1, WireFormat::WIRETYPE_END_GROUP); -const int kMessageSetTypeIdTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(2, WireFormat::WIRETYPE_VARINT); -const int kMessageSetMessageTag = - GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(3, WireFormat::WIRETYPE_LENGTH_DELIMITED); - -// Byte size of all tags of a MessageSet::Item combined. -static const int kMessageSetItemTagsSize = - io::CodedOutputStream::VarintSize32(kMessageSetItemStartTag) + - io::CodedOutputStream::VarintSize32(kMessageSetItemEndTag) + - io::CodedOutputStream::VarintSize32(kMessageSetTypeIdTag) + - io::CodedOutputStream::VarintSize32(kMessageSetMessageTag); - -} // anonymous namespace - -const WireFormat::WireType -WireFormat::kWireTypeForFieldType[FieldDescriptor::MAX_TYPE + 1] = { - static_cast<WireFormat::WireType>(-1), // invalid - WIRETYPE_FIXED64, // TYPE_DOUBLE - WIRETYPE_FIXED32, // TYPE_FLOAT - WIRETYPE_VARINT, // TYPE_INT64 - WIRETYPE_VARINT, // TYPE_UINT64 - WIRETYPE_VARINT, // TYPE_INT32 - WIRETYPE_FIXED64, // TYPE_FIXED64 - WIRETYPE_FIXED32, // TYPE_FIXED32 - WIRETYPE_VARINT, // TYPE_BOOL - WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING - WIRETYPE_START_GROUP, // TYPE_GROUP - WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE - WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES - WIRETYPE_VARINT, // TYPE_UINT32 - WIRETYPE_VARINT, // TYPE_ENUM - WIRETYPE_FIXED32, // TYPE_SFIXED32 - WIRETYPE_FIXED64, // TYPE_SFIXED64 - WIRETYPE_VARINT, // TYPE_SINT32 - WIRETYPE_VARINT, // TYPE_SINT64 -}; - -// =================================================================== - -bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, - UnknownFieldSet* unknown_fields) { - UnknownField* field = (unknown_fields == NULL) ? NULL : - unknown_fields->AddField(GetTagFieldNumber(tag)); - - switch (GetTagWireType(tag)) { - case WIRETYPE_VARINT: { - uint64 value; - if (!input->ReadVarint64(&value)) return false; - if (field != NULL) field->add_varint(value); - return true; - } - case WIRETYPE_FIXED64: { - uint64 value; - if (!input->ReadLittleEndian64(&value)) return false; - if (field != NULL) field->add_fixed64(value); - return true; - } - case WIRETYPE_LENGTH_DELIMITED: { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (field == NULL) { - if (!input->Skip(length)) return false; - } else { - if (!input->ReadString(field->add_length_delimited(), length)) { - return false; - } - } - return true; - } - case WIRETYPE_START_GROUP: { - if (!input->IncrementRecursionDepth()) return false; - if (!SkipMessage(input, (field == NULL) ? NULL : field->add_group())) { - return false; - } - input->DecrementRecursionDepth(); - // Check that the ending tag matched the starting tag. - if (!input->LastTagWas( - MakeTag(GetTagFieldNumber(tag), WIRETYPE_END_GROUP))) { - return false; - } - return true; - } - case WIRETYPE_END_GROUP: { - return false; - } - case WIRETYPE_FIXED32: { - uint32 value; - if (!input->ReadLittleEndian32(&value)) return false; - if (field != NULL) field->add_fixed32(value); - return true; - } - default: { - return false; - } - } -} - -bool WireFormat::SkipMessage(io::CodedInputStream* input, - UnknownFieldSet* unknown_fields) { - while(true) { - uint32 tag = input->ReadTag(); - if (tag == 0) { - // End of input. This is a valid place to end, so return true. - return true; - } - - WireType wire_type = GetTagWireType(tag); - - if (wire_type == WIRETYPE_END_GROUP) { - // Must be the end of the message. - return true; - } - - if (!SkipField(input, tag, unknown_fields)) return false; - } -} - -bool WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - -#define DO(EXPRESSION) if (!(EXPRESSION)) return false - for (int j = 0; j < field.varint_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_VARINT))); - DO(output->WriteVarint64(field.varint(j))); - } - for (int j = 0; j < field.fixed32_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED32))); - DO(output->WriteLittleEndian32(field.fixed32(j))); - } - for (int j = 0; j < field.fixed64_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_FIXED64))); - DO(output->WriteLittleEndian64(field.fixed64(j))); - } - for (int j = 0; j < field.length_delimited_size(); j++) { - DO(output->WriteVarint32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED))); - DO(output->WriteVarint32(field.length_delimited(j).size())); - DO(output->WriteString(field.length_delimited(j))); - } - for (int j = 0; j < field.group_size(); j++) { - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_START_GROUP))); - DO(SerializeUnknownFields(field.group(j), output)); - DO(output->WriteVarint32(MakeTag(field.number(), WIRETYPE_END_GROUP))); - } -#undef DO - } - - return true; -} - -bool WireFormat::SerializeUnknownMessageSetItems( - const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output) { - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - -#define DO(EXPRESSION) if (!(EXPRESSION)) return false - // The only unknown fields that are allowed to exist in a MessageSet are - // messages, which are length-delimited. - for (int j = 0; j < field.length_delimited_size(); j++) { - const string& data = field.length_delimited(j); - - // Start group. - DO(output->WriteVarint32(kMessageSetItemStartTag)); - - // Write type ID. - DO(output->WriteVarint32(kMessageSetTypeIdTag)); - DO(output->WriteVarint32(field.number())); - - // Write message. - DO(output->WriteVarint32(kMessageSetMessageTag)); - DO(output->WriteVarint32(data.size())); - DO(output->WriteString(data)); - - // End group. - DO(output->WriteVarint32(kMessageSetItemEndTag)); - } -#undef DO - } - - return true; -} - -int WireFormat::ComputeUnknownFieldsSize( - const UnknownFieldSet& unknown_fields) { - int size = 0; - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - for (int j = 0; j < field.varint_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_VARINT)); - size += io::CodedOutputStream::VarintSize64(field.varint(j)); - } - for (int j = 0; j < field.fixed32_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED32)); - size += sizeof(int32); - } - for (int j = 0; j < field.fixed64_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_FIXED64)); - size += sizeof(int64); - } - for (int j = 0; j < field.length_delimited_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_LENGTH_DELIMITED)); - size += io::CodedOutputStream::VarintSize32( - field.length_delimited(j).size()); - size += field.length_delimited(j).size(); - } - for (int j = 0; j < field.group_size(); j++) { - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_START_GROUP)); - size += ComputeUnknownFieldsSize(field.group(j)); - size += io::CodedOutputStream::VarintSize32( - MakeTag(field.number(), WIRETYPE_END_GROUP)); - } - } - - return size; -} - -int WireFormat::ComputeUnknownMessageSetItemsSize( - const UnknownFieldSet& unknown_fields) { - int size = 0; - for (int i = 0; i < unknown_fields.field_count(); i++) { - const UnknownField& field = unknown_fields.field(i); - - // The only unknown fields that are allowed to exist in a MessageSet are - // messages, which are length-delimited. - for (int j = 0; j < field.length_delimited_size(); j++) { - size += kMessageSetItemTagsSize; - size += io::CodedOutputStream::VarintSize32(field.number()); - size += io::CodedOutputStream::VarintSize32( - field.length_delimited(j).size()); - size += field.length_delimited(j).size(); - } - } - - return size; -} - -// =================================================================== - -bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, - Message* message) { - const Descriptor* descriptor = message->GetDescriptor(); - const Reflection* message_reflection = message->GetReflection(); - - while(true) { - uint32 tag = input->ReadTag(); - if (tag == 0) { - // End of input. This is a valid place to end, so return true. - return true; - } - - if (GetTagWireType(tag) == WIRETYPE_END_GROUP) { - // Must be the end of the message. - return true; - } - - const FieldDescriptor* field = NULL; - - if (descriptor != NULL) { - int field_number = GetTagFieldNumber(tag); - field = descriptor->FindFieldByNumber(field_number); - - // If that failed, check if the field is an extension. - if (field == NULL && descriptor->IsExtensionNumber(field_number)) { - field = message_reflection->FindKnownExtensionByNumber(field_number); - } - - // If that failed, but we're a MessageSet, and this is the tag for a - // MessageSet item, then parse that. - if (field == NULL && - descriptor->options().message_set_wire_format() && - tag == kMessageSetItemStartTag) { - if (!ParseAndMergeMessageSetItem(input, message)) { - return false; - } - continue; // Skip ParseAndMergeField(); already taken care of. - } - } - - if (!ParseAndMergeField(tag, field, message, input)) { - return false; - } - } -} - -bool WireFormat::ParseAndMergeField( - uint32 tag, - const FieldDescriptor* field, // May be NULL for unknown - Message* message, - io::CodedInputStream* input) { - const Reflection* message_reflection = message->GetReflection(); - - if (field == NULL || - GetTagWireType(tag) != WireTypeForFieldType(field->type())) { - // We don't recognize this field. Either the field number is unknown - // or the wire type doesn't match. Put it in our unknown field set. - return SkipField(input, tag, - message_reflection->MutableUnknownFields(message)); - } - - switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - CPPTYPE value; \ - if (!Read##TYPE_METHOD(input, &value)) return false; \ - if (field->is_repeated()) { \ - message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ - } else { \ - message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ - } \ - break; \ - } - - HANDLE_TYPE( INT32, Int32, int32, Int32) - HANDLE_TYPE( INT64, Int64, int64, Int64) - HANDLE_TYPE(SINT32, SInt32, int32, Int32) - HANDLE_TYPE(SINT64, SInt64, int64, Int64) - HANDLE_TYPE(UINT32, UInt32, uint32, UInt32) - HANDLE_TYPE(UINT64, UInt64, uint64, UInt64) - - HANDLE_TYPE( FIXED32, Fixed32, uint32, UInt32) - HANDLE_TYPE( FIXED64, Fixed64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, SFixed32, int32, Int32) - HANDLE_TYPE(SFIXED64, SFixed64, int64, Int64) - - HANDLE_TYPE(FLOAT , Float , float , Float ) - HANDLE_TYPE(DOUBLE, Double, double, Double) - - HANDLE_TYPE(BOOL, Bool, bool, Bool) - - HANDLE_TYPE(STRING, String, string, String) - HANDLE_TYPE(BYTES, Bytes, string, String) - -#undef HANDLE_TYPE - - case FieldDescriptor::TYPE_ENUM: { - int value; - if (!ReadEnum(input, &value)) return false; - const EnumValueDescriptor* enum_value = - field->enum_type()->FindValueByNumber(value); - if (enum_value != NULL) { - if (field->is_repeated()) { - message_reflection->AddEnum(message, field, enum_value); - } else { - message_reflection->SetEnum(message, field, enum_value); - } - } else { - // The enum value is not one of the known values. Add it to the - // UnknownFieldSet. - int64 sign_extended_value = static_cast<int64>(value); - message_reflection->MutableUnknownFields(message) - ->AddField(GetTagFieldNumber(tag)) - ->add_varint(sign_extended_value); - } - break; - } - - - case FieldDescriptor::TYPE_GROUP: { - Message* sub_message; - if (field->is_repeated()) { - sub_message = message_reflection->AddMessage(message, field); - } else { - sub_message = message_reflection->MutableMessage(message, field); - } - - if (!ReadGroup(GetTagFieldNumber(tag), input, sub_message)) return false; - break; - } - - case FieldDescriptor::TYPE_MESSAGE: { - Message* sub_message; - if (field->is_repeated()) { - sub_message = message_reflection->AddMessage(message, field); - } else { - sub_message = message_reflection->MutableMessage(message, field); - } - - if (!ReadMessage(input, sub_message)) return false; - break; - } - } - - return true; -} - -bool WireFormat::ParseAndMergeMessageSetItem( - io::CodedInputStream* input, - Message* message) { - const Reflection* message_reflection = message->GetReflection(); - - // This method parses a group which should contain two fields: - // required int32 type_id = 2; - // required data message = 3; - - // Once we see a type_id, we'll construct a fake tag for this extension - // which is the tag it would have had under the proto2 extensions wire - // format. - uint32 fake_tag = 0; - - // Once we see a type_id, we'll look up the FieldDescriptor for the - // extension. - const FieldDescriptor* field = NULL; - - // If we see message data before the type_id, we'll append it to this so - // we can parse it later. This will probably never happen in practice, - // as no MessageSet encoder I know of writes the message before the type ID. - // But, it's technically valid so we should allow it. - // TODO(kenton): Use a Cord instead? Do I care? - string message_data; - - while (true) { - uint32 tag = input->ReadTag(); - if (tag == 0) return false; - - switch (tag) { - case kMessageSetTypeIdTag: { - uint32 type_id; - if (!input->ReadVarint32(&type_id)) return false; - fake_tag = MakeTag(type_id, WIRETYPE_LENGTH_DELIMITED); - field = message_reflection->FindKnownExtensionByNumber(type_id); - - if (!message_data.empty()) { - // We saw some message data before the type_id. Have to parse it - // now. - io::ArrayInputStream raw_input(message_data.data(), - message_data.size()); - io::CodedInputStream sub_input(&raw_input); - if (!ParseAndMergeField(fake_tag, field, message, - &sub_input)) { - return false; - } - message_data.clear(); - } - - break; - } - - case kMessageSetMessageTag: { - if (fake_tag == 0) { - // We haven't seen a type_id yet. Append this data to message_data. - string temp; - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->ReadString(&temp, length)) return false; - message_data.append(temp); - } else { - // Already saw type_id, so we can parse this directly. - if (!ParseAndMergeField(fake_tag, field, message, input)) { - return false; - } - } - - break; - } - - case kMessageSetItemEndTag: { - return true; - } - - default: { - if (!SkipField(input, tag, NULL)) return false; - } - } - } -} - -// =================================================================== - -bool WireFormat::SerializeWithCachedSizes( - const Message& message, - int size, io::CodedOutputStream* output) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* message_reflection = message.GetReflection(); - int expected_endpoint = output->ByteCount() + size; - - vector<const FieldDescriptor*> fields; - message_reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - if (!SerializeFieldWithCachedSizes(fields[i], message, output)) { - return false; - } - } - - if (descriptor->options().message_set_wire_format()) { - if (!SerializeUnknownMessageSetItems( - message_reflection->GetUnknownFields(message), output)) { - return false; - } - } else { - if (!SerializeUnknownFields( - message_reflection->GetUnknownFields(message), output)) { - return false; - } - } - - GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint) - << ": Protocol message serialized to a size different from what was " - "originally expected. Perhaps it was modified by another thread " - "during serialization?"; - - return true; -} - -bool WireFormat::SerializeFieldWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output) { - const Reflection* message_reflection = message.GetReflection(); - - if (field->is_extension() && - field->containing_type()->options().message_set_wire_format() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_repeated()) { - return SerializeMessageSetItemWithCachedSizes( - field, message, output); - } - - int count = 0; - - if (field->is_repeated()) { - count = message_reflection->FieldSize(message, field); - } else if (message_reflection->HasField(message, field)) { - count = 1; - } - - for (int j = 0; j < count; j++) { - switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - if (!Write##TYPE_METHOD( \ - field->number(), \ - field->is_repeated() ? \ - message_reflection->GetRepeated##CPPTYPE_METHOD( \ - message, field, j) : \ - message_reflection->Get##CPPTYPE_METHOD(message, field), \ - output)) { \ - return false; \ - } \ - break; - - HANDLE_TYPE( INT32, Int32, Int32) - HANDLE_TYPE( INT64, Int64, Int64) - HANDLE_TYPE(SINT32, SInt32, Int32) - HANDLE_TYPE(SINT64, SInt64, Int64) - HANDLE_TYPE(UINT32, UInt32, UInt32) - HANDLE_TYPE(UINT64, UInt64, UInt64) - - HANDLE_TYPE( FIXED32, Fixed32, UInt32) - HANDLE_TYPE( FIXED64, Fixed64, UInt64) - HANDLE_TYPE(SFIXED32, SFixed32, Int32) - HANDLE_TYPE(SFIXED64, SFixed64, Int64) - - HANDLE_TYPE(FLOAT , Float , Float ) - HANDLE_TYPE(DOUBLE, Double, Double) - - HANDLE_TYPE(BOOL, Bool, Bool) - - HANDLE_TYPE(GROUP , Group , Message) - HANDLE_TYPE(MESSAGE, Message, Message) -#undef HANDLE_TYPE - - case FieldDescriptor::TYPE_ENUM: { - const EnumValueDescriptor* value = field->is_repeated() ? - message_reflection->GetRepeatedEnum(message, field, j) : - message_reflection->GetEnum(message, field); - if (!WriteEnum(field->number(), value->number(), output)) return false; - break; - } - - // Handle strings separately so that we can get string references - // instead of copying. - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - if (!WriteString(field->number(), value, output)) return false; - break; - } - } - } - - return true; -} - -bool WireFormat::SerializeMessageSetItemWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output) { - const Reflection* message_reflection = message.GetReflection(); - - // Start group. - if (!output->WriteVarint32(kMessageSetItemStartTag)) return false; - - // Write type ID. - if (!output->WriteVarint32(kMessageSetTypeIdTag)) return false; - if (!output->WriteVarint32(field->number())) return false; - - // Write message. - if (!output->WriteVarint32(kMessageSetMessageTag)) return false; - - const Message& sub_message = message_reflection->GetMessage(message, field); - if (!output->WriteVarint32(sub_message.GetCachedSize())) return false; - if (!sub_message.SerializeWithCachedSizes(output)) return false; - - // End group. - if (!output->WriteVarint32(kMessageSetItemEndTag)) return false; - - return true; -} - -// =================================================================== - -int WireFormat::ByteSize(const Message& message) { - const Descriptor* descriptor = message.GetDescriptor(); - const Reflection* message_reflection = message.GetReflection(); - - int our_size = 0; - - vector<const FieldDescriptor*> fields; - message_reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - our_size += FieldByteSize(fields[i], message); - } - - if (descriptor->options().message_set_wire_format()) { - our_size += ComputeUnknownMessageSetItemsSize( - message_reflection->GetUnknownFields(message)); - } else { - our_size += ComputeUnknownFieldsSize( - message_reflection->GetUnknownFields(message)); - } - - return our_size; -} - -int WireFormat::FieldByteSize( - const FieldDescriptor* field, - const Message& message) { - const Reflection* message_reflection = message.GetReflection(); - - if (field->is_extension() && - field->containing_type()->options().message_set_wire_format() && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_repeated()) { - return MessageSetItemByteSize(field, message); - } - - int our_size = 0; - - int count = 0; - - if (field->is_repeated()) { - count = message_reflection->FieldSize(message, field); - } else if (message_reflection->HasField(message, field)) { - count = 1; - } - - our_size += count * TagSize(field->number(), field->type()); - - switch (field->type()) { -#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - if (field->is_repeated()) { \ - for (int j = 0; j < count; j++) { \ - our_size += TYPE_METHOD##Size( \ - message_reflection->GetRepeated##CPPTYPE_METHOD( \ - message, field, j)); \ - } \ - } else { \ - our_size += TYPE_METHOD##Size( \ - message_reflection->Get##CPPTYPE_METHOD(message, field)); \ - } \ - break; - -#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: \ - our_size += count * k##TYPE_METHOD##Size; \ - break; - - HANDLE_TYPE( INT32, Int32, Int32) - HANDLE_TYPE( INT64, Int64, Int64) - HANDLE_TYPE(SINT32, SInt32, Int32) - HANDLE_TYPE(SINT64, SInt64, Int64) - HANDLE_TYPE(UINT32, UInt32, UInt32) - HANDLE_TYPE(UINT64, UInt64, UInt64) - - HANDLE_FIXED_TYPE( FIXED32, Fixed32) - HANDLE_FIXED_TYPE( FIXED64, Fixed64) - HANDLE_FIXED_TYPE(SFIXED32, SFixed32) - HANDLE_FIXED_TYPE(SFIXED64, SFixed64) - - HANDLE_FIXED_TYPE(FLOAT , Float ) - HANDLE_FIXED_TYPE(DOUBLE, Double) - - HANDLE_FIXED_TYPE(BOOL, Bool) - - HANDLE_TYPE(GROUP , Group , Message) - HANDLE_TYPE(MESSAGE, Message, Message) -#undef HANDLE_TYPE -#undef HANDLE_FIXED_TYPE - - case FieldDescriptor::TYPE_ENUM: { - if (field->is_repeated()) { - for (int j = 0; j < count; j++) { - our_size += EnumSize( - message_reflection->GetRepeatedEnum(message, field, j)->number()); - } - } else { - our_size += EnumSize( - message_reflection->GetEnum(message, field)->number()); - } - break; - } - - // Handle strings separately so that we can get string references - // instead of copying. - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: { - for (int j = 0; j < count; j++) { - string scratch; - const string& value = field->is_repeated() ? - message_reflection->GetRepeatedStringReference( - message, field, j, &scratch) : - message_reflection->GetStringReference(message, field, &scratch); - our_size += StringSize(value); - } - break; - } - } - - return our_size; -} - -int WireFormat::MessageSetItemByteSize( - const FieldDescriptor* field, - const Message& message) { - const Reflection* message_reflection = message.GetReflection(); - - int our_size = kMessageSetItemTagsSize; - - // type_id - our_size += io::CodedOutputStream::VarintSize32(field->number()); - - // message - const Message& sub_message = message_reflection->GetMessage(message, field); - int message_size = sub_message.ByteSize(); - - our_size += io::CodedOutputStream::VarintSize32(message_size); - our_size += message_size; - - return our_size; -} - -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h deleted file mode 100644 index 7e8ab5db..00000000 --- a/src/google/protobuf/wire_format.h +++ /dev/null @@ -1,443 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// atenasio@google.com (Chris Atenasio) (ZigZag transform) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This header is logically internal, but is made public because it is used -// from protocol-compiler-generated code, which may reside in other components. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__ - -#include <string> -#include <google/protobuf/message.h> -#include <google/protobuf/descriptor.h> - -namespace google { - -namespace protobuf { - namespace io { - class CodedInputStream; // coded_stream.h - class CodedOutputStream; // coded_stream.h - } - class UnknownFieldSet; // unknown_field_set.h -} - -namespace protobuf { -namespace internal { - -// This class is for internal use by the protocol buffer library and by -// protocol-complier-generated message classes. It must not be called -// directly by clients. -// -// This class contains helpers for implementing the binary protocol buffer -// wire format. These helpers are called primarily by generated code. The -// class also contains reflection-based implementations of the wire format. -// -// This class is really a namespace that contains only static methods. -class LIBPROTOBUF_EXPORT WireFormat { - public: - // These procedures can be used to implement the methods of Message which - // handle parsing and serialization of the protocol buffer wire format - // using only the Reflection interface. When you ask the protocol - // compiler to optimize for code size rather than speed, it will implement - // those methods in terms of these procedures. Of course, these are much - // slower than the specialized implementations which the protocol compiler - // generates when told to optimize for speed. - - // Read a message in protocol buffer wire format. - // - // This procedure reads either to the end of the input stream or through - // a WIRETYPE_END_GROUP tag ending the message, whichever comes first. - // It returns false if the input is invalid. - // - // Required fields are NOT checked by this method. You must call - // IsInitialized() on the resulting message yourself. - static bool ParseAndMergePartial(io::CodedInputStream* input, - Message* message); - - // Serialize a message in protocol buffer wire format. - // - // Any embedded messages within the message must have their correct sizes - // cached. However, the top-level message need not; its size is passed as - // a parameter to this procedure. - // - // These return false iff the underlying stream returns a write error. - static bool SerializeWithCachedSizes( - const Message& message, - int size, io::CodedOutputStream* output); - - // Implements Message::ByteSize() via reflection. WARNING: The result - // of this method is *not* cached anywhere. However, all embedded messages - // will have their ByteSize() methods called, so their sizes will be cached. - // Therefore, calling this method is sufficient to allow you to call - // WireFormat::SerializeWithCachedSizes() on the same object. - static int ByteSize(const Message& message); - - // ----------------------------------------------------------------- - // Helpers for dealing with unknown fields - - // Skips a field value of the given WireType. The input should start - // positioned immediately after the tag. If unknown_fields is non-NULL, - // the contents of the field will be added to it. - static bool SkipField(io::CodedInputStream* input, uint32 tag, - UnknownFieldSet* unknown_fields); - - // Reads and ignores a message from the input. If unknown_fields is non-NULL, - // the contents will be added to it. - static bool SkipMessage(io::CodedInputStream* input, - UnknownFieldSet* unknown_fields); - - // Write the contents of an UnknownFieldSet to the output. - static bool SerializeUnknownFields(const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output); - - // Same thing except for messages that have the message_set_wire_format - // option. - static bool SerializeUnknownMessageSetItems( - const UnknownFieldSet& unknown_fields, - io::CodedOutputStream* output); - - // Compute the size of the UnknownFieldSet on the wire. - static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields); - - // Same thing except for messages that have the message_set_wire_format - // option. - static int ComputeUnknownMessageSetItemsSize( - const UnknownFieldSet& unknown_fields); - - // ----------------------------------------------------------------- - // Helper constants and functions related to the format. These are - // mostly meant for internal and generated code to use. - - // The wire format is composed of a sequence of tag/value pairs, each - // of which contains the value of one field (or one element of a repeated - // field). Each tag is encoded as a varint. The lower bits of the tag - // identify its wire type, which specifies the format of the data to follow. - // The rest of the bits contain the field number. Each type of field (as - // declared by FieldDescriptor::Type, in descriptor.h) maps to one of - // these wire types. Immediately following each tag is the field's value, - // encoded in the format specified by the wire type. Because the tag - // identifies the encoding of this data, it is possible to skip - // unrecognized fields for forwards compatibility. - - enum WireType { - WIRETYPE_VARINT = 0, - WIRETYPE_FIXED64 = 1, - WIRETYPE_LENGTH_DELIMITED = 2, - WIRETYPE_START_GROUP = 3, - WIRETYPE_END_GROUP = 4, - WIRETYPE_FIXED32 = 5, - }; - - static inline WireType WireTypeForFieldType(FieldDescriptor::Type type) { - return kWireTypeForFieldType[type]; - } - - // Number of bits in a tag which identify the wire type. - static const int kTagTypeBits = 3; - // Mask for those bits. - static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; - - // Helper functions for encoding and decoding tags. (Inlined below.) - static uint32 MakeTag(const FieldDescriptor* field); - static uint32 MakeTag(int field_number, WireType type); - static WireType GetTagWireType(uint32 tag); - static int GetTagFieldNumber(uint32 tag); - - // Helper functions for converting between floats/doubles and IEEE-754 - // uint32s/uint64s so that they can be written. (Assumes your platform - // uses IEEE-754 floats.) - static uint32 EncodeFloat(float value); - static float DecodeFloat(uint32 value); - static uint64 EncodeDouble(double value); - static double DecodeDouble(uint64 value); - - // Helper functions for mapping signed integers to unsigned integers in - // such a way that numbers with small magnitudes will encode to smaller - // varints. If you simply static_cast a negative number to an unsigned - // number and varint-encode it, it will always take 10 bytes, defeating - // the purpose of varint. So, for the "sint32" and "sint64" field types, - // we ZigZag-encode the values. - static uint32 ZigZagEncode32(int32 n); - static int32 ZigZagDecode32(uint32 n); - static uint64 ZigZagEncode64(int64 n); - static int64 ZigZagDecode64(uint64 n); - - // Parse a single field. The input should start out positioned immidately - // after the tag. - static bool ParseAndMergeField( - uint32 tag, - const FieldDescriptor* field, // May be NULL for unknown - Message* message, - io::CodedInputStream* input); - - // Serialize a single field. - static bool SerializeFieldWithCachedSizes( - const FieldDescriptor* field, // Cannot be NULL - const Message& message, - io::CodedOutputStream* output); - - // Compute size of a single field. If the field is a message type, this - // will call ByteSize() for the embedded message, insuring that it caches - // its size. - static int FieldByteSize( - const FieldDescriptor* field, // Cannot be NULL - const Message& message); - - // ================================================================= - // Methods for reading/writing individual field. The implementations - // of these methods are defined in wire_format_inl.h; you must #include - // that file to use these. - -// Avoid ugly line wrapping -#define input io::CodedInputStream* input -#define output io::CodedOutputStream* output -#define field_number int field_number -#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE - - // Read fields, not including tags. The assumption is that you already - // read the tag to determine what field to read. - static inline bool ReadInt32 (input, int32* value); - static inline bool ReadInt64 (input, int64* value); - static inline bool ReadUInt32 (input, uint32* value); - static inline bool ReadUInt64 (input, uint64* value); - static inline bool ReadSInt32 (input, int32* value); - static inline bool ReadSInt64 (input, int64* value); - static inline bool ReadFixed32 (input, uint32* value); - static inline bool ReadFixed64 (input, uint64* value); - static inline bool ReadSFixed32(input, int32* value); - static inline bool ReadSFixed64(input, int64* value); - static inline bool ReadFloat (input, float* value); - static inline bool ReadDouble (input, double* value); - static inline bool ReadBool (input, bool* value); - static inline bool ReadEnum (input, int* value); - - static inline bool ReadString(input, string* value); - static inline bool ReadBytes (input, string* value); - - static inline bool ReadGroup (field_number, input, Message* value); - static inline bool ReadMessage(input, Message* value); - - // Like above, but de-virtualize the call to MergePartialFromCodedStream(). - // The pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override MergePartialFromCodedStream()). - template<typename MessageType> - static inline bool ReadGroupNoVirtual(field_number, input, - MessageType* value); - template<typename MessageType> - static inline bool ReadMessageNoVirtual(input, MessageType* value); - - // Write a tag. The Write*() functions automatically include the tag, so - // normally there's no need to call this. - static inline bool WriteTag(field_number, WireType type, output) INL; - - // Write fields, including tags. - static inline bool WriteInt32 (field_number, int32 value, output) INL; - static inline bool WriteInt64 (field_number, int64 value, output) INL; - static inline bool WriteUInt32 (field_number, uint32 value, output) INL; - static inline bool WriteUInt64 (field_number, uint64 value, output) INL; - static inline bool WriteSInt32 (field_number, int32 value, output) INL; - static inline bool WriteSInt64 (field_number, int64 value, output) INL; - static inline bool WriteFixed32 (field_number, uint32 value, output) INL; - static inline bool WriteFixed64 (field_number, uint64 value, output) INL; - static inline bool WriteSFixed32(field_number, int32 value, output) INL; - static inline bool WriteSFixed64(field_number, int64 value, output) INL; - static inline bool WriteFloat (field_number, float value, output) INL; - static inline bool WriteDouble (field_number, double value, output) INL; - static inline bool WriteBool (field_number, bool value, output) INL; - static inline bool WriteEnum (field_number, int value, output) INL; - - static inline bool WriteString(field_number, const string& value, output) INL; - static inline bool WriteBytes (field_number, const string& value, output) INL; - - static inline bool WriteGroup(field_number, const Message& value, output) INL; - static inline bool WriteMessage( - field_number, const Message& value, output) INL; - - // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override SerializeWithCachedSizes()). - template<typename MessageType> - static inline bool WriteGroupNoVirtual( - field_number, const MessageType& value, output) INL; - template<typename MessageType> - static inline bool WriteMessageNoVirtual( - field_number, const MessageType& value, output) INL; - - // Compute the byte size of a tag. For groups, this includes both the start - // and end tags. - static inline int TagSize(field_number, FieldDescriptor::Type type); - - // Compute the byte size of a field. The XxSize() functions do NOT include - // the tag, so you must also call TagSize(). (This is because, for repeated - // fields, you should only call TagSize() once and multiply it by the element - // count, but you may have to call XxSize() for each individual element.) - static inline int Int32Size ( int32 value); - static inline int Int64Size ( int64 value); - static inline int UInt32Size (uint32 value); - static inline int UInt64Size (uint64 value); - static inline int SInt32Size ( int32 value); - static inline int SInt64Size ( int64 value); - static inline int EnumSize ( int value); - - // These types always have the same size. - static const int kFixed32Size = 4; - static const int kFixed64Size = 8; - static const int kSFixed32Size = 4; - static const int kSFixed64Size = 8; - static const int kFloatSize = 4; - static const int kDoubleSize = 8; - static const int kBoolSize = 1; - - static inline int StringSize(const string& value); - static inline int BytesSize (const string& value); - - static inline int GroupSize (const Message& value); - static inline int MessageSize(const Message& value); - - // Like above, but de-virtualize the call to ByteSize(). The - // pointer must point at an instance of MessageType, *not* a subclass (or - // the subclass must not override ByteSize()). - template<typename MessageType> - static inline int GroupSizeNoVirtual (const MessageType& value); - template<typename MessageType> - static inline int MessageSizeNoVirtual(const MessageType& value); - -#undef input -#undef output -#undef field_number -#undef INL - - private: - static const WireType kWireTypeForFieldType[]; - - // Parse/serialize a MessageSet::Item group. Used with messages that use - // opion message_set_wire_format = true. - static bool ParseAndMergeMessageSetItem( - io::CodedInputStream* input, - Message* message); - static bool SerializeMessageSetItemWithCachedSizes( - const FieldDescriptor* field, - const Message& message, - io::CodedOutputStream* output); - static int MessageSetItemByteSize( - const FieldDescriptor* field, - const Message& message); - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); -}; - -// inline methods ==================================================== - -// This macro does the same thing as WireFormat::MakeTag(), but the -// result is usable as a compile-time constant, which makes it usable -// as a switch case or a template input. WireFormat::MakeTag() is more -// type-safe, though, so prefer it if possible. -#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \ - static_cast<uint32>( \ - ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormat::kTagTypeBits) | (TYPE)) - -inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) { - return MakeTag(field->number(), WireTypeForFieldType(field->type())); -} - -inline uint32 WireFormat::MakeTag(int field_number, WireType type) { - return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type); -} - -inline WireFormat::WireType WireFormat::GetTagWireType(uint32 tag) { - return static_cast<WireType>(tag & kTagTypeMask); -} - -inline int WireFormat::GetTagFieldNumber(uint32 tag) { - return static_cast<int>(tag >> kTagTypeBits); -} - -inline uint32 WireFormat::EncodeFloat(float value) { - union {float f; uint32 i;}; - f = value; - return i; -} - -inline float WireFormat::DecodeFloat(uint32 value) { - union {float f; uint32 i;}; - i = value; - return f; -} - -inline uint64 WireFormat::EncodeDouble(double value) { - union {double f; uint64 i;}; - f = value; - return i; -} - -inline double WireFormat::DecodeDouble(uint64 value) { - union {double f; uint64 i;}; - i = value; - return f; -} - -// ZigZag Transform: Encodes signed integers so that they can be -// effectively used with varint encoding. -// -// varint operates on unsigned integers, encoding smaller numbers into -// fewer bytes. If you try to use it on a signed integer, it will treat -// this number as a very large unsigned integer, which means that even -// small signed numbers like -1 will take the maximum number of bytes -// (10) to encode. ZigZagEncode() maps signed integers to unsigned -// in such a way that those with a small absolute value will have smaller -// encoded values, making them appropriate for encoding using varint. -// -// int32 -> uint32 -// ------------------------- -// 0 -> 0 -// -1 -> 1 -// 1 -> 2 -// -2 -> 3 -// ... -> ... -// 2147483647 -> 4294967294 -// -2147483648 -> 4294967295 -// -// >> encode >> -// << decode << - -inline uint32 WireFormat::ZigZagEncode32(int32 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 31); -} - -inline int32 WireFormat::ZigZagDecode32(uint32 n) { - return (n >> 1) ^ -static_cast<int32>(n & 1); -} - -inline uint64 WireFormat::ZigZagEncode64(int64 n) { - // Note: the right-shift must be arithmetic - return (n << 1) ^ (n >> 63); -} - -inline int64 WireFormat::ZigZagDecode64(uint64 n) { - return (n >> 1) ^ -static_cast<int64>(n & 1); -} - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__ diff --git a/src/google/protobuf/wire_format_inl.h b/src/google/protobuf/wire_format_inl.h deleted file mode 100644 index d8cdd8d6..00000000 --- a/src/google/protobuf/wire_format_inl.h +++ /dev/null @@ -1,371 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ -#define GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ - -#include <string> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/io/coded_stream.h> - - -namespace google { -namespace protobuf { -namespace internal { - -inline bool WireFormat::ReadInt32(io::CodedInputStream* input, int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast<int32>(temp); - return true; -} -inline bool WireFormat::ReadInt64(io::CodedInputStream* input, int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = static_cast<int64>(temp); - return true; -} -inline bool WireFormat::ReadUInt32(io::CodedInputStream* input, uint32* value) { - return input->ReadVarint32(value); -} -inline bool WireFormat::ReadUInt64(io::CodedInputStream* input, uint64* value) { - return input->ReadVarint64(value); -} -inline bool WireFormat::ReadSInt32(io::CodedInputStream* input, int32* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = ZigZagDecode32(temp); - return true; -} -inline bool WireFormat::ReadSInt64(io::CodedInputStream* input, int64* value) { - uint64 temp; - if (!input->ReadVarint64(&temp)) return false; - *value = ZigZagDecode64(temp); - return true; -} -inline bool WireFormat::ReadFixed32(io::CodedInputStream* input, - uint32* value) { - return input->ReadLittleEndian32(value); -} -inline bool WireFormat::ReadFixed64(io::CodedInputStream* input, - uint64* value) { - return input->ReadLittleEndian64(value); -} -inline bool WireFormat::ReadSFixed32(io::CodedInputStream* input, - int32* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = static_cast<int32>(temp); - return true; -} -inline bool WireFormat::ReadSFixed64(io::CodedInputStream* input, - int64* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = static_cast<int64>(temp); - return true; -} -inline bool WireFormat::ReadFloat(io::CodedInputStream* input, float* value) { - uint32 temp; - if (!input->ReadLittleEndian32(&temp)) return false; - *value = DecodeFloat(temp); - return true; -} -inline bool WireFormat::ReadDouble(io::CodedInputStream* input, double* value) { - uint64 temp; - if (!input->ReadLittleEndian64(&temp)) return false; - *value = DecodeDouble(temp); - return true; -} -inline bool WireFormat::ReadBool(io::CodedInputStream* input, bool* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = temp != 0; - return true; -} -inline bool WireFormat::ReadEnum(io::CodedInputStream* input, int* value) { - uint32 temp; - if (!input->ReadVarint32(&temp)) return false; - *value = static_cast<int>(temp); - return true; -} - -inline bool WireFormat::ReadString(io::CodedInputStream* input, string* value) { - // WARNING: In wire_format.cc, both strings and bytes are handled by - // ReadString() to avoid code duplication. If the implementations become - // different, you will need to update that usage. - uint32 length; - if (!input->ReadVarint32(&length)) return false; - return input->ReadString(value, length); -} -inline bool WireFormat::ReadBytes(io::CodedInputStream* input, string* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - return input->ReadString(value, length); -} - - -inline bool WireFormat::ReadGroup(int field_number, io::CodedInputStream* input, - Message* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->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))) { - return false; - } - return true; -} -inline bool WireFormat::ReadMessage(io::CodedInputStream* input, Message* value) { - uint32 length; - if (!input->ReadVarint32(&length)) return false; - if (!input->IncrementRecursionDepth()) return false; - io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MergePartialFromCodedStream(input)) return false; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -template<typename MessageType> -inline bool WireFormat::ReadGroupNoVirtual(int field_number, - io::CodedInputStream* input, - MessageType* value) { - if (!input->IncrementRecursionDepth()) return false; - if (!value->MessageType::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))) { - return false; - } - return true; -} -template<typename MessageType> -inline bool WireFormat::ReadMessageNoVirtual(io::CodedInputStream* input, - MessageType* 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; - // Make sure that parsing stopped when the limit was hit, not at an endgroup - // tag. - if (!input->ConsumedEntireMessage()) return false; - input->PopLimit(limit); - input->DecrementRecursionDepth(); - return true; -} - -// =================================================================== - -inline bool WireFormat::WriteTag(int field_number, WireType type, - io::CodedOutputStream* output) { - return output->WriteTag(MakeTag(field_number, type)); -} - -inline bool WireFormat::WriteInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint32SignExtended(value); -} -inline bool WireFormat::WriteInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint64(static_cast<uint64>(value)); -} -inline bool WireFormat::WriteUInt32(int field_number, uint32 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint32(value); -} -inline bool WireFormat::WriteUInt64(int field_number, uint64 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint64(value); -} -inline bool WireFormat::WriteSInt32(int field_number, int32 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint32(ZigZagEncode32(value)); -} -inline bool WireFormat::WriteSInt64(int field_number, int64 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint64(ZigZagEncode64(value)); -} -inline bool WireFormat::WriteFixed32(int field_number, uint32 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED32, output) && - output->WriteLittleEndian32(value); -} -inline bool WireFormat::WriteFixed64(int field_number, uint64 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED64, output) && - output->WriteLittleEndian64(value); -} -inline bool WireFormat::WriteSFixed32(int field_number, int32 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED32, output) && - output->WriteLittleEndian32(static_cast<uint32>(value)); -} -inline bool WireFormat::WriteSFixed64(int field_number, int64 value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED64, output) && - output->WriteLittleEndian64(static_cast<uint64>(value)); -} -inline bool WireFormat::WriteFloat(int field_number, float value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED32, output) && - output->WriteLittleEndian32(EncodeFloat(value)); -} -inline bool WireFormat::WriteDouble(int field_number, double value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_FIXED64, output) && - output->WriteLittleEndian64(EncodeDouble(value)); -} -inline bool WireFormat::WriteBool(int field_number, bool value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint32(value ? 1 : 0); -} -inline bool WireFormat::WriteEnum(int field_number, int value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_VARINT, output) && - output->WriteVarint32SignExtended(value); -} - -inline bool WireFormat::WriteString(int field_number, const string& value, - io::CodedOutputStream* output) { - // WARNING: In wire_format.cc, both strings and bytes are handled by - // WriteString() to avoid code duplication. If the implementations become - // different, you will need to update that usage. - return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && - output->WriteVarint32(value.size()) && - output->WriteString(value); -} -inline bool WireFormat::WriteBytes(int field_number, const string& value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && - output->WriteVarint32(value.size()) && - output->WriteString(value); -} - - -inline bool WireFormat::WriteGroup(int field_number, const Message& value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_START_GROUP, output) && - value.SerializeWithCachedSizes(output) && - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -inline bool WireFormat::WriteMessage(int field_number, const Message& value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && - output->WriteVarint32(value.GetCachedSize()) && - value.SerializeWithCachedSizes(output); -} - -template<typename MessageType> -inline bool WireFormat::WriteGroupNoVirtual( - int field_number, const MessageType& value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_START_GROUP, output) && - value.MessageType::SerializeWithCachedSizes(output) && - WriteTag(field_number, WIRETYPE_END_GROUP, output); -} -template<typename MessageType> -inline bool WireFormat::WriteMessageNoVirtual( - int field_number, const MessageType& value, - io::CodedOutputStream* output) { - return WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output) && - output->WriteVarint32(value.MessageType::GetCachedSize()) && - value.MessageType::SerializeWithCachedSizes(output); -} - -// =================================================================== - -inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) { - int result = io::CodedOutputStream::VarintSize32( - field_number << kTagTypeBits); - if (type == FieldDescriptor::TYPE_GROUP) { - // Groups have both a start and an end tag. - return result * 2; - } else { - return result; - } -} - -inline int WireFormat::Int32Size(int32 value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} -inline int WireFormat::Int64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value)); -} -inline int WireFormat::UInt32Size(uint32 value) { - return io::CodedOutputStream::VarintSize32(value); -} -inline int WireFormat::UInt64Size(uint64 value) { - return io::CodedOutputStream::VarintSize64(value); -} -inline int WireFormat::SInt32Size(int32 value) { - return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value)); -} -inline int WireFormat::SInt64Size(int64 value) { - return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value)); -} -inline int WireFormat::EnumSize(int value) { - return io::CodedOutputStream::VarintSize32SignExtended(value); -} - -inline int WireFormat::StringSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} -inline int WireFormat::BytesSize(const string& value) { - return io::CodedOutputStream::VarintSize32(value.size()) + - value.size(); -} - - -inline int WireFormat::GroupSize(const Message& value) { - return value.ByteSize(); -} -inline int WireFormat::MessageSize(const Message& value) { - int size = value.ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -template<typename MessageType> -inline int WireFormat::GroupSizeNoVirtual(const MessageType& value) { - return value.MessageType::ByteSize(); -} -template<typename MessageType> -inline int WireFormat::MessageSizeNoVirtual(const MessageType& value) { - int size = value.MessageType::ByteSize(); - return io::CodedOutputStream::VarintSize32(size) + size; -} - -} // namespace internal -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_INL_H__ diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc deleted file mode 100644 index f5953bea..00000000 --- a/src/google/protobuf/wire_format_unittest.cc +++ /dev/null @@ -1,533 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. -// http://code.google.com/p/protobuf/ -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/wire_format.h> -#include <google/protobuf/wire_format_inl.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/unittest_mset.pb.h> -#include <google/protobuf/test_util.h> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> - -namespace google { -namespace protobuf { -namespace internal { -namespace { - -TEST(WireFormatTest, MaxFieldNumber) { - // Make sure the max field number constant is accurate. - EXPECT_EQ((1 << (32 - WireFormat::kTagTypeBits)) - 1, - FieldDescriptor::kMaxNumber); -} - -TEST(WireFormatTest, Parse) { - unittest::TestAllTypes source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetAllFields(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllFieldsSet(dest); -} - -TEST(WireFormatTest, ParseExtensions) { - unittest::TestAllExtensions source, dest; - string data; - - // Serialize using the generated code. - TestUtil::SetAllExtensions(&source); - source.SerializeToString(&data); - - // Parse using WireFormat. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - WireFormat::ParseAndMergePartial(&input, &dest); - - // Check. - TestUtil::ExpectAllExtensionsSet(dest); -} - -TEST(WireFormatTest, ByteSize) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, ByteSizeExtensions) { - unittest::TestAllExtensions message; - TestUtil::SetAllExtensions(&message); - - EXPECT_EQ(message.ByteSize(), - WireFormat::ByteSize(message)); - message.Clear(); - EXPECT_EQ(0, message.ByteSize()); - EXPECT_EQ(0, WireFormat::ByteSize(message)); -} - -TEST(WireFormatTest, Serialize) { - unittest::TestAllTypes message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllFields(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); -} - -TEST(WireFormatTest, SerializeExtensions) { - unittest::TestAllExtensions message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllExtensions(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); -} - -TEST(WireFormatTest, SerializeFieldsAndExtensions) { - unittest::TestFieldOrderings message; - string generated_data; - string dynamic_data; - - TestUtil::SetAllFieldsAndExtensions(&message); - int size = message.ByteSize(); - - // Serialize using the generated code. - { - io::StringOutputStream raw_output(&generated_data); - io::CodedOutputStream output(&raw_output); - message.SerializeWithCachedSizes(&output); - } - - // Serialize using WireFormat. - { - io::StringOutputStream raw_output(&dynamic_data); - io::CodedOutputStream output(&raw_output); - WireFormat::SerializeWithCachedSizes(message, size, &output); - } - - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); - - // Should output in canonical order. - TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data); - TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data); -} - -const int kUnknownTypeId = 1550055; - -TEST(WireFormatTest, SerializeMessageSet) { - // Set up a TestMessageSet with two known messages and an unknown one. - unittest::TestMessageSet message_set; - message_set.MutableExtension( - unittest::TestMessageSetExtension1::message_set_extension)->set_i(123); - message_set.MutableExtension( - unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo"); - message_set.mutable_unknown_fields()->AddField(kUnknownTypeId) - ->add_length_delimited("bar"); - - string data; - ASSERT_TRUE(message_set.SerializeToString(&data)); - - // Parse back using RawMessageSet and check the contents. - unittest::RawMessageSet raw; - ASSERT_TRUE(raw.ParseFromString(data)); - - EXPECT_EQ(0, raw.unknown_fields().field_count()); - - ASSERT_EQ(3, raw.item_size()); - EXPECT_EQ( - unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(), - raw.item(0).type_id()); - EXPECT_EQ( - unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(), - raw.item(1).type_id()); - EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id()); - - unittest::TestMessageSetExtension1 message1; - EXPECT_TRUE(message1.ParseFromString(raw.item(0).message())); - EXPECT_EQ(123, message1.i()); - - unittest::TestMessageSetExtension2 message2; - EXPECT_TRUE(message2.ParseFromString(raw.item(1).message())); - EXPECT_EQ("foo", message2.str()); - - EXPECT_EQ("bar", raw.item(2).message()); -} - -TEST(WireFormatTest, ParseMessageSet) { - // Set up a RawMessageSet with two known messages and an unknown one. - unittest::RawMessageSet raw; - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id( - unittest::TestMessageSetExtension1::descriptor()->extension(0)->number()); - unittest::TestMessageSetExtension1 message; - message.set_i(123); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id( - unittest::TestMessageSetExtension2::descriptor()->extension(0)->number()); - unittest::TestMessageSetExtension2 message; - message.set_str("foo"); - message.SerializeToString(item->mutable_message()); - } - - { - unittest::RawMessageSet::Item* item = raw.add_item(); - item->set_type_id(kUnknownTypeId); - item->set_message("bar"); - } - - string data; - ASSERT_TRUE(raw.SerializeToString(&data)); - - // Parse as a TestMessageSet and check the contents. - unittest::TestMessageSet message_set; - ASSERT_TRUE(message_set.ParseFromString(data)); - - EXPECT_EQ(123, message_set.GetExtension( - unittest::TestMessageSetExtension1::message_set_extension).i()); - EXPECT_EQ("foo", message_set.GetExtension( - unittest::TestMessageSetExtension2::message_set_extension).str()); - - ASSERT_EQ(1, message_set.unknown_fields().field_count()); - ASSERT_EQ(1, message_set.unknown_fields().field(0).length_delimited_size()); - EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited(0)); -} - -TEST(WireFormatTest, RecursionLimit) { - unittest::TestRecursiveMessage message; - message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1); - string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestRecursiveMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestRecursiveMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, UnknownFieldRecursionLimit) { - unittest::TestEmptyMessage message; - message.mutable_unknown_fields() - ->AddField(1234)->add_group() - ->AddField(1234)->add_group() - ->AddField(1234)->add_group() - ->AddField(1234)->add_group() - ->AddField(1234)->add_varint(123); - string data; - message.SerializeToString(&data); - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(4); - unittest::TestEmptyMessage message2; - EXPECT_TRUE(message2.ParseFromCodedStream(&input)); - } - - { - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream input(&raw_input); - input.SetRecursionLimit(3); - unittest::TestEmptyMessage message2; - EXPECT_FALSE(message2.ParseFromCodedStream(&input)); - } -} - -TEST(WireFormatTest, ZigZag) { -// avoid line-wrapping -#define LL(x) GOOGLE_LONGLONG(x) -#define ULL(x) GOOGLE_ULONGLONG(x) -#define ZigZagEncode32(x) WireFormat::ZigZagEncode32(x) -#define ZigZagDecode32(x) WireFormat::ZigZagDecode32(x) -#define ZigZagEncode64(x) WireFormat::ZigZagEncode64(x) -#define ZigZagDecode64(x) WireFormat::ZigZagDecode64(x) - - EXPECT_EQ(0u, ZigZagEncode32( 0)); - EXPECT_EQ(1u, ZigZagEncode32(-1)); - EXPECT_EQ(2u, ZigZagEncode32( 1)); - EXPECT_EQ(3u, ZigZagEncode32(-2)); - EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF)); - EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000)); - EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF)); - EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000)); - - EXPECT_EQ( 0, ZigZagDecode32(0u)); - EXPECT_EQ(-1, ZigZagDecode32(1u)); - EXPECT_EQ( 1, ZigZagDecode32(2u)); - EXPECT_EQ(-2, ZigZagDecode32(3u)); - EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu)); - EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu)); - EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu)); - EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu)); - - EXPECT_EQ(0u, ZigZagEncode64( 0)); - EXPECT_EQ(1u, ZigZagEncode64(-1)); - EXPECT_EQ(2u, ZigZagEncode64( 1)); - EXPECT_EQ(3u, ZigZagEncode64(-2)); - EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF))); - EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000))); - EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF))); - EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF))); - EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000))); - - EXPECT_EQ( 0, ZigZagDecode64(0u)); - EXPECT_EQ(-1, ZigZagDecode64(1u)); - EXPECT_EQ( 1, ZigZagDecode64(2u)); - EXPECT_EQ(-2, ZigZagDecode64(3u)); - EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF))); - EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE))); - EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF))); - EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE))); - EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF))); - - // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) - // were chosen semi-randomly via keyboard bashing. - EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0))); - EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1))); - EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1))); - EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927))); - EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612))); - - EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0))); - EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1))); - EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1))); - EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927))); - EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612))); - - EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64( - LL(856912304801416)))); - EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64( - LL(-75123905439571256)))); -} - -class WireFormatInvalidInputTest : public testing::Test { - protected: - // Make a serialized TestAllTypes in which the field optional_nested_message - // contains exactly the given bytes, which may be invalid. - string MakeInvalidEmbeddedMessage(const char* bytes, int size) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName( - "optional_nested_message"); - GOOGLE_CHECK(field != NULL); - - string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - EXPECT_TRUE(WireFormat::WriteString( - field->number(), string(bytes, size), &output)); - } - - return result; - } - - // Make a serialized TestAllTypes in which the field optionalgroup - // contains exactly the given bytes -- which may be invalid -- and - // possibly no end tag. - string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) { - const FieldDescriptor* field = - unittest::TestAllTypes::descriptor()->FindFieldByName( - "optionalgroup"); - GOOGLE_CHECK(field != NULL); - - string result; - - { - io::StringOutputStream raw_output(&result); - io::CodedOutputStream output(&raw_output); - - EXPECT_TRUE(output.WriteVarint32(WireFormat::MakeTag(field))); - EXPECT_TRUE(output.WriteString(string(bytes, size))); - if (include_end_tag) { - EXPECT_TRUE( - output.WriteVarint32(WireFormat::MakeTag( - field->number(), WireFormat::WIRETYPE_END_GROUP))); - } - } - - return result; - } -}; - -TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1))); - - // The byte is an endgroup tag, but we aren't parsing a group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidGroup) { - unittest::TestAllTypes message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) { - // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not - // be a known tag number. - unittest::TestEmptyMessage message; - - // Control case. - EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true))); - - // Missing end tag. Groups cannot end at EOF. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false))); - - // The byte is a valid varint, but not a valid tag (zero). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false))); - - // The byte is a malformed varint. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false))); - - // The byte is an endgroup tag, but not the right one for this group. - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false))); - - // The byte is a valid varint but not a valid tag (bad wire type). - EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true))); -} - -TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) { - // Test a bug fix: SkipMessage should fail if the message contains a string - // whose length would extend beyond the message end. - - unittest::TestAllTypes message; - message.set_optional_string("foo foo foo foo"); - string data; - message.SerializeToString(&data); - - // Chop some bytes off the end. - data.resize(data.size() - 4); - - // Try to skip it. Note that the bug was only present when parsing to an - // UnknownFieldSet. - io::ArrayInputStream raw_input(data.data(), data.size()); - io::CodedInputStream coded_input(&raw_input); - UnknownFieldSet unknown_fields; - EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields)); -} - -} // namespace -} // namespace internal -} // namespace protobuf -} // namespace google diff --git a/src/gtest/CHANGES b/src/gtest/CHANGES deleted file mode 100644 index 871ef1fb..00000000 --- a/src/gtest/CHANGES +++ /dev/null @@ -1,3 +0,0 @@ -Changes for 1.0.0: - - * Initial Open Source release of Google Test diff --git a/src/gtest/CONTRIBUTORS b/src/gtest/CONTRIBUTORS deleted file mode 100644 index 31341833..00000000 --- a/src/gtest/CONTRIBUTORS +++ /dev/null @@ -1,23 +0,0 @@ -# This file contains a list of people who've made non-trivial -# contribution to the Google C++ Testing Framework project. People -# who commit code to the project are encouraged to add their names -# here. Please keep the list sorted by first names. - -Ajay Joshi <jaj@google.com> -Bharat Mediratta <bharat@menalto.com> -Chandler Carruth <chandlerc@google.com> -Chris Prince <cprince@google.com> -Chris Taylor <taylorc@google.com> -Jeffrey Yasskin <jyasskin@google.com> -Keir Mierle <mierle@gmail.com> -Keith Ray <keith.ray@gmail.com> -Markus Heule <markus.heule@gmail.com> -Patrick Hanna <phanna@google.com> -Patrick Riley <pfr@google.com> -Peter Kaminski <piotrk@google.com> -Russ Cox <rsc@google.com> -Russ Rufer <russ@pentad.com> -Sean Mcafee <eefacm@gmail.com> -Sigurður Ásgeirsson <siggi@google.com> -Tracy Bialik <tracy@pentad.com> -Zhanyong Wan <wan@google.com> diff --git a/src/gtest/COPYING b/src/gtest/COPYING deleted file mode 100644 index 1941a11f..00000000 --- a/src/gtest/COPYING +++ /dev/null @@ -1,28 +0,0 @@ -Copyright 2008, Google Inc. -All rights reserved. - -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. diff --git a/src/gtest/README b/src/gtest/README deleted file mode 100644 index 0e170475..00000000 --- a/src/gtest/README +++ /dev/null @@ -1,150 +0,0 @@ -This directory contains Google Test, described below. It is used by the -Protocol Buffer C++ unit tests. If you would like to use Google Test -yourself, you should probably download it from the URL mentioned below, -not attempt to use the sources in this package. - -Two changes were made from the original sources: -* gtest.cc's #include of gtest-internal-inl.h was modified to reflect the - environment it is being built in (replaced "src/" with "gtest/"). -* GetThreadCount() in gtest-port.h was hard-coded to return 1 rather than 0, - since the Protocol Buffer tests do not use threads. - -The original Google Test README follows. - -====================================================================== - -Google C++ Testing Framework -============================ -http://code.google.com/p/googletest/ - -Overview --------- -Google's framework for writing C++ tests on a variety of platforms (Linux, Mac -OS X, Windows, Windows CE, and Symbian). Based on the xUnit architecture. -Supports automatic test discovery, a rich set of assertions, user-defined -assertions, death tests, fatal and non-fatal failures, various options for -running the tests, and XML test report generation. - -Please see the project page above for more information as well as mailing lists -for questions, discussions, and development. There is also an IRC channel on -OFTC (irc.oftc.net) #gtest available. Please join us! - -Requirements ------------- -Google Test is designed to have fairly minimal requirements to build and use -with your projects, but there are some. Currently, the only Operating System -(OS) on which Google Test is known to build properly is Linux, but we are -actively working on Windows and Mac support as well. The source code itself is -already portable across many other platforms, but we are still developing -robust build systems for each. - -### Linux Requirements ### -These are the base requirements to build and use Google Test from a source -package (as described below): - * GNU-compatible Make or "gmake" - * POSIX-standard shell - * POSIX(-2) Regular Expressions (regex.h) - * A C++98 standards compliant compiler - -Furthermore, if you are building Google Test from a VCS Checkout (also -described below), there are further requirements: - * Automake version 1.9 or newer - * Autoconf version 2.59 or newer - * Libtool / Libtoolize - * Python version 2.4 or newer - -Getting the Source ------------------- -There are two primary ways of getting Google Test's source code: you can -download a source release in your preferred archive format, or directly check -out the source from a Version Control System (VCS, we use Google Code's -Subversion hosting). The VCS checkout requires a few extra steps and some extra -software packages on your system, but lets you track development, and make -patches to contribute much more easily, so we highly encourage it. - -### VCS Checkout: ### -The first step is to select whether you want to check out the main line of -development on Google Test, or one of the released branches. The former will be -much more active and have the latest features, but the latter provides much -more stability and predictability. Choose whichever fits your needs best, and -proceed with the following Subversion commands: - - $ svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn - -or for a release version X.Y.*'s branch: - - $ svn checkout http://googletest.googlecode.com/svn/branches/release-X.Y/ gtest-X.Y-svn - -Next you will need to prepare the GNU Autotools build system. Enter the -target directory of the checkout command you used ('gtest-svn' or -'gtest-X.Y-svn' above) and proceed with the following commands: - - $ aclocal-1.9 # Where "1.9" must match the following automake command - $ libtoolize -c - $ autoheader - $ automake-1.9 -ac # See Automake version requirements above - $ autoconf - -While this is a bit complicated, it will most often be automatically re-run by -your "make" invocations, so in practice you shouldn't need to worry too much. -Once you have completed these steps, your VCS checkout should be equivalent to -a source package, and you may continue with those directions, skipping over the -acquiring and unpacking of the source itself, as the VCS has done that for you. - -### Source Package: ### -Google Test is also released in source packages which can be downloaded from -its Google Code download page[1]. Several different archive formats are -provided, but the only difference is the tools used to manipulate them, and the -size of the resulting file. Download whichever you are most comfortable with. - - [1] Google Test Downloads: http://code.google.com/p/googletest/downloads/list - -Once downloaded expand the archive using whichever tools you prefer for that -type. This will always result in a new directory with the name "gtest-X.Y.Z" -which contains all of the source code. Here are some examples in Linux: - - $ tar -xvzf gtest-X.Y.Z.tar.gz - $ tar -xvjf gtest-X.Y.Z.tar.bz2 - $ unzip gtest-X.Y.Z.zip - -Building the Source -------------------- -There are two primary options for building the source at this point: build it -inside the source code tree, or in a separate directory. We recommend building -in a separate directory as that tends to produce both more consistent results -and be easier to clean up should anything go wrong, but both patterns are -supported. The only hard restriction is that while the build directory can be -a subdirectory of the source directory, the opposite is not possible and will -result in errors. Once you have selected where you wish to build Google Test, -create the directory if necessary, and enter it. The following steps apply for -either approach by simply substituting the shell variable SRCDIR with "." for -building inside the source directory, and the relative path to the source -directory otherwise. - - $ ${SRCDIR}/configure # Standard GNU configure script, --help for more info - $ make # Standard makefile following GNU conventions - -Other programs will only be able to use Google Test's functionality if you -install it in a location which they can access, in Linux this is typically -under '/usr/local'. The following command will install all of the Google Test -libraries, public headers, and utilities necessary for other programs and -libraries to leverage it: - - $ sudo make install # Not necessary, but allows use by other programs - -TODO(chandlerc@google.com): This section needs to be expanded when the -'gtest-config' script is finished and Autoconf macro's are provided (or not -provided) in order to properly reflect the process for other programs to -locate, include, and link against Google Test. - -Finally, should you need to remove Google Test from your system after having -installed it, run the following command, and it will back out its changes. -However, note carefully that you must run this command on the *same* Google -Test build that you ran the install from, or the results are not predictable. -If you install Google Test on your system, and are working from a VCS checkout, -make sure you run this *before* updating your checkout of the source in order -to uninstall the same version which you installed. - - $ sudo make uninstall # Must be run against the exact same build as "install" - -Happy testing! diff --git a/src/gtest/gen_gtest_pred_impl.py b/src/gtest/gen_gtest_pred_impl.py deleted file mode 100755 index 7cb31da2..00000000 --- a/src/gtest/gen_gtest_pred_impl.py +++ /dev/null @@ -1,733 +0,0 @@ -#!/usr/bin/python2.4 -# -# Copyright 2006, Google Inc. -# All rights reserved. -# -# 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. - -"""gen_gtest_pred_impl.py v0.1 - -Generates the implementation of Google Test predicate assertions and -accompanying tests. - -Usage: - - gen_gtest_pred_impl.py MAX_ARITY - -where MAX_ARITY is a positive integer. - -The command generates the implementation of up-to MAX_ARITY-ary -predicate assertions, and writes it to file gtest_pred_impl.h in the -directory where the script is. It also generates the accompanying -unit test in file gtest_pred_impl_unittest.cc. -""" - -__author__ = 'wan@google.com (Zhanyong Wan)' - -import os -import sys -import time - -# Where this script is. -SCRIPT_DIR = os.path.dirname(sys.argv[0]) - -# Where to store the generated header. -HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h') - -# Where to store the generated unit test. -UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc') - - -def HeaderPreamble(n): - """Returns the preamble for the header file. - - Args: - n: the maximum arity of the predicate macros to be generated. - """ - - # A map that defines the values used in the preamble template. - DEFS = { - 'today' : time.strftime('%m/%d/%Y'), - 'year' : time.strftime('%Y'), - 'command' : '%s %s' % (os.path.basename(sys.argv[0]), n), - 'n' : n - } - - return ( -"""// Copyright 2006, Google Inc. -// All rights reserved. -// -// 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. - -// This file is AUTOMATICALLY GENERATED on %(today)s by command -// '%(command)s'. DO NOT EDIT BY HAND! -// -// Implements a family of generic predicate assertion macros. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ - -// Makes sure this header is not included before gtest.h. -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ - -// This header implements a family of generic predicate assertion -// macros: -// -// ASSERT_PRED_FORMAT1(pred_format, v1) -// ASSERT_PRED_FORMAT2(pred_format, v1, v2) -// ... -// -// where pred_format is a function or functor that takes n (in the -// case of ASSERT_PRED_FORMATn) values and their source expression -// text, and returns a testing::AssertionResult. See the definition -// of ASSERT_EQ in gtest.h for an example. -// -// If you don't care about formatting, you can use the more -// restrictive version: -// -// ASSERT_PRED1(pred, v1) -// ASSERT_PRED2(pred, v1, v2) -// ... -// -// where pred is an n-ary function or functor that returns bool, -// and the values v1, v2, ..., must support the << operator for -// streaming to std::ostream. -// -// We also define the EXPECT_* variations. -// -// For now we only support predicates whose arity is at most %(n)s. -// Please email googletestframework@googlegroups.com if you need -// support for higher arities. - -// GTEST_ASSERT is the basic statement to which all of the assertions -// in this file reduce. Don't use this in your code. - -#define GTEST_ASSERT(expression, on_failure) \\ - GTEST_AMBIGUOUS_ELSE_BLOCKER \\ - if (const ::testing::AssertionResult gtest_ar = (expression)) \\ - ; \\ - else \\ - on_failure(gtest_ar.failure_message()) -""" % DEFS) - - -def Arity(n): - """Returns the English name of the given arity.""" - - if n < 0: - return None - elif n <= 3: - return ['nullary', 'unary', 'binary', 'ternary'][n] - else: - return '%s-ary' % n - - -def Title(word): - """Returns the given word in title case. The difference between - this and string's title() method is that Title('4-ary') is '4-ary' - while '4-ary'.title() is '4-Ary'.""" - - return word[0].upper() + word[1:] - - -def OneTo(n): - """Returns the list [1, 2, 3, ..., n].""" - - return range(1, n + 1) - - -def Iter(n, format, sep=''): - """Given a positive integer n, a format string that contains 0 or - more '%s' format specs, and optionally a separator string, returns - the join of n strings, each formatted with the format string on an - iterator ranged from 1 to n. - - Example: - - Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'. - """ - - # How many '%s' specs are in format? - spec_count = len(format.split('%s')) - 1 - return sep.join([format % (spec_count * (i,)) for i in OneTo(n)]) - - -def ImplementationForArity(n): - """Returns the implementation of n-ary predicate assertions.""" - - # A map the defines the values used in the implementation template. - DEFS = { - 'n' : str(n), - 'vs' : Iter(n, 'v%s', sep=', '), - 'vts' : Iter(n, '#v%s', sep=', '), - 'arity' : Arity(n), - 'Arity' : Title(Arity(n)) - } - - impl = """ - -// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use -// this in your code. -template <typename Pred""" % DEFS - - impl += Iter(n, """, - typename T%s""") - - impl += """> -AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS - - impl += Iter(n, """, - const char* e%s""") - - impl += """, - Pred pred""" - - impl += Iter(n, """, - const T%s& v%s""") - - impl += """) { - if (pred(%(vs)s)) return AssertionSuccess(); - - Message msg; -""" % DEFS - - impl += ' msg << pred_text << "("' - - impl += Iter(n, """ - << e%s""", sep=' << ", "') - - impl += ' << ") evaluates to false, where"' - - impl += Iter(n, """ - << "\\n" << e%s << " evaluates to " << v%s""") - - impl += """; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s. -// Don't use this in your code. -#define GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, on_failure)\\ - GTEST_ASSERT(pred_format(%(vts)s, %(vs)s),\\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use -// this in your code. -#define GTEST_PRED%(n)s(pred, %(vs)s, on_failure)\\ - GTEST_ASSERT(::testing::AssertPred%(n)sHelper(#pred""" % DEFS - - impl += Iter(n, """, \\ - #v%s""") - - impl += """, \\ - pred""" - - impl += Iter(n, """, \\ - v%s""") - - impl += """), on_failure) - -// %(Arity)s predicate assertion macros. -#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ - GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED%(n)s(pred, %(vs)s) \\ - GTEST_PRED%(n)s(pred, %(vs)s, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\ - GTEST_PRED_FORMAT%(n)s(pred_format, %(vs)s, GTEST_FATAL_FAILURE) -#define ASSERT_PRED%(n)s(pred, %(vs)s) \\ - GTEST_PRED%(n)s(pred, %(vs)s, GTEST_FATAL_FAILURE) - -""" % DEFS - - return impl - - -def HeaderPostamble(): - """Returns the postamble for the header file.""" - - return """ - -#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -""" - - -def GenerateFile(path, content): - """Given a file path and a content string, overwrites it with the - given content.""" - - print 'Updating file %s . . .' % path - - f = file(path, 'w+') - print >>f, content, - f.close() - - print 'File %s has been updated.' % path - - -def GenerateHeader(n): - """Given the maximum arity n, updates the header file that implements - the predicate assertions.""" - - GenerateFile(HEADER, - HeaderPreamble(n) - + ''.join([ImplementationForArity(i) for i in OneTo(n)]) - + HeaderPostamble()) - - -def UnitTestPreamble(): - """Returns the preamble for the unit test file.""" - - # A map that defines the values used in the preamble template. - DEFS = { - 'today' : time.strftime('%m/%d/%Y'), - 'year' : time.strftime('%Y'), - 'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]), - } - - return ( -"""// Copyright 2006, Google Inc. -// All rights reserved. -// -// 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. - -// This file is AUTOMATICALLY GENERATED on %(today)s by command -// '%(command)s'. DO NOT EDIT BY HAND! - -// Regression test for gtest_pred_impl.h -// -// This file is generated by a script and quite long. If you intend to -// learn how Google Test works by reading its unit tests, read -// gtest_unittest.cc instead. -// -// This is intended as a regression test for the Google Test predicate -// assertions. We compile it as part of the gtest_unittest target -// only to keep the implementation tidy and compact, as it is quite -// involved to set up the stage for testing Google Test using Google -// Test itself. -// -// Currently, gtest_unittest takes ~11 seconds to run in the testing -// daemon. In the future, if it grows too large and needs much more -// time to finish, we should consider separating this file into a -// stand-alone regression test. - -#include <iostream> - -#include <gtest/gtest.h> -#include <gtest/gtest-spi.h> - -// A user-defined data type. -struct Bool { - explicit Bool(int val) : value(val != 0) {} - - bool operator>(int n) const { return value > Bool(n).value; } - - Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); } - - bool operator==(const Bool& rhs) const { return value == rhs.value; } - - bool value; -}; - -// Enables Bool to be used in assertions. -std::ostream& operator<<(std::ostream& os, const Bool& x) { - return os << (x.value ? "true" : "false"); -} - -""" % DEFS) - - -def TestsForArity(n): - """Returns the tests for n-ary predicate assertions.""" - - # A map that defines the values used in the template for the tests. - DEFS = { - 'n' : n, - 'es' : Iter(n, 'e%s', sep=', '), - 'vs' : Iter(n, 'v%s', sep=', '), - 'vts' : Iter(n, '#v%s', sep=', '), - 'tvs' : Iter(n, 'T%s v%s', sep=', '), - 'int_vs' : Iter(n, 'int v%s', sep=', '), - 'Bool_vs' : Iter(n, 'Bool v%s', sep=', '), - 'types' : Iter(n, 'typename T%s', sep=', '), - 'v_sum' : Iter(n, 'v%s', sep=' + '), - 'arity' : Arity(n), - 'Arity' : Title(Arity(n)), - } - - tests = ( -"""// Sample functions/functors for testing %(arity)s predicate assertions. - -// A %(arity)s predicate function. -template <%(types)s> -bool PredFunction%(n)s(%(tvs)s) { - return %(v_sum)s > 0; -} - -// The following two functions are needed to circumvent a bug in -// gcc 2.95.3, which sometimes has problem with the above template -// function. -bool PredFunction%(n)sInt(%(int_vs)s) { - return %(v_sum)s > 0; -} -bool PredFunction%(n)sBool(%(Bool_vs)s) { - return %(v_sum)s > 0; -} -""" % DEFS) - - tests += """ -// A %(arity)s predicate functor. -struct PredFunctor%(n)s { - template <%(types)s> - bool operator()(""" % DEFS - - tests += Iter(n, 'const T%s& v%s', sep=""", - """) - - tests += """) { - return %(v_sum)s > 0; - } -}; -""" % DEFS - - tests += """ -// A %(arity)s predicate-formatter function. -template <%(types)s> -testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS - - tests += Iter(n, 'const char* e%s', sep=""", - """) - - tests += Iter(n, """, - const T%s& v%s""") - - tests += """) { - if (PredFunction%(n)s(%(vs)s)) - return testing::AssertionSuccess(); - - testing::Message msg; - msg << """ % DEFS - - tests += Iter(n, 'e%s', sep=' << " + " << ') - - tests += """ - << " is expected to be positive, but evaluates to " - << %(v_sum)s << "."; - return testing::AssertionFailure(msg); -} -""" % DEFS - - tests += """ -// A %(arity)s predicate-formatter functor. -struct PredFormatFunctor%(n)s { - template <%(types)s> - testing::AssertionResult operator()(""" % DEFS - - tests += Iter(n, 'const char* e%s', sep=""", - """) - - tests += Iter(n, """, - const T%s& v%s""") - - tests += """) const { - return PredFormatFunction%(n)s(%(es)s, %(vs)s); - } -}; -""" % DEFS - - tests += """ -// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s. - -class Predicate%(n)sTest : public testing::Test { - protected: - virtual void SetUp() { - expected_to_finish_ = true; - finished_ = false;""" % DEFS - - tests += """ - """ + Iter(n, 'n%s_ = ') + """0; - } -""" - - tests += """ - virtual void TearDown() { - // Verifies that each of the predicate's arguments was evaluated - // exactly once.""" - - tests += ''.join([""" - EXPECT_EQ(1, n%s_) << - "The predicate assertion didn't evaluate argument %s " - "exactly once.";""" % (i, i + 1) for i in OneTo(n)]) - - tests += """ - - // Verifies that the control flow in the test function is expected. - if (expected_to_finish_ && !finished_) { - FAIL() << "The predicate assertion unexpactedly aborted the test."; - } else if (!expected_to_finish_ && finished_) { - FAIL() << "The failed predicate assertion didn't abort the test " - "as expected."; - } - } - - // true iff the test function is expected to run to finish. - static bool expected_to_finish_; - - // true iff the test function did run to finish. - static bool finished_; -""" % DEFS - - tests += Iter(n, """ - static int n%s_;""") - - tests += """ -}; - -bool Predicate%(n)sTest::expected_to_finish_; -bool Predicate%(n)sTest::finished_; -""" % DEFS - - tests += Iter(n, """int Predicate%%(n)sTest::n%s_; -""") % DEFS - - tests += """ -typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest; -typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest; -typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest; -typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest; -""" % DEFS - - def GenTest(use_format, use_assert, expect_failure, - use_functor, use_user_type): - """Returns the test for a predicate assertion macro. - - Args: - use_format: true iff the assertion is a *_PRED_FORMAT*. - use_assert: true iff the assertion is a ASSERT_*. - expect_failure: true iff the assertion is expected to fail. - use_functor: true iff the first argument of the assertion is - a functor (as opposed to a function) - use_user_type: true iff the predicate functor/function takes - argument(s) of a user-defined type. - - Example: - - GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior - of a successful EXPECT_PRED_FORMATn() that takes a functor - whose arguments have built-in types.""" - - if use_assert: - assrt = 'ASSERT' # 'assert' is reserved, so we cannot use - # that identifier here. - else: - assrt = 'EXPECT' - - assertion = assrt + '_PRED' - - if use_format: - pred_format = 'PredFormat' - assertion += '_FORMAT' - else: - pred_format = 'Pred' - - assertion += '%(n)s' % DEFS - - if use_functor: - pred_format_type = 'functor' - pred_format += 'Functor%(n)s()' - else: - pred_format_type = 'function' - pred_format += 'Function%(n)s' - if not use_format: - if use_user_type: - pred_format += 'Bool' - else: - pred_format += 'Int' - - test_name = pred_format_type.title() - - if use_user_type: - arg_type = 'user-defined type (Bool)' - test_name += 'OnUserType' - if expect_failure: - arg = 'Bool(n%s_++)' - else: - arg = 'Bool(++n%s_)' - else: - arg_type = 'built-in type (int)' - test_name += 'OnBuiltInType' - if expect_failure: - arg = 'n%s_++' - else: - arg = '++n%s_' - - if expect_failure: - successful_or_failed = 'failed' - expected_or_not = 'expected.' - test_name += 'Failure' - else: - successful_or_failed = 'successful' - expected_or_not = 'UNEXPECTED!' - test_name += 'Success' - - # A map that defines the values used in the test template. - defs = DEFS.copy() - defs.update({ - 'assert' : assrt, - 'assertion' : assertion, - 'test_name' : test_name, - 'pf_type' : pred_format_type, - 'pf' : pred_format, - 'arg_type' : arg_type, - 'arg' : arg, - 'successful' : successful_or_failed, - 'expected' : expected_or_not, - }) - - test = """ -// Tests a %(successful)s %(assertion)s where the -// predicate-formatter is a %(pf_type)s on a %(arg_type)s. -TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs - - indent = (len(assertion) + 3)*' ' - extra_indent = '' - - if expect_failure: - extra_indent = ' ' - if use_assert: - test += """ - expected_to_finish_ = false; - EXPECT_FATAL_FAILURE({ // NOLINT""" - else: - test += """ - EXPECT_NONFATAL_FAILURE({ // NOLINT""" - - test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs - - test = test % defs - test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs) - test += ');\n' + extra_indent + ' finished_ = true;\n' - - if expect_failure: - test += ' }, "");\n' - - test += '}\n' - return test - - # Generates tests for all 2**6 = 64 combinations. - tests += ''.join([GenTest(use_format, use_assert, expect_failure, - use_functor, use_user_type) - for use_format in [0, 1] - for use_assert in [0, 1] - for expect_failure in [0, 1] - for use_functor in [0, 1] - for use_user_type in [0, 1] - ]) - - return tests - - -def UnitTestPostamble(): - """Returns the postamble for the tests.""" - - return '' - - -def GenerateUnitTest(n): - """Returns the tests for up-to n-ary predicate assertions.""" - - GenerateFile(UNIT_TEST, - UnitTestPreamble() - + ''.join([TestsForArity(i) for i in OneTo(n)]) - + UnitTestPostamble()) - - -def _Main(): - """The entry point of the script. Generates the header file and its - unit test.""" - - if len(sys.argv) != 2: - print __doc__ - print 'Author: ' + __author__ - sys.exit(1) - - n = int(sys.argv[1]) - GenerateHeader(n) - GenerateUnitTest(n) - - -if __name__ == '__main__': - _Main() diff --git a/src/gtest/gtest-death-test.cc b/src/gtest/gtest-death-test.cc deleted file mode 100644 index 09fdd3ff..00000000 --- a/src/gtest/gtest-death-test.cc +++ /dev/null @@ -1,751 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// This file implements death tests. - -#include <gtest/gtest-death-test.h> -#include <gtest/internal/gtest-port.h> - -#include <errno.h> -#include <limits.h> -#include <stdarg.h> - -#include <gtest/gtest-message.h> -#include <gtest/internal/gtest-string.h> - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION -#include "gtest-internal-inl.h" -#undef GTEST_IMPLEMENTATION - -namespace testing { - -// Constants. - -// The default death test style. -static const char kDefaultDeathTestStyle[] = "fast"; - -GTEST_DEFINE_string( - death_test_style, - internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), - "Indicates how to run a death test in a forked child process: " - "\"threadsafe\" (child process re-executes the test binary " - "from the beginning, running only the specific death test) or " - "\"fast\" (child process runs the death test immediately " - "after forking)."); - -namespace internal { -GTEST_DEFINE_string( - internal_run_death_test, "", - "Indicates the file, line number, temporal index of " - "the single death test to run, and a file descriptor to " - "which a success code may be sent, all separated by " - "colons. This flag is specified if and only if the current " - "process is a sub-process launched for running a thread-safe " - "death test. FOR INTERNAL USE ONLY."); -} // namespace internal - -#ifdef GTEST_HAS_DEATH_TEST - -// ExitedWithCode constructor. -ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { -} - -// ExitedWithCode function-call operator. -bool ExitedWithCode::operator()(int exit_status) const { - return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; -} - -// KilledBySignal constructor. -KilledBySignal::KilledBySignal(int signum) : signum_(signum) { -} - -// KilledBySignal function-call operator. -bool KilledBySignal::operator()(int exit_status) const { - return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; -} - -namespace internal { - -// Utilities needed for death tests. - -// Generates a textual description of a given exit code, in the format -// specified by wait(2). -static String ExitSummary(int exit_code) { - Message m; - if (WIFEXITED(exit_code)) { - m << "Exited with exit status " << WEXITSTATUS(exit_code); - } else if (WIFSIGNALED(exit_code)) { - m << "Terminated by signal " << WTERMSIG(exit_code); - } -#ifdef WCOREDUMP - if (WCOREDUMP(exit_code)) { - m << " (core dumped)"; - } -#endif - return m.GetString(); -} - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status) { - return !ExitedWithCode(0)(exit_status); -} - -// Generates a textual failure message when a death test finds more than -// one thread running, or cannot determine the number of threads, prior -// to executing the given statement. It is the responsibility of the -// caller not to pass a thread_count of 1. -static String DeathTestThreadWarning(size_t thread_count) { - Message msg; - msg << "Death tests use fork(), which is unsafe particularly" - << " in a threaded context. For this test, " << GTEST_NAME << " "; - if (thread_count == 0) - msg << "couldn't detect the number of threads."; - else - msg << "detected " << thread_count << " threads."; - return msg.GetString(); -} - -// Static string containing a description of the outcome of the -// last death test. -static String last_death_test_message; - -// Flag characters for reporting a death test that did not die. -static const char kDeathTestLived = 'L'; -static const char kDeathTestReturned = 'R'; -static const char kDeathTestInternalError = 'I'; - -// An enumeration describing all of the possible ways that a death test -// can conclude. DIED means that the process died while executing the -// test code; LIVED means that process lived beyond the end of the test -// code; and RETURNED means that the test statement attempted a "return," -// which is not allowed. IN_PROGRESS means the test has not yet -// concluded. -enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; - -// Routine for aborting the program which is safe to call from an -// exec-style death test child process, in which case the the error -// message is propagated back to the parent process. Otherwise, the -// message is simply printed to stderr. In either case, the program -// then exits with status 1. -void DeathTestAbort(const char* format, ...) { - // This function may be called from a threadsafe-style death test - // child process, which operates on a very small stack. Use the - // heap for any additional non-miniscule memory requirements. - const InternalRunDeathTestFlag* const flag = - GetUnitTestImpl()->internal_run_death_test_flag(); - va_list args; - va_start(args, format); - - if (flag != NULL) { - FILE* parent = fdopen(flag->status_fd, "w"); - fputc(kDeathTestInternalError, parent); - vfprintf(parent, format, args); - fclose(parent); - va_end(args); - _exit(1); - } else { - vfprintf(stderr, format, args); - va_end(args); - abort(); - } -} - -// A replacement for CHECK that calls DeathTestAbort if the assertion -// fails. -#define GTEST_DEATH_TEST_CHECK(expression) \ - do { \ - if (!(expression)) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s", \ - __FILE__, __LINE__, #expression); \ - } \ - } while (0) - -// This macro is similar to GTEST_DEATH_TEST_CHECK, but it is meant for -// evaluating any system call that fulfills two conditions: it must return -// -1 on failure, and set errno to EINTR when it is interrupted and -// should be tried again. The macro expands to a loop that repeatedly -// evaluates the expression as long as it evaluates to -1 and sets -// errno to EINTR. If the expression evaluates to -1 but errno is -// something other than EINTR, DeathTestAbort is called. -#define GTEST_DEATH_TEST_CHECK_SYSCALL(expression) \ - do { \ - int retval; \ - do { \ - retval = (expression); \ - } while (retval == -1 && errno == EINTR); \ - if (retval == -1) { \ - DeathTestAbort("CHECK failed: File %s, line %d: %s != -1", \ - __FILE__, __LINE__, #expression); \ - } \ - } while (0) - -// Death test constructor. Increments the running death test count -// for the current test. -DeathTest::DeathTest() { - TestInfo* const info = GetUnitTestImpl()->current_test_info(); - if (info == NULL) { - DeathTestAbort("Cannot run a death test outside of a TEST or " - "TEST_F construct"); - } -} - -// Creates and returns a death test by dispatching to the current -// death test factory. -bool DeathTest::Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) { - return GetUnitTestImpl()->death_test_factory()->Create( - statement, regex, file, line, test); -} - -const char* DeathTest::LastMessage() { - return last_death_test_message.c_str(); -} - -// ForkingDeathTest provides implementations for most of the abstract -// methods of the DeathTest interface. Only the AssumeRole method is -// left undefined. -class ForkingDeathTest : public DeathTest { - public: - ForkingDeathTest(const char* statement, const RE* regex); - - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - virtual bool Passed(bool status_ok); - virtual void Abort(AbortReason reason); - - protected: - void set_forked(bool forked) { forked_ = forked; } - void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } - void set_read_fd(int fd) { read_fd_ = fd; } - void set_write_fd(int fd) { write_fd_ = fd; } - - private: - // The textual content of the code this object is testing. - const char* const statement_; - // The regular expression which test output must match. - const RE* const regex_; - // True if the death test successfully forked. - bool forked_; - // PID of child process during death test; 0 in the child process itself. - pid_t child_pid_; - // File descriptors for communicating the death test's status byte. - int read_fd_; // Always -1 in the child process. - int write_fd_; // Always -1 in the parent process. - // The exit status of the child process. - int status_; - // How the death test concluded. - DeathTestOutcome outcome_; -}; - -// Constructs a ForkingDeathTest. -ForkingDeathTest::ForkingDeathTest(const char* statement, const RE* regex) - : DeathTest(), - statement_(statement), - regex_(regex), - forked_(false), - child_pid_(-1), - read_fd_(-1), - write_fd_(-1), - status_(-1), - outcome_(IN_PROGRESS) { -} - -// Reads an internal failure message from a file descriptor, then calls -// LOG(FATAL) with that message. Called from a death test parent process -// to read a failure message from the death test child process. -static void FailFromInternalError(int fd) { - Message error; - char buffer[256]; - ssize_t num_read; - - do { - while ((num_read = read(fd, buffer, 255)) > 0) { - buffer[num_read] = '\0'; - error << buffer; - } - } while (num_read == -1 && errno == EINTR); - - // TODO(smcafee): Maybe just FAIL the test instead? - if (num_read == 0) { - GTEST_LOG(FATAL, error); - } else { - GTEST_LOG(FATAL, - Message() << "Error while reading death test internal: " - << strerror(errno) << " [" << errno << "]"); - } -} - -// Waits for the child in a death test to exit, returning its exit -// status, or 0 if no child process exists. As a side effect, sets the -// outcome data member. -int ForkingDeathTest::Wait() { - if (!forked_) - return 0; - - // The read() here blocks until data is available (signifying the - // failure of the death test) or until the pipe is closed (signifying - // its success), so it's okay to call this in the parent before - // the child process has exited. - char flag; - ssize_t bytes_read; - - do { - bytes_read = read(read_fd_, &flag, 1); - } while (bytes_read == -1 && errno == EINTR); - - if (bytes_read == 0) { - outcome_ = DIED; - } else if (bytes_read == 1) { - switch (flag) { - case kDeathTestReturned: - outcome_ = RETURNED; - break; - case kDeathTestLived: - outcome_ = LIVED; - break; - case kDeathTestInternalError: - FailFromInternalError(read_fd_); // Does not return. - break; - default: - GTEST_LOG(FATAL, - Message() << "Death test child process reported unexpected " - << "status byte (" << static_cast<unsigned int>(flag) - << ")"); - } - } else { - GTEST_LOG(FATAL, - Message() << "Read from death test child process failed: " - << strerror(errno)); - } - - GTEST_DEATH_TEST_CHECK_SYSCALL(close(read_fd_)); - GTEST_DEATH_TEST_CHECK_SYSCALL(waitpid(child_pid_, &status_, 0)); - return status_; -} - -// Assesses the success or failure of a death test, using both private -// members which have previously been set, and one argument: -// -// Private data members: -// outcome: an enumeration describing how the death test -// concluded: DIED, LIVED, or RETURNED. The death test fails -// in the latter two cases -// status: the exit status of the child process, in the format -// specified by wait(2) -// regex: a regular expression object to be applied to -// the test's captured standard error output; the death test -// fails if it does not match -// -// Argument: -// status_ok: true if exit_status is acceptable in the context of -// this particular death test, which fails if it is false -// -// Returns true iff all of the above conditions are met. Otherwise, the -// first failing condition, in the order given above, is the one that is -// reported. Also sets the static variable last_death_test_message. -bool ForkingDeathTest::Passed(bool status_ok) { - if (!forked_) - return false; - -#if GTEST_HAS_GLOBAL_STRING - const ::string error_message = GetCapturedStderr(); -#else - const ::std::string error_message = GetCapturedStderr(); -#endif // GTEST_HAS_GLOBAL_STRING - - bool success = false; - Message buffer; - - buffer << "Death test: " << statement_ << "\n"; - switch (outcome_) { - case LIVED: - buffer << " Result: failed to die.\n" - << " Error msg: " << error_message; - break; - case RETURNED: - buffer << " Result: illegal return in test statement.\n" - << " Error msg: " << error_message; - break; - case DIED: - if (status_ok) { - if (RE::PartialMatch(error_message, *regex_)) { - success = true; - } else { - buffer << " Result: died but not with expected error.\n" - << " Expected: " << regex_->pattern() << "\n" - << "Actual msg: " << error_message; - } - } else { - buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status_) << "\n"; - } - break; - default: - GTEST_LOG(FATAL, - "DeathTest::Passed somehow called before conclusion of test"); - } - - last_death_test_message = buffer.GetString(); - return success; -} - -// Signals that the death test code which should have exited, didn't. -// Should be called only in a death test child process. -// Writes a status byte to the child's status file desriptor, then -// calls _exit(1). -void ForkingDeathTest::Abort(AbortReason reason) { - // The parent process considers the death test to be a failure if - // it finds any data in our pipe. So, here we write a single flag byte - // to the pipe, then exit. - const char flag = - reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; - GTEST_DEATH_TEST_CHECK_SYSCALL(write(write_fd_, &flag, 1)); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(write_fd_)); - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) -} - -// A concrete death test class that forks, then immediately runs the test -// in the child process. -class NoExecDeathTest : public ForkingDeathTest { - public: - NoExecDeathTest(const char* statement, const RE* regex) : - ForkingDeathTest(statement, regex) { } - virtual TestRole AssumeRole(); -}; - -// The AssumeRole process for a fork-and-run death test. It implements a -// straightforward fork, with a simple pipe to transmit the status byte. -DeathTest::TestRole NoExecDeathTest::AssumeRole() { - const size_t thread_count = GetThreadCount(); - if (thread_count != 1) { - GTEST_LOG(WARNING, DeathTestThreadWarning(thread_count)); - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1); - - last_death_test_message = ""; - CaptureStderr(); - // When we fork the process below, the log file buffers are copied, but the - // file descriptors are shared. We flush all log files here so that closing - // the file descriptors in the child process doesn't throw off the - // synchronization between descriptors and buffers in the parent process. - // This is as close to the fork as possible to avoid a race condition in case - // there are multiple threads running before the death test, and another - // thread writes to the log file. - FlushInfoLog(); - - const pid_t child_pid = fork(); - GTEST_DEATH_TEST_CHECK(child_pid != -1); - set_child_pid(child_pid); - if (child_pid == 0) { - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[0])); - set_write_fd(pipe_fd[1]); - // Redirects all logging to stderr in the child process to prevent - // concurrent writes to the log files. We capture stderr in the parent - // process and append the child process' output to a log. - LogToStderr(); - return EXECUTE_TEST; - } else { - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1])); - set_read_fd(pipe_fd[0]); - set_forked(true); - return OVERSEE_TEST; - } -} - -// A concrete death test class that forks and re-executes the main -// program from the beginning, with command-line flags set that cause -// only this specific death test to be run. -class ExecDeathTest : public ForkingDeathTest { - public: - ExecDeathTest(const char* statement, const RE* regex, - const char* file, int line) : - ForkingDeathTest(statement, regex), file_(file), line_(line) { } - virtual TestRole AssumeRole(); - private: - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; -}; - -// Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { - args_.push_back(NULL); - } - ~Arguments() { - for (std::vector<char*>::iterator i = args_.begin(); - i + 1 != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, strdup(argument)); - } - - template <typename Str> - void AddArguments(const ::std::vector<Str>& arguments) { - for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); - i != arguments.end(); - ++i) { - args_.insert(args_.end() - 1, strdup(i->c_str())); - } - } - char* const* Argv() { - return &args_[0]; - } - private: - std::vector<char*> args_; -}; - -// A struct that encompasses the arguments to the child process of a -// threadsafe-style death test process. -struct ExecDeathTestArgs { - char* const* argv; // Command-line arguments for the child's call to exec - int close_fd; // File descriptor to close; the read end of a pipe -}; - -// The main function for a threadsafe-style death test child process. -static int ExecDeathTestChildMain(void* child_arg) { - ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(args->close_fd)); - execve(args->argv[0], args->argv, environ); - DeathTestAbort("execve failed: %s", strerror(errno)); - return EXIT_FAILURE; -} - -// Two utility routines that together determine the direction the stack -// grows. -// This could be accomplished more elegantly by a single recursive -// function, but we want to guard against the unlikely possibility of -// a smart compiler optimizing the recursion away. -static bool StackLowerThanAddress(const void* ptr) { - int dummy; - return &dummy < ptr; -} - -static bool StackGrowsDown() { - int dummy; - return StackLowerThanAddress(&dummy); -} - -// A threadsafe implementation of fork(2) for threadsafe-style death tests -// that uses clone(2). It dies with an error message if anything goes -// wrong. -static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { - static const bool stack_grows_down = StackGrowsDown(); - const size_t stack_size = getpagesize(); - void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - GTEST_DEATH_TEST_CHECK(stack != MAP_FAILED); - void* const stack_top = - static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); - ExecDeathTestArgs args = { argv, close_fd }; - const pid_t child_pid = clone(&ExecDeathTestChildMain, stack_top, - SIGCHLD, &args); - GTEST_DEATH_TEST_CHECK(child_pid != -1); - GTEST_DEATH_TEST_CHECK(munmap(stack, stack_size) != -1); - return child_pid; -} - -// The AssumeRole process for a fork-and-exec death test. It re-executes the -// main program from the beginning, setting the --gtest_filter -// and --gtest_internal_run_death_test flags to cause only the current -// death test to be re-run. -DeathTest::TestRole ExecDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); - - if (flag != NULL) { - set_write_fd(flag->status_fd); - return EXECUTE_TEST; - } - - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK(pipe(pipe_fd) != -1); - // Clear the close-on-exec flag on the write end of the pipe, lest - // it be closed when the child process does an exec: - GTEST_DEATH_TEST_CHECK(fcntl(pipe_fd[1], F_SETFD, 0) != -1); - - const String filter_flag = - String::Format("--%s%s=%s.%s", - GTEST_FLAG_PREFIX, kFilterFlag, - info->test_case_name(), info->name()); - const String internal_flag = - String::Format("--%s%s=%s:%d:%d:%d", - GTEST_FLAG_PREFIX, kInternalRunDeathTestFlag, file_, line_, - death_test_index, pipe_fd[1]); - Arguments args; - args.AddArguments(GetArgvs()); - args.AddArgument("--logtostderr"); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); - - last_death_test_message = ""; - - CaptureStderr(); - // See the comment in NoExecDeathTest::AssumeRole for why the next line - // is necessary. - FlushInfoLog(); - - const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); - GTEST_DEATH_TEST_CHECK_SYSCALL(close(pipe_fd[1])); - set_child_pid(child_pid); - set_read_fd(pipe_fd[0]); - set_forked(true); - return OVERSEE_TEST; -} - -// Creates a concrete DeathTest-derived class that depends on the -// --gtest_death_test_style flag, and sets the pointer pointed to -// by the "test" argument to its address. If the test should be -// skipped, sets that pointer to NULL. Returns true, unless the -// flag is set to an invalid value. -bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, - const char* file, int line, - DeathTest** test) { - UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const int death_test_index = impl->current_test_info() - ->increment_death_test_count(); - - if (flag != NULL) { - if (death_test_index > flag->index) { - last_death_test_message = String::Format( - "Death test count (%d) somehow exceeded expected maximum (%d)", - death_test_index, flag->index); - return false; - } - - if (!(flag->file == file && flag->line == line && - flag->index == death_test_index)) { - *test = NULL; - return true; - } - } - - if (GTEST_FLAG(death_test_style) == "threadsafe") { - *test = new ExecDeathTest(statement, regex, file, line); - } else if (GTEST_FLAG(death_test_style) == "fast") { - *test = new NoExecDeathTest(statement, regex); - } else { - last_death_test_message = String::Format( - "Unknown death test style \"%s\" encountered", - GTEST_FLAG(death_test_style).c_str()); - return false; - } - - return true; -} - -// Splits a given string on a given delimiter, populating a given -// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have -// ::std::string, so we can use it here. -static void SplitString(const ::std::string& str, char delimiter, - ::std::vector< ::std::string>* dest) { - ::std::vector< ::std::string> parsed; - ::std::string::size_type pos = 0; - while (true) { - const ::std::string::size_type colon = str.find(':', pos); - if (colon == ::std::string::npos) { - parsed.push_back(str.substr(pos)); - break; - } else { - parsed.push_back(str.substr(pos, colon - pos)); - pos = colon + 1; - } - } - dest->swap(parsed); -} - -// Attempts to parse a string into a positive integer. Returns true -// if that is possible. GTEST_HAS_DEATH_TEST implies that we have -// ::std::string, so we can use it here. -static bool ParsePositiveInt(const ::std::string& str, int* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtol's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !isdigit(str[0])) { - return false; - } - char* endptr; - const long parsed = strtol(str.c_str(), &endptr, 10); // NOLINT - if (*endptr == '\0' && parsed <= INT_MAX) { - *number = static_cast<int>(parsed); - return true; - } else { - return false; - } -} - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { - if (GTEST_FLAG(internal_run_death_test) == "") return NULL; - - InternalRunDeathTestFlag* const internal_run_death_test_flag = - new InternalRunDeathTestFlag; - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), ':', &fields); - if (fields.size() != 4 - || !ParsePositiveInt(fields[1], &internal_run_death_test_flag->line) - || !ParsePositiveInt(fields[2], &internal_run_death_test_flag->index) - || !ParsePositiveInt(fields[3], - &internal_run_death_test_flag->status_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: %s", - GTEST_FLAG(internal_run_death_test).c_str()); - } - internal_run_death_test_flag->file = fields[0].c_str(); - return internal_run_death_test_flag; -} - -} // namespace internal - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace testing diff --git a/src/gtest/gtest-death-test.h b/src/gtest/gtest-death-test.h deleted file mode 100644 index cbd41fe6..00000000 --- a/src/gtest/gtest-death-test.h +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the public API for death tests. It is -// #included by gtest.h so a user doesn't need to include this -// directly. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ - -#include <gtest/internal/gtest-death-test-internal.h> - -namespace testing { - -// This flag controls the style of death tests. Valid values are "threadsafe", -// meaning that the death test child process will re-execute the test binary -// from the start, running only a single death test, or "fast", -// meaning that the child process will execute the test logic immediately -// after forking. -GTEST_DECLARE_string(death_test_style); - -#ifdef GTEST_HAS_DEATH_TEST - -// The following macros are useful for writing death tests. - -// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is -// executed: -// -// 1. The assertion fails immediately if there are more than one -// active threads. This is because it's safe to fork() only when -// there is a single thread. -// -// 2. The parent process forks a sub-process and runs the death test -// in it; the sub-process exits with code 0 at the end of the death -// test, if it hasn't exited already. -// -// 3. The parent process waits for the sub-process to terminate. -// -// 4. The parent process checks the exit code and error message of -// the sub-process. -// -// Note: -// -// It's not safe to call exit() if the current process is forked from -// a multi-threaded process, so people usually call _exit() instead in -// such a case. However, we are not concerned with this as we run -// death tests only when there is a single thread. Since exit() has a -// cleaner semantics (it also calls functions registered with atexit() -// and on_exit()), this macro calls exit() instead of _exit() to -// terminate the child process. -// -// Examples: -// -// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); -// for (int i = 0; i < 5; i++) { -// EXPECT_DEATH(server.ProcessRequest(i), -// "Invalid request .* in ProcessRequest()") -// << "Failed to die on request " << i); -// } -// -// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); -// -// bool KilledBySIGHUP(int exit_code) { -// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; -// } -// -// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); - -// Asserts that a given statement causes the program to exit, with an -// integer exit status that satisfies predicate, and emitting error output -// that matches regex. -#define ASSERT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST(statement, predicate, regex, GTEST_FATAL_FAILURE) - -// Like ASSERT_EXIT, but continues on to successive tests in the -// test case, if any: -#define EXPECT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST(statement, predicate, regex, GTEST_NONFATAL_FAILURE) - -// Asserts that a given statement causes the program to exit, either by -// explicitly exiting with a nonzero exit code or being killed by a -// signal, and emitting error output that matches regex. -#define ASSERT_DEATH(statement, regex) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) - -// Like ASSERT_DEATH, but continues on to successive tests in the -// test case, if any: -#define EXPECT_DEATH(statement, regex) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) - -// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: - -// Tests that an exit code describes a normal exit with a given exit code. -class ExitedWithCode { - public: - explicit ExitedWithCode(int exit_code); - bool operator()(int exit_status) const; - private: - const int exit_code_; -}; - -// Tests that an exit code describes an exit due to termination by a -// given signal. -class KilledBySignal { - public: - explicit KilledBySignal(int signum); - bool operator()(int exit_status) const; - private: - const int signum_; -}; - -// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. -// The death testing framework causes this to have interesting semantics, -// since the sideeffects of the call are only visible in opt mode, and not -// in debug mode. -// -// In practice, this can be used to test functions that utilize the -// LOG(DFATAL) macro using the following style: -// -// int DieInDebugOr12(int* sideeffect) { -// if (sideeffect) { -// *sideeffect = 12; -// } -// LOG(DFATAL) << "death"; -// return 12; -// } -// -// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { -// int sideeffect = 0; -// // Only asserts in dbg. -// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); -// -// #ifdef NDEBUG -// // opt-mode has sideeffect visible. -// EXPECT_EQ(12, sideeffect); -// #else -// // dbg-mode no visible sideeffect. -// EXPECT_EQ(0, sideeffect); -// #endif -// } -// -// This will assert that DieInDebugReturn12InOpt() crashes in debug -// mode, usually due to a DCHECK or LOG(DFATAL), but returns the -// appropriate fallback value (12 in this case) in opt mode. If you -// need to test that a function has appropriate side-effects in opt -// mode, include assertions against the side-effects. A general -// pattern for this is: -// -// EXPECT_DEBUG_DEATH({ -// // Side-effects here will have an effect after this statement in -// // opt mode, but none in debug mode. -// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); -// }, "death"); -// -#ifdef NDEBUG - -#define EXPECT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) - -#define ASSERT_DEBUG_DEATH(statement, regex) \ - do { statement; } while (false) - -#else - -#define EXPECT_DEBUG_DEATH(statement, regex) \ - EXPECT_DEATH(statement, regex) - -#define ASSERT_DEBUG_DEATH(statement, regex) \ - ASSERT_DEATH(statement, regex) - -#endif // NDEBUG for EXPECT_DEBUG_DEATH -#endif // GTEST_HAS_DEATH_TEST -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/src/gtest/gtest-filepath.cc b/src/gtest/gtest-filepath.cc deleted file mode 100644 index 2fba96ea..00000000 --- a/src/gtest/gtest-filepath.cc +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// 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. -// -// Authors: keith.ray@gmail.com (Keith Ray) - -#include <gtest/internal/gtest-filepath.h> -#include <gtest/internal/gtest-port.h> - -#ifdef _WIN32 -#include <direct.h> -#include <io.h> -#endif // _WIN32 - -#include <sys/stat.h> - -#include <gtest/internal/gtest-string.h> - -namespace testing { -namespace internal { - -#ifdef GTEST_OS_WINDOWS -const char kPathSeparator = '\\'; -const char kPathSeparatorString[] = "\\"; -const char kCurrentDirectoryString[] = ".\\"; -#else -const char kPathSeparator = '/'; -const char kPathSeparatorString[] = "/"; -const char kCurrentDirectoryString[] = "./"; -#endif // GTEST_OS_WINDOWS - -// Returns a copy of the FilePath with the case-insensitive extension removed. -// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns -// FilePath("dir/file"). If a case-insensitive extension is not -// found, returns a copy of the original FilePath. -FilePath FilePath::RemoveExtension(const char* extension) const { - String dot_extension(String::Format(".%s", extension)); - if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { - return FilePath(String(pathname_.c_str(), pathname_.GetLength() - 4)); - } - return *this; -} - -// Returns a copy of the FilePath with the directory part removed. -// Example: FilePath("path/to/file").RemoveDirectoryName() returns -// FilePath("file"). If there is no directory part ("just_a_file"), it returns -// the FilePath unmodified. If there is no file part ("just_a_dir/") it -// returns an empty FilePath (""). -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); - return last_sep ? FilePath(String(last_sep + 1)) : *this; -} - -// RemoveFileName returns the directory path with the filename removed. -// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". -// If the FilePath is "a_file" or "/a_file", RemoveFileName returns -// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does -// not have a file, like "just/a/dir/", it returns the FilePath unmodified. -// On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveFileName() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); - return FilePath(last_sep ? String(c_str(), last_sep + 1 - c_str()) - : String(kCurrentDirectoryString)); -} - -// Helper functions for naming files in a directory for xml output. - -// Given directory = "dir", base_name = "test", number = 0, -// extension = "xml", returns "dir/test.xml". If number is greater -// than zero (e.g., 12), returns "dir/test_12.xml". -// On Windows platform, uses \ as the separator rather than /. -FilePath FilePath::MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension) { - FilePath dir(directory.RemoveTrailingPathSeparator()); - if (number == 0) { - return FilePath(String::Format("%s%c%s.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), extension)); - } - return FilePath(String::Format("%s%c%s_%d.%s", dir.c_str(), kPathSeparator, - base_name.c_str(), number, extension)); -} - -// Returns true if pathname describes something findable in the file-system, -// either a file, directory, or whatever. -bool FilePath::FileOrDirectoryExists() const { -#ifdef GTEST_OS_WINDOWS - struct _stat file_stat = {}; - return _stat(pathname_.c_str(), &file_stat) == 0; -#else - struct stat file_stat = {}; - return stat(pathname_.c_str(), &file_stat) == 0; -#endif // GTEST_OS_WINDOWS -} - -// Returns true if pathname describes a directory in the file-system -// that exists. -bool FilePath::DirectoryExists() const { - bool result = false; -#ifdef _WIN32 - FilePath removed_sep(this->RemoveTrailingPathSeparator()); - struct _stat file_stat = {}; - result = _stat(removed_sep.c_str(), &file_stat) == 0 && - (_S_IFDIR & file_stat.st_mode) != 0; -#else - struct stat file_stat = {}; - result = stat(pathname_.c_str(), &file_stat) == 0 && - S_ISDIR(file_stat.st_mode); -#endif // _WIN32 - return result; -} - -// Returns a pathname for a file that does not currently exist. The pathname -// will be directory/base_name.extension or -// directory/base_name_<number>.extension if directory/base_name.extension -// already exists. The number will be incremented until a pathname is found -// that does not already exist. -// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. -// There could be a race condition if two or more processes are calling this -// function at the same time -- they could both pick the same filename. -FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension) { - FilePath full_pathname; - int number = 0; - do { - full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); - } while (full_pathname.FileOrDirectoryExists()); - return full_pathname; -} - -// Returns true if FilePath ends with a path separator, which indicates that -// it is intended to represent a directory. Returns false otherwise. -// This does NOT check that a directory (or file) actually exists. -bool FilePath::IsDirectory() const { - return pathname_.EndsWith(kPathSeparatorString); -} - -// Create directories so that path exists. Returns true if successful or if -// the directories already exist; returns false if unable to create directories -// for any reason. -bool FilePath::CreateDirectoriesRecursively() const { - if (!this->IsDirectory()) { - return false; - } - - if (pathname_.GetLength() == 0 || this->DirectoryExists()) { - return true; - } - - const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); - return parent.CreateDirectoriesRecursively() && this->CreateFolder(); -} - -// Create the directory so that path exists. Returns true if successful or -// if the directory already exists; returns false if unable to create the -// directory for any reason, including if the parent directory does not -// exist. Not named "CreateDirectory" because that's a macro on Windows. -bool FilePath::CreateFolder() const { -#ifdef _WIN32 - int result = _mkdir(pathname_.c_str()); -#else - int result = mkdir(pathname_.c_str(), 0777); -#endif // _WIN32 - if (result == -1) { - return this->DirectoryExists(); // An error is OK if the directory exists. - } - return true; // No error. -} - -// If input name has a trailing separator character, remove it and return the -// name, otherwise return the name string unmodified. -// On Windows platform, uses \ as the separator, other platforms use /. -FilePath FilePath::RemoveTrailingPathSeparator() const { - return pathname_.EndsWith(kPathSeparatorString) - ? FilePath(String(pathname_.c_str(), pathname_.GetLength() - 1)) - : *this; -} - -} // namespace internal -} // namespace testing diff --git a/src/gtest/gtest-internal-inl.h b/src/gtest/gtest-internal-inl.h deleted file mode 100644 index 2a7d71cb..00000000 --- a/src/gtest/gtest-internal-inl.h +++ /dev/null @@ -1,1118 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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. - -// Utility functions and classes used by the Google C++ testing framework. -// -// Author: wan@google.com (Zhanyong Wan) -// -// This file contains purely Google Test's internal implementation. Please -// DO NOT #INCLUDE IT IN A USER PROGRAM. - -#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ -#define GTEST_SRC_GTEST_INTERNAL_INL_H_ - -// GTEST_IMPLEMENTATION is defined iff the current translation unit is -// part of Google Test's implementation. -#ifndef GTEST_IMPLEMENTATION -// A user is trying to include this from his code - just say no. -#error "gtest-internal-inl.h is part of Google Test's internal implementation." -#error "It must not be included except by Google Test itself." -#endif // GTEST_IMPLEMENTATION - -#include <stddef.h> - -#include <gtest/internal/gtest-port.h> - -#ifdef GTEST_OS_WINDOWS -#include <windows.h> // NOLINT -#endif // GTEST_OS_WINDOWS - -#include <ostream> // NOLINT -#include <gtest/gtest.h> -#include <gtest/gtest-spi.h> - -namespace testing { - -// Declares the flags. -// -// We don't want the users to modify these flags in the code, but want -// Google Test's own unit tests to be able to access them. Therefore we -// declare them here as opposed to in gtest.h. -GTEST_DECLARE_bool(break_on_failure); -GTEST_DECLARE_bool(catch_exceptions); -GTEST_DECLARE_string(color); -GTEST_DECLARE_string(filter); -GTEST_DECLARE_bool(list_tests); -GTEST_DECLARE_string(output); -GTEST_DECLARE_int32(repeat); -GTEST_DECLARE_int32(stack_trace_depth); -GTEST_DECLARE_bool(show_internal_stack_frames); - -namespace internal { - -// Names of the flags (needed for parsing Google Test flags). -const char kBreakOnFailureFlag[] = "break_on_failure"; -const char kCatchExceptionsFlag[] = "catch_exceptions"; -const char kFilterFlag[] = "filter"; -const char kListTestsFlag[] = "list_tests"; -const char kOutputFlag[] = "output"; -const char kColorFlag[] = "color"; -const char kRepeatFlag[] = "repeat"; - -// This class saves the values of all Google Test flags in its c'tor, and -// restores them in its d'tor. -class GTestFlagSaver { - public: - // The c'tor. - GTestFlagSaver() { - break_on_failure_ = GTEST_FLAG(break_on_failure); - catch_exceptions_ = GTEST_FLAG(catch_exceptions); - color_ = GTEST_FLAG(color); - death_test_style_ = GTEST_FLAG(death_test_style); - filter_ = GTEST_FLAG(filter); - internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); - list_tests_ = GTEST_FLAG(list_tests); - output_ = GTEST_FLAG(output); - repeat_ = GTEST_FLAG(repeat); - } - - // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. - ~GTestFlagSaver() { - GTEST_FLAG(break_on_failure) = break_on_failure_; - GTEST_FLAG(catch_exceptions) = catch_exceptions_; - GTEST_FLAG(color) = color_; - GTEST_FLAG(death_test_style) = death_test_style_; - GTEST_FLAG(filter) = filter_; - GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; - GTEST_FLAG(list_tests) = list_tests_; - GTEST_FLAG(output) = output_; - GTEST_FLAG(repeat) = repeat_; - } - private: - // Fields for saving the original values of flags. - bool break_on_failure_; - bool catch_exceptions_; - String color_; - String death_test_style_; - String filter_; - String internal_run_death_test_; - bool list_tests_; - String output_; - bool pretty_; - internal::Int32 repeat_; -} GTEST_ATTRIBUTE_UNUSED; - -// Converts a Unicode code-point to its UTF-8 encoding. -String ToUtf8String(wchar_t wchar); - -// Returns the number of active threads, or 0 when there is an error. -size_t GetThreadCount(); - -// List is a simple singly-linked list container. -// -// We cannot use std::list as Microsoft's implementation of STL has -// problems when exception is disabled. There is a hack to work -// around this, but we've seen cases where the hack fails to work. -// -// TODO(wan): switch to std::list when we have a reliable fix for the -// STL problem, e.g. when we upgrade to the next version of Visual -// C++, or (more likely) switch to STLport. -// -// The element type must support copy constructor. - -// Forward declare List -template <typename E> // E is the element type. -class List; - -// ListNode is a node in a singly-linked list. It consists of an -// element and a pointer to the next node. The last node in the list -// has a NULL value for its next pointer. -template <typename E> // E is the element type. -class ListNode { - friend class List<E>; - - private: - - E element_; - ListNode * next_; - - // The c'tor is private s.t. only in the ListNode class and in its - // friend class List we can create a ListNode object. - // - // Creates a node with a given element value. The next pointer is - // set to NULL. - // - // ListNode does NOT have a default constructor. Always use this - // constructor (with parameter) to create a ListNode object. - explicit ListNode(const E & element) : element_(element), next_(NULL) {} - - // We disallow copying ListNode - GTEST_DISALLOW_COPY_AND_ASSIGN(ListNode); - - public: - - // Gets the element in this node. - E & element() { return element_; } - const E & element() const { return element_; } - - // Gets the next node in the list. - ListNode * next() { return next_; } - const ListNode * next() const { return next_; } -}; - - -// List is a simple singly-linked list container. -template <typename E> // E is the element type. -class List { - public: - - // Creates an empty list. - List() : head_(NULL), last_(NULL), size_(0) {} - - // D'tor. - virtual ~List(); - - // Clears the list. - void Clear() { - if ( size_ > 0 ) { - // 1. Deletes every node. - ListNode<E> * node = head_; - ListNode<E> * next = node->next(); - for ( ; ; ) { - delete node; - node = next; - if ( node == NULL ) break; - next = node->next(); - } - - // 2. Resets the member variables. - head_ = last_ = NULL; - size_ = 0; - } - } - - // Gets the number of elements. - int size() const { return size_; } - - // Returns true if the list is empty. - bool IsEmpty() const { return size() == 0; } - - // Gets the first element of the list, or NULL if the list is empty. - ListNode<E> * Head() { return head_; } - const ListNode<E> * Head() const { return head_; } - - // Gets the last element of the list, or NULL if the list is empty. - ListNode<E> * Last() { return last_; } - const ListNode<E> * Last() const { return last_; } - - // Adds an element to the end of the list. A copy of the element is - // created using the copy constructor, and then stored in the list. - // Changes made to the element in the list doesn't affect the source - // object, and vice versa. - void PushBack(const E & element) { - ListNode<E> * new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - last_->next_ = new_node; - last_ = new_node; - size_++; - } - } - - // Adds an element to the beginning of this list. - void PushFront(const E& element) { - ListNode<E>* const new_node = new ListNode<E>(element); - - if ( size_ == 0 ) { - head_ = last_ = new_node; - size_ = 1; - } else { - new_node->next_ = head_; - head_ = new_node; - size_++; - } - } - - // Removes an element from the beginning of this list. If the - // result argument is not NULL, the removed element is stored in the - // memory it points to. Otherwise the element is thrown away. - // Returns true iff the list wasn't empty before the operation. - bool PopFront(E* result) { - if (size_ == 0) return false; - - if (result != NULL) { - *result = head_->element_; - } - - ListNode<E>* const old_head = head_; - size_--; - if (size_ == 0) { - head_ = last_ = NULL; - } else { - head_ = head_->next_; - } - delete old_head; - - return true; - } - - // Inserts an element after a given node in the list. It's the - // caller's responsibility to ensure that the given node is in the - // list. If the given node is NULL, inserts the element at the - // front of the list. - ListNode<E>* InsertAfter(ListNode<E>* node, const E& element) { - if (node == NULL) { - PushFront(element); - return Head(); - } - - ListNode<E>* const new_node = new ListNode<E>(element); - new_node->next_ = node->next_; - node->next_ = new_node; - size_++; - if (node == last_) { - last_ = new_node; - } - - return new_node; - } - - // Returns the number of elements that satisfy a given predicate. - // The parameter 'predicate' is a Boolean function or functor that - // accepts a 'const E &', where E is the element type. - template <typename P> // P is the type of the predicate function/functor - int CountIf(P predicate) const { - int count = 0; - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { - count++; - } - } - - return count; - } - - // Applies a function/functor to each element in the list. The - // parameter 'functor' is a function/functor that accepts a 'const - // E &', where E is the element type. This method does not change - // the elements. - template <typename F> // F is the type of the function/functor - void ForEach(F functor) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - functor(node->element()); - } - } - - // Returns the first node whose element satisfies a given predicate, - // or NULL if none is found. The parameter 'predicate' is a - // function/functor that accepts a 'const E &', where E is the - // element type. This method does not change the elements. - template <typename P> // P is the type of the predicate function/functor. - const ListNode<E> * FindIf(P predicate) const { - for ( const ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element()) ) { - return node; - } - } - - return NULL; - } - - template <typename P> - ListNode<E> * FindIf(P predicate) { - for ( ListNode<E> * node = Head(); - node != NULL; - node = node->next() ) { - if ( predicate(node->element() ) ) { - return node; - } - } - - return NULL; - } - - private: - ListNode<E>* head_; // The first node of the list. - ListNode<E>* last_; // The last node of the list. - int size_; // The number of elements in the list. - - // We disallow copying List. - GTEST_DISALLOW_COPY_AND_ASSIGN(List); -}; - -// The virtual destructor of List. -template <typename E> -List<E>::~List() { - Clear(); -} - -// A function for deleting an object. Handy for being used as a -// functor. -template <typename T> -static void Delete(T * x) { - delete x; -} - -// A copyable object representing a user specified test property which can be -// output as a key/value string pair. -// -// Don't inherit from TestProperty as its destructor is not virtual. -class TestProperty { - public: - // C'tor. TestProperty does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestProperty object. - TestProperty(const char* key, const char* value) : - key_(key), value_(value) { - } - - // Gets the user supplied key. - const char* key() const { - return key_.c_str(); - } - - // Gets the user supplied value. - const char* value() const { - return value_.c_str(); - } - - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const char* new_value) { - value_ = new_value; - } - - private: - // The key supplied by the user. - String key_; - // The value supplied by the user. - String value_; -}; - -// A predicate that checks the key of a TestProperty against a known key. -// -// TestPropertyKeyIs is copyable. -class TestPropertyKeyIs { - public: - // Constructor. - // - // TestPropertyKeyIs has NO default constructor. - explicit TestPropertyKeyIs(const char* key) - : key_(key) {} - - // Returns true iff the test name of test property matches on key_. - bool operator()(const TestProperty& test_property) const { - return String(test_property.key()).Compare(key_) == 0; - } - - private: - String key_; -}; - -// The result of a single Test. This includes a list of -// TestPartResults, a list of TestProperties, a count of how many -// death tests there are in the Test, and how much time it took to run -// the Test. -// -// TestResult is not copyable. -class TestResult { - public: - // Creates an empty TestResult. - TestResult(); - - // D'tor. Do not inherit from TestResult. - ~TestResult(); - - // Gets the list of TestPartResults. - const internal::List<TestPartResult> & test_part_results() const { - return test_part_results_; - } - - // Gets the list of TestProperties. - const internal::List<internal::TestProperty> & test_properties() const { - return test_properties_; - } - - // Gets the number of successful test parts. - int successful_part_count() const; - - // Gets the number of failed test parts. - int failed_part_count() const; - - // Gets the number of all test parts. This is the sum of the number - // of successful test parts and the number of failed test parts. - int total_part_count() const; - - // Returns true iff the test passed (i.e. no test part failed). - bool Passed() const { return !Failed(); } - - // Returns true iff the test failed. - bool Failed() const { return failed_part_count() > 0; } - - // Returns true iff the test fatally failed. - bool HasFatalFailure() const; - - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); - - // Adds a test property to the list. The property is validated and may add - // a non-fatal failure if invalid (e.g., if it conflicts with reserved - // key names). If a property is already recorded for the same key, the - // value will be updated, rather than storing multiple values for the same - // key. - void RecordProperty(const internal::TestProperty& test_property); - - // Adds a failure if the key is a reserved attribute of Google Test - // testcase tags. Returns true if the property is valid. - // TODO(russr): Validate attribute names are legal and human readable. - static bool ValidateTestProperty(const internal::TestProperty& test_property); - - // Returns the death test count. - int death_test_count() const { return death_test_count_; } - - // Increments the death test count, returning the new count. - int increment_death_test_count() { return ++death_test_count_; } - - // Clears the object. - void Clear(); - private: - // Protects mutable state of the property list and of owned properties, whose - // values may be updated. - internal::Mutex test_properites_mutex_; - - // The list of TestPartResults - internal::List<TestPartResult> test_part_results_; - // The list of TestProperties - internal::List<internal::TestProperty> test_properties_; - // Running count of death tests. - int death_test_count_; - // The elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - - // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN(TestResult); -}; // class TestResult - -class TestInfoImpl { - public: - TestInfoImpl(TestInfo* parent, const char* test_case_name, - const char* name, TypeId fixture_class_id, - TestMaker maker); - ~TestInfoImpl(); - - // Returns true if this test should run. - bool should_run() const { return should_run_; } - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Returns true if this test is disabled. Disabled tests are not run. - bool is_disabled() const { return is_disabled_; } - - // Sets the is_disabled member. - void set_is_disabled(bool is) { is_disabled_ = is; } - - // Returns the test case name. - const char* test_case_name() const { return test_case_name_.c_str(); } - - // Returns the test name. - const char* name() const { return name_.c_str(); } - - // Returns the ID of the test fixture class. - TypeId fixture_class_id() const { return fixture_class_id_; } - - // Returns the test result. - internal::TestResult* result() { return &result_; } - const internal::TestResult* result() const { return &result_; } - - // Creates the test object, runs it, records its result, and then - // deletes it. - void Run(); - - // Calls the given TestInfo object's Run() method. - static void RunTest(TestInfo * test_info) { - test_info->impl()->Run(); - } - - // Clears the test result. - void ClearResult() { result_.Clear(); } - - // Clears the test result in the given TestInfo object. - static void ClearTestResult(TestInfo * test_info) { - test_info->impl()->ClearResult(); - } - - private: - // These fields are immutable properties of the test. - TestInfo* const parent_; // The owner of this object - const String test_case_name_; // Test case name - const String name_; // Test name - const TypeId fixture_class_id_; // ID of the test fixture class - bool should_run_; // True iff this test should run - bool is_disabled_; // True iff this test is disabled - const TestMaker maker_; // The function that creates the test object - - // This field is mutable and needs to be reset before running the - // test for the second time. - internal::TestResult result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(TestInfoImpl); -}; - -} // namespace internal - -// A test case, which consists of a list of TestInfos. -// -// TestCase is not copyable. -class TestCase { - public: - // Creates a TestCase with the given name. - // - // TestCase does NOT have a default constructor. Always use this - // constructor to create a TestCase object. - // - // Arguments: - // - // name: name of the test case - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase(const char* name, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); - - // Destructor of TestCase. - virtual ~TestCase(); - - // Gets the name of the TestCase. - const char* name() const { return name_.c_str(); } - - // Returns true if any test in this test case should run. - bool should_run() const { return should_run_; } - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Gets the (mutable) list of TestInfos in this TestCase. - internal::List<TestInfo*>& test_info_list() { return *test_info_list_; } - - // Gets the (immutable) list of TestInfos in this TestCase. - const internal::List<TestInfo *> & test_info_list() const { - return *test_info_list_; - } - - // Gets the number of successful tests in this test case. - int successful_test_count() const; - - // Gets the number of failed tests in this test case. - int failed_test_count() const; - - // Gets the number of disabled tests in this test case. - int disabled_test_count() const; - - // Get the number of tests in this test case that should run. - int test_to_run_count() const; - - // Gets the number of all tests in this test case. - int total_test_count() const; - - // Returns true iff the test case passed. - bool Passed() const { return !Failed(); } - - // Returns true iff the test case failed. - bool Failed() const { return failed_test_count() > 0; } - - // Returns the elapsed time, in milliseconds. - internal::TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Adds a TestInfo to this test case. Will delete the TestInfo upon - // destruction of the TestCase object. - void AddTestInfo(TestInfo * test_info); - - // Finds and returns a TestInfo with the given name. If one doesn't - // exist, returns NULL. - TestInfo* GetTestInfo(const char* test_name); - - // Clears the results of all tests in this test case. - void ClearResult(); - - // Clears the results of all tests in the given test case. - static void ClearTestCaseResult(TestCase* test_case) { - test_case->ClearResult(); - } - - // Runs every test in this TestCase. - void Run(); - - // Runs every test in the given TestCase. - static void RunTestCase(TestCase * test_case) { test_case->Run(); } - - // Returns true iff test passed. - static bool TestPassed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Passed(); - } - - // Returns true iff test failed. - static bool TestFailed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Failed(); - } - - // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo * test_info) { - return test_info->impl()->is_disabled(); - } - - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo *test_info) { - return test_info->impl()->should_run(); - } - - private: - // Name of the test case. - internal::String name_; - // List of TestInfos. - internal::List<TestInfo*>* test_info_list_; - // Pointer to the function that sets up the test case. - Test::SetUpTestCaseFunc set_up_tc_; - // Pointer to the function that tears down the test case. - Test::TearDownTestCaseFunc tear_down_tc_; - // True iff any test in this test case should run. - bool should_run_; - // Elapsed time, in milliseconds. - internal::TimeInMillis elapsed_time_; - - // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN(TestCase); -}; - -namespace internal { - -// Class UnitTestOptions. -// -// This class contains functions for processing options the user -// specifies when running the tests. It has only static members. -// -// In most cases, the user can specify an option using either an -// environment variable or a command line flag. E.g. you can set the -// test filter using either GTEST_FILTER or --gtest_filter. If both -// the variable and the flag are present, the latter overrides the -// former. -class UnitTestOptions { - public: - // Functions for processing the gtest_output flag. - - // Returns the output format, or "" for normal printed output. - static String GetOutputFormat(); - - // Returns the name of the requested output file, or the default if none - // was explicitly specified. - static String GetOutputFile(); - - // Functions for processing the gtest_filter flag. - - // Returns true iff the wildcard pattern matches the string. The - // first ':' or '\0' character in pattern marks the end of it. - // - // This recursive algorithm isn't very efficient, but is clear and - // works well enough for matching test names, which are short. - static bool PatternMatchesString(const char *pattern, const char *str); - - // Returns true iff the user-specified filter matches the test case - // name and the test name. - static bool FilterMatchesTest(const String &test_case_name, - const String &test_name); - -#ifdef GTEST_OS_WINDOWS - // Function for supporting the gtest_catch_exception flag. - - // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the - // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. - // This function is useful as an __except condition. - static int GTestShouldProcessSEH(DWORD exception_code); -#endif // GTEST_OS_WINDOWS - private: - // Returns true if "name" matches the ':' separated list of glob-style - // filters in "filter". - static bool MatchesFilter(const String& name, const char* filter); -}; - -// Returns the current application's name, removing directory path if that -// is present. Used by UnitTestOptions::GetOutputFile. -FilePath GetCurrentExecutableName(); - -// The role interface for getting the OS stack trace as a string. -class OsStackTraceGetterInterface { - public: - OsStackTraceGetterInterface() {} - virtual ~OsStackTraceGetterInterface() {} - - // Returns the current OS stack trace as a String. Parameters: - // - // max_depth - the maximum number of stack frames to be included - // in the trace. - // skip_count - the number of top frames to be skipped; doesn't count - // against max_depth. - virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; - - // UponLeavingGTest() should be called immediately before Google Test calls - // user code. It saves some information about the current stack that - // CurrentStackTrace() will use to find and hide Google Test stack frames. - virtual void UponLeavingGTest() = 0; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetterInterface); -}; - -// A working implemenation of the OsStackTraceGetterInterface interface. -class OsStackTraceGetter : public OsStackTraceGetterInterface { - public: - OsStackTraceGetter() {} - virtual String CurrentStackTrace(int max_depth, int skip_count); - virtual void UponLeavingGTest(); - - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; - - private: - Mutex mutex_; // protects all internal state - - // We save the stack frame below the frame that calls user code. - // We do this because the address of the frame immediately below - // the user code changes between the call to UponLeavingGTest() - // and any calls to CurrentStackTrace() from within the user code. - void* caller_frame_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(OsStackTraceGetter); -}; - -// Information about a Google Test trace point. -struct TraceInfo { - const char* file; - int line; - String message; -}; - -// The private implementation of the UnitTest class. We don't protect -// the methods under a mutex, as this class is not accessible by a -// user and the UnitTest class that delegates work to this class does -// proper locking. -class UnitTestImpl : public TestPartResultReporterInterface { - public: - explicit UnitTestImpl(UnitTest* parent); - virtual ~UnitTestImpl(); - - // Reports a test part result. This method is from the - // TestPartResultReporterInterface interface. - virtual void ReportTestPartResult(const TestPartResult& result); - - // Returns the current test part result reporter. - TestPartResultReporterInterface* test_part_result_reporter(); - - // Sets the current test part result reporter. - void set_test_part_result_reporter(TestPartResultReporterInterface* reporter); - - // Gets the number of successful test cases. - int successful_test_case_count() const; - - // Gets the number of failed test cases. - int failed_test_case_count() const; - - // Gets the number of all test cases. - int total_test_case_count() const; - - // Gets the number of all test cases that contain at least one test - // that should run. - int test_case_to_run_count() const; - - // Gets the number of successful tests. - int successful_test_count() const; - - // Gets the number of failed tests. - int failed_test_count() const; - - // Gets the number of disabled tests. - int disabled_test_count() const; - - // Gets the number of all tests. - int total_test_count() const; - - // Gets the number of tests that should run. - int test_to_run_count() const; - - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } - - // Returns true iff the unit test passed (i.e. all test cases passed). - bool Passed() const { return !Failed(); } - - // Returns true iff the unit test failed (i.e. some test case failed - // or something outside of all tests failed). - bool Failed() const { - return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); - } - - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - internal::TestResult* current_test_result(); - - // Returns the TestResult for the ad hoc test. - const internal::TestResult* ad_hoc_test_result() const { - return &ad_hoc_test_result_; - } - - // Sets the unit test result printer. - // - // Does nothing if the input and the current printer object are the - // same; otherwise, deletes the old printer object and makes the - // input the current printer. - void set_result_printer(UnitTestEventListenerInterface * result_printer); - - // Returns the current unit test result printer if it is not NULL; - // otherwise, creates an appropriate result printer, makes it the - // current printer, and returns it. - UnitTestEventListenerInterface* result_printer(); - - // Sets the OS stack trace getter. - // - // Does nothing if the input and the current OS stack trace getter - // are the same; otherwise, deletes the old getter and makes the - // input the current getter. - void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); - - // Returns the current OS stack trace getter if it is not NULL; - // otherwise, creates an OsStackTraceGetter, makes it the current - // getter, and returns it. - OsStackTraceGetterInterface* os_stack_trace_getter(); - - // Returns the current OS stack trace as a String. - // - // The maximum number of stack frames to be included is specified by - // the gtest_stack_trace_depth flag. The skip_count parameter - // specifies the number of top frames to be skipped, which doesn't - // count against the number of frames to be included. - // - // For example, if Foo() calls Bar(), which in turn calls - // CurrentOsStackTraceExceptTop(1), Foo() will be included in the - // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - String CurrentOsStackTraceExceptTop(int skip_count); - - // Finds and returns a TestCase with the given name. If one doesn't - // exist, creates one and returns it. - // - // Arguments: - // - // test_case_name: name of the test case - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase* GetTestCase(const char* test_case_name, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); - - // Adds a TestInfo to the unit test. - // - // Arguments: - // - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - // test_info: the TestInfo object - void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - TestInfo * test_info) { - GetTestCase(test_info->test_case_name(), - set_up_tc, - tear_down_tc)->AddTestInfo(test_info); - } - - // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* current_test_case) { - current_test_case_ = current_test_case; - } - - // Sets the TestInfo object for the test that's currently running. If - // current_test_info is NULL, the assertion results will be stored in - // ad_hoc_test_result_. - void set_current_test_info(TestInfo* current_test_info) { - current_test_info_ = current_test_info; - } - - // Runs all tests in this UnitTest object, prints the result, and - // returns 0 if all tests are successful, or 1 otherwise. If any - // exception is thrown during a test on Windows, this test is - // considered to be failed, but the rest of the tests will still be - // run. (We disable exceptions on Linux and Mac OS X, so the issue - // doesn't apply there.) - int RunAllTests(); - - // Clears the results of all tests, including the ad hoc test. - void ClearResult() { - test_cases_.ForEach(TestCase::ClearTestCaseResult); - ad_hoc_test_result_.Clear(); - } - - // Matches the full name of each test against the user-specified - // filter to decide whether the test should run, then records the - // result in each TestCase and TestInfo object. - // Returns the number of tests that should run. - int FilterTests(); - - // Lists all the tests by name. - void ListAllTests(); - - const TestCase* current_test_case() const { return current_test_case_; } - TestInfo* current_test_info() { return current_test_info_; } - const TestInfo* current_test_info() const { return current_test_info_; } - - // Returns the list of environments that need to be set-up/torn-down - // before/after the tests are run. - internal::List<Environment*>* environments() { return &environments_; } - internal::List<Environment*>* environments_in_reverse_order() { - return &environments_in_reverse_order_; - } - - internal::List<TestCase*>* test_cases() { return &test_cases_; } - const internal::List<TestCase*>* test_cases() const { return &test_cases_; } - - // Getters for the per-thread Google Test trace stack. - internal::List<TraceInfo>* gtest_trace_stack() { - return gtest_trace_stack_.pointer(); - } - const internal::List<TraceInfo>* gtest_trace_stack() const { - return gtest_trace_stack_.pointer(); - } - -#ifdef GTEST_HAS_DEATH_TEST - // Returns a pointer to the parsed --gtest_internal_run_death_test - // flag, or NULL if that flag was not specified. - // This information is useful only in a death test child process. - const InternalRunDeathTestFlag* internal_run_death_test_flag() const { - return internal_run_death_test_flag_.get(); - } - - // Returns a pointer to the current death test factory. - internal::DeathTestFactory* death_test_factory() { - return death_test_factory_.get(); - } - - friend class ReplaceDeathTestFactory; -#endif // GTEST_HAS_DEATH_TEST - - private: - // The UnitTest object that owns this implementation object. - UnitTest* const parent_; - - // Points to (but doesn't own) the test part result reporter. - TestPartResultReporterInterface* test_part_result_reporter_; - - // The list of environments that need to be set-up/torn-down - // before/after the tests are run. environments_in_reverse_order_ - // simply mirrors environments_ in reverse order. - internal::List<Environment*> environments_; - internal::List<Environment*> environments_in_reverse_order_; - - internal::List<TestCase*> test_cases_; // The list of TestCases. - - // Points to the last death test case registered. Initially NULL. - internal::ListNode<TestCase*>* last_death_test_case_; - - // This points to the TestCase for the currently running test. It - // changes as Google Test goes through one test case after another. - // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initally NULL. - TestCase* current_test_case_; - - // This points to the TestInfo for the currently running test. It - // changes as Google Test goes through one test after another. When - // no test is running, this is set to NULL and Google Test stores - // assertion results in ad_hoc_test_result_. Initially NULL. - TestInfo* current_test_info_; - - // Normally, a user only writes assertions inside a TEST or TEST_F, - // or inside a function called by a TEST or TEST_F. Since Google - // Test keeps track of which test is current running, it can - // associate such an assertion with the test it belongs to. - // - // If an assertion is encountered when no TEST or TEST_F is running, - // Google Test attributes the assertion result to an imaginary "ad hoc" - // test, and records the result in ad_hoc_test_result_. - internal::TestResult ad_hoc_test_result_; - - // The unit test result printer. Will be deleted when the UnitTest - // object is destructed. By default, a plain text printer is used, - // but the user can set this field to use a custom printer if that - // is desired. - UnitTestEventListenerInterface* result_printer_; - - // The OS stack trace getter. Will be deleted when the UnitTest - // object is destructed. By default, an OsStackTraceGetter is used, - // but the user can set this field to use a custom getter if that is - // desired. - OsStackTraceGetterInterface* os_stack_trace_getter_; - - // How long the test took to run, in milliseconds. - TimeInMillis elapsed_time_; - -#ifdef GTEST_HAS_DEATH_TEST - // The decomposed components of the gtest_internal_run_death_test flag, - // parsed when RUN_ALL_TESTS is called. - internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; - internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_; -#endif // GTEST_HAS_DEATH_TEST - - // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal<internal::List<TraceInfo> > gtest_trace_stack_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestImpl); -}; // class UnitTestImpl - -// Convenience function for accessing the global UnitTest -// implementation object. -inline UnitTestImpl* GetUnitTestImpl() { - return UnitTest::GetInstance()->impl(); -} - -} // namespace internal -} // namespace testing - -#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/src/gtest/gtest-message.h b/src/gtest/gtest-message.h deleted file mode 100644 index 746a1685..00000000 --- a/src/gtest/gtest-message.h +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the Message class. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! - -#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ -#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-string.h" // NOLINT -#include "gtest-internal.h" // NOLINT -#else -#include <gtest/internal/gtest-string.h> -#include <gtest/internal/gtest-internal.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -namespace testing { - -// The Message class works like an ostream repeater. -// -// Typical usage: -// -// 1. You stream a bunch of values to a Message object. -// It will remember the text in a StrStream. -// 2. Then you stream the Message object to an ostream. -// This causes the text in the Message to be streamed -// to the ostream. -// -// For example; -// -// testing::Message foo; -// foo << 1 << " != " << 2; -// std::cout << foo; -// -// will print "1 != 2". -// -// Message is not intended to be inherited from. In particular, its -// destructor is not virtual. -// -// Note that StrStream behaves differently in gcc and in MSVC. You -// can stream a NULL char pointer to it in the former, but not in the -// latter (it causes an access violation if you do). The Message -// class hides this difference by treating a NULL char pointer as -// "(null)". -class Message { - private: - // The type of basic IO manipulators (endl, ends, and flush) for - // narrow streams. - typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); - - public: - // Constructs an empty Message. - // We allocate the StrStream separately because it otherwise each use of - // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's - // stack frame leading to huge stack frames in some cases; gcc does not reuse - // the stack space. - Message() : ss_(new internal::StrStream) {} - - // Copy constructor. - Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT - *ss_ << msg.GetString(); - } - - // Constructs a Message from a C-string. - explicit Message(const char* str) : ss_(new internal::StrStream) { - *ss_ << str; - } - - ~Message() { delete ss_; } -#ifdef __SYMBIAN32__ - // Streams a value (either a pointer or not) to this object. - template <typename T> - inline Message& operator <<(const T& value) { - StreamHelper(typename internal::is_pointer<T>::type(), value); - return *this; - } -#else - // Streams a non-pointer value to this object. - template <typename T> - inline Message& operator <<(const T& val) { - ::GTestStreamToHelper(ss_, val); - return *this; - } - - // Streams a pointer value to this object. - // - // This function is an overload of the previous one. When you - // stream a pointer to a Message, this definition will be used as it - // is more specialized. (The C++ Standard, section - // [temp.func.order].) If you stream a non-pointer, then the - // previous definition will be used. - // - // The reason for this overload is that streaming a NULL pointer to - // ostream is undefined behavior. Depending on the compiler, you - // may get "0", "(nil)", "(null)", or an access violation. To - // ensure consistent result across compilers, we always treat NULL - // as "(null)". - template <typename T> - inline Message& operator <<(T* const& pointer) { // NOLINT - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - ::GTestStreamToHelper(ss_, pointer); - } - return *this; - } -#endif // __SYMBIAN32__ - - // Since the basic IO manipulators are overloaded for both narrow - // and wide streams, we have to provide this specialized definition - // of operator <<, even though its body is the same as the - // templatized version above. Without this definition, streaming - // endl or other basic IO manipulators to Message will confuse the - // compiler. - Message& operator <<(BasicNarrowIoManip val) { - *ss_ << val; - return *this; - } - - // Instead of 1/0, we want to see true/false for bool values. - Message& operator <<(bool b) { - return *this << (b ? "true" : "false"); - } - - // These two overloads allow streaming a wide C string to a Message - // using the UTF-8 encoding. - Message& operator <<(const wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); - } - Message& operator <<(wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); - } - -#if GTEST_HAS_STD_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::std::wstring& wstr); -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::wstring& wstr); -#endif // GTEST_HAS_GLOBAL_WSTRING - - // Gets the text streamed to this object so far as a String. - // Each '\0' character in the buffer is replaced with "\\0". - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - internal::String GetString() const { - return internal::StrStreamToString(ss_); - } - - private: -#ifdef __SYMBIAN32__ - // These are needed as the Nokia Symbian Compiler cannot decide between - // const T& and const T* in a function template. The Nokia compiler _can_ - // decide between class template specializations for T and T*, so a - // tr1::type_traits-like is_pointer works, and we can overload on that. - template <typename T> - inline void StreamHelper(internal::true_type dummy, T* pointer) { - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - ::GTestStreamToHelper(ss_, pointer); - } - } - template <typename T> - inline void StreamHelper(internal::false_type dummy, const T& value) { - ::GTestStreamToHelper(ss_, value); - } -#endif // __SYMBIAN32__ - - // We'll hold the text streamed to this object here. - internal::StrStream* const ss_; - - // We declare (but don't implement) this to prevent the compiler - // from implementing the assignment operator. - void operator=(const Message&); -}; - -// Streams a Message to an ostream. -inline std::ostream& operator <<(std::ostream& os, const Message& sb) { - return os << sb.GetString(); -} - -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/src/gtest/gtest-port.cc b/src/gtest/gtest-port.cc deleted file mode 100644 index 5c126149..00000000 --- a/src/gtest/gtest-port.cc +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) - -#include <gtest/internal/gtest-port.h> - -#include <limits.h> -#ifdef GTEST_HAS_DEATH_TEST -#include <regex.h> -#endif // GTEST_HAS_DEATH_TEST -#include <stdlib.h> -#include <stdio.h> - -#include <gtest/gtest-spi.h> -#include <gtest/gtest-message.h> -#include <gtest/internal/gtest-string.h> - -namespace testing { -namespace internal { - -#ifdef GTEST_HAS_DEATH_TEST - -// Implements RE. Currently only needed for death tests. - -RE::~RE() { - regfree(®ex_); - free(const_cast<char*>(pattern_)); -} - -// Returns true iff str contains regular expression re. -bool RE::PartialMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; - - regmatch_t match; - return regexec(&re.regex_, str, 1, &match, 0) == 0; -} - -// Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = strdup(regex); - is_valid_ = regcomp(®ex_, regex, REG_EXTENDED) == 0; - EXPECT_TRUE(is_valid_) - << "Regular expression \"" << regex - << "\" is not a valid POSIX Extended regular expression."; -} - -#endif // GTEST_HAS_DEATH_TEST - -// Logs a message at the given severity level. -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg) { - const char* const marker = - severity == GTEST_INFO ? "[ INFO ]" : - severity == GTEST_WARNING ? "[WARNING]" : - severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg); - if (severity == GTEST_FATAL) { - abort(); - } -} - -#ifdef GTEST_HAS_DEATH_TEST - -// Defines the stderr capturer. - -class CapturedStderr { - public: - // The ctor redirects stderr to a temporary file. - CapturedStderr() { - uncaptured_fd_ = dup(STDERR_FILENO); - - char name_template[] = "captured_stderr.XXXXXX"; - const int captured_fd = mkstemp(name_template); - filename_ = name_template; - fflush(NULL); - dup2(captured_fd, STDERR_FILENO); - close(captured_fd); - } - - ~CapturedStderr() { - remove(filename_.c_str()); - } - - // Stops redirecting stderr. - void StopCapture() { - // Restores the original stream. - fflush(NULL); - dup2(uncaptured_fd_, STDERR_FILENO); - close(uncaptured_fd_); - uncaptured_fd_ = -1; - } - - // Returns the name of the temporary file holding the stderr output. - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - ::std::string filename() const { return filename_; } - - private: - int uncaptured_fd_; - ::std::string filename_; -}; - -static CapturedStderr* g_captured_stderr = NULL; - -// Returns the size (in bytes) of a file. -static size_t GetFileSize(FILE * file) { - fseek(file, 0, SEEK_END); - return static_cast<size_t>(ftell(file)); -} - -// Reads the entire content of a file as a string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. -static ::std::string ReadEntireFile(FILE * file) { - const size_t file_size = GetFileSize(file); - char* const buffer = new char[file_size]; - - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far - - fseek(file, 0, SEEK_SET); - - // Keeps reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); - - const ::std::string content(buffer, buffer+bytes_read); - delete[] buffer; - - return content; -} - -// Starts capturing stderr. -void CaptureStderr() { - if (g_captured_stderr != NULL) { - GTEST_LOG(FATAL, "Only one stderr capturer can exist at one time."); - } - g_captured_stderr = new CapturedStderr; -} - -// Stops capturing stderr and returns the captured string. -// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can -// use it here. -::std::string GetCapturedStderr() { - g_captured_stderr->StopCapture(); - FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r"); - const ::std::string content = ReadEntireFile(file); - fclose(file); - - delete g_captured_stderr; - g_captured_stderr = NULL; - - return content; -} - -// A copy of all command line arguments. Set by ParseGTestFlags(). -::std::vector<String> g_argvs; - -// Returns the command line as a vector of strings. -const ::std::vector<String>& GetArgvs() { return g_argvs; } - -#endif // GTEST_HAS_DEATH_TEST - -// Returns the name of the environment variable corresponding to the -// given flag. For example, FlagToEnvVar("foo") will return -// "GTEST_FOO" in the open-source version. -static String FlagToEnvVar(const char* flag) { - const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString(); - - Message env_var; - for (int i = 0; i != full_flag.GetLength(); i++) { - env_var << static_cast<char>(toupper(full_flag.c_str()[i])); - } - - return env_var.GetString(); -} - -// Reads and returns the Boolean environment variable corresponding to -// the given flag; if it's not set, returns default_value. -// -// The value is considered true iff it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { - const String env_var = FlagToEnvVar(flag); - const char* const string_value = GetEnv(env_var.c_str()); - return string_value == NULL ? - default_value : strcmp(string_value, "0") != 0; -} - -// Parses 'str' for a 32-bit signed integer. If successful, writes -// the result to *value and returns true; otherwise leaves *value -// unchanged and returns false. -bool ParseInt32(const Message& src_text, const char* str, Int32* value) { - // Parses the environment variable as a decimal integer. - char* end = NULL; - const long long_value = strtol(str, &end, 10); // NOLINT - - // Has strtol() consumed all characters in the string? - if (*end != '\0') { - // No - an invalid character was encountered. - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value \"" << str << "\".\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - // Is the parsed value in the range of an Int32? - const Int32 result = static_cast<Int32>(long_value); - if (long_value == LONG_MAX || long_value == LONG_MIN || - // The parsed value overflows as a long. (strtol() returns - // LONG_MAX or LONG_MIN when the input overflows.) - result != long_value - // The parsed value overflows as an Int32. - ) { - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } - - *value = result; - return true; -} - -// Reads and returns a 32-bit integer stored in the environment -// variable corresponding to the given flag; if it isn't set or -// doesn't represent a valid 32-bit integer, returns default_value. -Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { - const String env_var = FlagToEnvVar(flag); - const char* const string_value = GetEnv(env_var.c_str()); - if (string_value == NULL) { - // The environment variable is not set. - return default_value; - } - - Int32 result = default_value; - if (!ParseInt32(Message() << "Environment variable " << env_var, - string_value, &result)) { - printf("The default value %s is used.\n", - (Message() << default_value).GetString().c_str()); - fflush(stdout); - return default_value; - } - - return result; -} - -// Reads and returns the string environment variable corresponding to -// the given flag; if it's not set, returns default_value. -const char* StringFromGTestEnv(const char* flag, const char* default_value) { - const String env_var = FlagToEnvVar(flag); - const char* const value = GetEnv(env_var.c_str()); - return value == NULL ? default_value : value; -} - -} // namespace internal -} // namespace testing diff --git a/src/gtest/gtest-spi.h b/src/gtest/gtest-spi.h deleted file mode 100644 index 75d0dcf2..00000000 --- a/src/gtest/gtest-spi.h +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2007, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// Utilities for testing Google Test itself and code that uses Google Test -// (e.g. frameworks built on top of Google Test). - -#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ -#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ - -#include <gtest/gtest.h> - -namespace testing { - -// A copyable object representing the result of a test part (i.e. an -// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). -// -// Don't inherit from TestPartResult as its destructor is not virtual. -class TestPartResult { - public: - // C'tor. TestPartResult does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestPartResult object. - TestPartResult(TestPartResultType type, - const char* file_name, - int line_number, - const char* message) - : type_(type), - file_name_(file_name), - line_number_(line_number), - message_(message) { - } - - // Gets the outcome of the test part. - TestPartResultType type() const { return type_; } - - // Gets the name of the source file where the test part took place, or - // NULL if it's unknown. - const char* file_name() const { return file_name_.c_str(); } - - // Gets the line in the source file where the test part took place, - // or -1 if it's unknown. - int line_number() const { return line_number_; } - - // Gets the message associated with the test part. - const char* message() const { return message_.c_str(); } - - // Returns true iff the test part passed. - bool passed() const { return type_ == TPRT_SUCCESS; } - - // Returns true iff the test part failed. - bool failed() const { return type_ != TPRT_SUCCESS; } - - // Returns true iff the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == TPRT_NONFATAL_FAILURE; } - - // Returns true iff the test part fatally failed. - bool fatally_failed() const { return type_ == TPRT_FATAL_FAILURE; } - private: - TestPartResultType type_; - - // The name of the source file where the test part took place, or - // NULL if the source file is unknown. - internal::String file_name_; - // The line in the source file where the test part took place, or -1 - // if the line number is unknown. - int line_number_; - internal::String message_; // The test failure message. -}; - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result); - -// An array of TestPartResult objects. -// -// We define this class as we cannot use STL containers when compiling -// Google Test with MSVC 7.1 and exceptions disabled. -// -// Don't inherit from TestPartResultArray as its destructor is not -// virtual. -class TestPartResultArray { - public: - TestPartResultArray(); - ~TestPartResultArray(); - - // Appends the given TestPartResult to the array. - void Append(const TestPartResult& result); - - // Returns the TestPartResult at the given index (0-based). - const TestPartResult& GetTestPartResult(int index) const; - - // Returns the number of TestPartResult objects in the array. - int size() const; - private: - // Internally we use a list to simulate the array. Yes, this means - // that random access is O(N) in time, but it's OK for its purpose. - internal::List<TestPartResult>* const list_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(TestPartResultArray); -}; - -// This interface knows how to report a test part result. -class TestPartResultReporterInterface { - public: - virtual ~TestPartResultReporterInterface() {} - - virtual void ReportTestPartResult(const TestPartResult& result) = 0; -}; - -// This helper class can be used to mock out Google Test failure reporting -// so that we can test Google Test or code that builds on Google Test. -// -// An object of this class appends a TestPartResult object to the -// TestPartResultArray object given in the constructor whenever a -// Google Test failure is reported. -class ScopedFakeTestPartResultReporter - : public TestPartResultReporterInterface { - public: - // The c'tor sets this object as the test part result reporter used - // by Google Test. The 'result' parameter specifies where to report the - // results. - explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); - - // The d'tor restores the previous test part result reporter. - virtual ~ScopedFakeTestPartResultReporter(); - - // Appends the TestPartResult object to the TestPartResultArray - // received in the constructor. - // - // This method is from the TestPartResultReporterInterface - // interface. - virtual void ReportTestPartResult(const TestPartResult& result); - private: - TestPartResultReporterInterface* const old_reporter_; - TestPartResultArray* const result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(ScopedFakeTestPartResultReporter); -}; - -namespace internal { - -// A helper class for implementing EXPECT_FATAL_FAILURE() and -// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -class SingleFailureChecker { - public: - // The constructor remembers the arguments. - SingleFailureChecker(const TestPartResultArray* results, - TestPartResultType type, - const char* substr); - ~SingleFailureChecker(); - private: - const TestPartResultArray* const results_; - const TestPartResultType type_; - const String substr_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(SingleFailureChecker); -}; - -} // namespace internal - -} // namespace testing - -// A macro for testing Google Test assertions or code that's expected to -// generate Google Test fatal failures. It verifies that the given -// statement will cause exactly one fatal Google Test failure with 'substr' -// being part of the failure message. -// -// Implementation note: The verification is done in the destructor of -// SingleFailureChecker, to make sure that it's done even when -// 'statement' throws an exception. -// -// Known restrictions: -// - 'statement' cannot reference local non-static variables or -// non-static members of the current object. -// - 'statement' cannot return a value. -// - You cannot stream a failure message to this macro. -#define EXPECT_FATAL_FAILURE(statement, substr) do {\ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_FATAL_FAILURE, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ - } while (false) - -// A macro for testing Google Test assertions or code that's expected to -// generate Google Test non-fatal failures. It asserts that the given -// statement will cause exactly one non-fatal Google Test failure with -// 'substr' being part of the failure message. -// -// 'statement' is allowed to reference local variables and members of -// the current object. -// -// Implementation note: The verification is done in the destructor of -// SingleFailureChecker, to make sure that it's done even when -// 'statement' throws an exception or aborts the function. -// -// Known restrictions: -// - You cannot stream a failure message to this macro. -#define EXPECT_NONFATAL_FAILURE(statement, substr) do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - >est_failures);\ - statement;\ - }\ - } while (false) - -#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/src/gtest/gtest.cc b/src/gtest/gtest.cc deleted file mode 100644 index 1eee3922..00000000 --- a/src/gtest/gtest.cc +++ /dev/null @@ -1,3546 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) - -#include <gtest/gtest.h> -#include <gtest/gtest-spi.h> - -#include <ctype.h> -#include <math.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef GTEST_OS_LINUX - -// TODO(kenton): Use autoconf to detect availability of gettimeofday(). -#define HAS_GETTIMEOFDAY - -#include <fcntl.h> -#include <limits.h> -#include <sched.h> -// Declares vsnprintf(). This header is not available on Windows. -#include <strings.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <unistd.h> -#include <string> -#include <vector> - -#elif defined(_WIN32_WCE) // We are on Windows CE. - -#include <windows.h> // NOLINT - -#elif defined(_WIN32) // We are on Windows proper. - -#include <io.h> // NOLINT -#include <sys/timeb.h> // NOLINT -#include <sys/types.h> // NOLINT -#include <sys/stat.h> // NOLINT - -#if defined(__MINGW__) || defined(__MINGW32__) -// MinGW has gettimeofday() but not _ftime64() -// TODO(kenton): Use autoconf to detect availability of gettimeofday(). -// TODO(kenton): There are other ways to get the time on Windows, like -// GetTickCount() or GetSystemTimeAsFileTime(). MinGW supports these. -// consider using them instead. -#define HAS_GETTIMEOFDAY -#include <sys/time.h> // NOLINT -#endif - -// cpplint thinks that the header is already included, so we want to -// silence it. -#include <windows.h> // NOLINT - -#else - -// Assume other platforms have gettimeofday(). -// TODO(kenton): Use autoconf to detect availability of gettimeofday(). -#define HAS_GETTIMEOFDAY - -// cpplint thinks that the header is already included, so we want to -// silence it. -#include <sys/time.h> // NOLINT -#include <unistd.h> // NOLINT - -#endif - -// Indicates that this translation unit is part of Google Test's -// implementation. It must come before gtest-internal-inl.h is -// included, or there will be a compiler error. This trick is to -// prevent a user from accidentally including gtest-internal-inl.h in -// his code. -#define GTEST_IMPLEMENTATION -#include <gtest/gtest-internal-inl.h> -#undef GTEST_IMPLEMENTATION - -#ifdef GTEST_OS_WINDOWS -#define fileno _fileno -#define isatty _isatty -#define vsnprintf _vsnprintf -#endif // GTEST_OS_WINDOWS - -namespace testing { - -// Constants. - -// A test that matches this pattern is disabled and not run. -static const char kDisableTestPattern[] = "DISABLED_*"; - -// A test filter that matches everything. -static const char kUniversalFilter[] = "*"; - -// The default output file for XML output. -static const char kDefaultOutputFile[] = "test_detail.xml"; - -GTEST_DEFINE_bool( - break_on_failure, - internal::BoolFromGTestEnv("break_on_failure", false), - "True iff a failed assertion should be a debugger break-point."); - -GTEST_DEFINE_bool( - catch_exceptions, - internal::BoolFromGTestEnv("catch_exceptions", false), - "True iff " GTEST_NAME - " should catch exceptions and treat them as test failures."); - -GTEST_DEFINE_string( - color, - internal::StringFromGTestEnv("color", "auto"), - "Whether to use colors in the output. Valid values: yes, no, " - "and auto. 'auto' means to use colors if the output is " - "being sent to a terminal and the TERM environment variable " - "is set to xterm or xterm-color."); - -GTEST_DEFINE_string( - filter, - internal::StringFromGTestEnv("filter", kUniversalFilter), - "A colon-separated list of glob (not regex) patterns " - "for filtering the tests to run, optionally followed by a " - "'-' and a : separated list of negative patterns (tests to " - "exclude). A test is run if it matches one of the positive " - "patterns and does not match any of the negative patterns."); - -GTEST_DEFINE_bool(list_tests, false, - "List all tests without running them."); - -GTEST_DEFINE_string( - output, - internal::StringFromGTestEnv("output", ""), - "A format (currently must be \"xml\"), optionally followed " - "by a colon and an output file name or directory. A directory " - "is indicated by a trailing pathname separator. " - "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " - "If a directory is specified, output files will be created " - "within that directory, with file-names based on the test " - "executable's name and, if necessary, made unique by adding " - "digits."); - -GTEST_DEFINE_int32( - repeat, - internal::Int32FromGTestEnv("repeat", 1), - "How many times to repeat each test. Specify a negative number " - "for repeating forever. Useful for shaking out flaky tests."); - -GTEST_DEFINE_int32( - stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), - "The maximum number of stack frames to print when an " - "assertion fails. The valid range is 0 through 100, inclusive."); - -GTEST_DEFINE_bool( - show_internal_stack_frames, false, - "True iff " GTEST_NAME " should include internal stack frames when " - "printing test failure stack traces."); - -namespace internal { - -// GTestIsInitialized() returns true iff the user has initialized -// Google Test. Useful for catching the user mistake of not initializing -// Google Test before calling RUN_ALL_TESTS(). - -// A user must call testing::ParseGTestFlags() to initialize Google -// Test. g_parse_gtest_flags_called is set to true iff -// ParseGTestFlags() has been called. We don't protect this variable -// under a mutex as it is only accessed in the main thread. -static bool g_parse_gtest_flags_called = false; -static bool GTestIsInitialized() { return g_parse_gtest_flags_called; } - -// Iterates over a list of TestCases, keeping a running sum of the -// results of calling a given int-returning method on each. -// Returns the sum. -static int SumOverTestCaseList(const internal::List<TestCase*>& case_list, - int (TestCase::*method)() const) { - int sum = 0; - for (const internal::ListNode<TestCase*>* node = case_list.Head(); - node != NULL; - node = node->next()) { - sum += (node->element()->*method)(); - } - return sum; -} - -// Returns true iff the test case passed. -static bool TestCasePassed(const TestCase* test_case) { - return test_case->should_run() && test_case->Passed(); -} - -// Returns true iff the test case failed. -static bool TestCaseFailed(const TestCase* test_case) { - return test_case->should_run() && test_case->Failed(); -} - -// Returns true iff test_case contains at least one test that should -// run. -static bool ShouldRunTestCase(const TestCase* test_case) { - return test_case->should_run(); -} - -#ifdef _WIN32_WCE -// Windows CE has no C library. The abort() function is used in -// several places in Google Test. This implementation provides a reasonable -// imitation of standard behaviour. -static void abort() { - DebugBreak(); - TerminateProcess(GetCurrentProcess(), 1); -} -#endif // _WIN32_WCE - -// AssertHelper constructor. -AssertHelper::AssertHelper(TestPartResultType type, const char* file, - int line, const char* message) - : type_(type), file_(file), line_(line), message_(message) { -} - -// Message assignment, for assertion streaming support. -void AssertHelper::operator=(const Message& message) const { - UnitTest::GetInstance()-> - AddTestPartResult(type_, file_, line_, - AppendUserMessage(message_, message), - UnitTest::GetInstance()->impl() - ->CurrentOsStackTraceExceptTop(1) - // Skips the stack frame for this function itself. - ); // NOLINT -} - -// Application pathname gotten in ParseGTestFlags. -String g_executable_path; - -// Returns the current application's name, removing directory path if that -// is present. -FilePath GetCurrentExecutableName() { - FilePath result; - -#if defined(_WIN32_WCE) || defined(_WIN32) - result.Set(FilePath(g_executable_path).RemoveExtension("exe")); -#else - result.Set(FilePath(g_executable_path)); -#endif // _WIN32_WCE || _WIN32 - - return result.RemoveDirectoryName(); -} - -// Functions for processing the gtest_output flag. - -// Returns the output format, or "" for normal printed output. -String UnitTestOptions::GetOutputFormat() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) return String(""); - - const char* const colon = strchr(gtest_output_flag, ':'); - return (colon == NULL) ? - String(gtest_output_flag) : - String(gtest_output_flag, colon - gtest_output_flag); -} - -// Returns the name of the requested output file, or the default if none -// was explicitly specified. -String UnitTestOptions::GetOutputFile() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) - return String(""); - - const char* const colon = strchr(gtest_output_flag, ':'); - if (colon == NULL) - return String(kDefaultOutputFile); - - internal::FilePath output_name(colon + 1); - if (!output_name.IsDirectory()) - return output_name.ToString(); - - internal::FilePath result(internal::FilePath::GenerateUniqueFileName( - output_name, internal::GetCurrentExecutableName(), - GetOutputFormat().c_str())); - return result.ToString(); -} - -// Returns true iff the wildcard pattern matches the string. The -// first ':' or '\0' character in pattern marks the end of it. -// -// This recursive algorithm isn't very efficient, but is clear and -// works well enough for matching test names, which are short. -bool UnitTestOptions::PatternMatchesString(const char *pattern, - const char *str) { - switch (*pattern) { - case '\0': - case ':': // Either ':' or '\0' marks the end of the pattern. - return *str == '\0'; - case '?': // Matches any single character. - return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); - case '*': // Matches any string (possibly empty) of characters. - return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || - PatternMatchesString(pattern + 1, str); - default: // Non-special character. Matches itself. - return *pattern == *str && - PatternMatchesString(pattern + 1, str + 1); - } -} - -bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { - const char *cur_pattern = filter; - while (true) { - if (PatternMatchesString(cur_pattern, name.c_str())) { - return true; - } - - // Finds the next pattern in the filter. - cur_pattern = strchr(cur_pattern, ':'); - - // Returns if no more pattern can be found. - if (cur_pattern == NULL) { - return false; - } - - // Skips the pattern separater (the ':' character). - cur_pattern++; - } -} - -// TODO(keithray): move String function implementations to gtest-string.cc. - -// Returns true iff the user-specified filter matches the test case -// name and the test name. -bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, - const String &test_name) { - const String& full_name = String::Format("%s.%s", - test_case_name.c_str(), - test_name.c_str()); - - // Split --gtest_filter at '-', if there is one, to separate into - // positive filter and negative filter portions - const char* const p = GTEST_FLAG(filter).c_str(); - const char* const dash = strchr(p, '-'); - String positive; - String negative; - if (dash == NULL) { - positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter - negative = String(""); - } else { - positive.Set(p, dash - p); // Everything up to the dash - negative = String(dash+1); // Everything after the dash - if (positive.empty()) { - // Treat '-test1' as the same as '*-test1' - positive = kUniversalFilter; - } - } - - // A filter is a colon-separated list of patterns. It matches a - // test if any pattern in it matches the test. - return (MatchesFilter(full_name, positive.c_str()) && - !MatchesFilter(full_name, negative.c_str())); -} - -#ifdef GTEST_OS_WINDOWS -// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the -// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. -// This function is useful as an __except condition. -int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { - // Google Test should handle an exception if: - // 1. the user wants it to, AND - // 2. this is not a breakpoint exception. - return (GTEST_FLAG(catch_exceptions) && - exception_code != EXCEPTION_BREAKPOINT) ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH; -} -#endif // GTEST_OS_WINDOWS - -} // namespace internal - -// The interface for printing the result of a UnitTest -class UnitTestEventListenerInterface { - public: - // The d'tor is pure virtual as this is an abstract class. - virtual ~UnitTestEventListenerInterface() = 0; - - // Called before the unit test starts. - virtual void OnUnitTestStart(const UnitTest*) {} - - // Called after the unit test ends. - virtual void OnUnitTestEnd(const UnitTest*) {} - - // Called before the test case starts. - virtual void OnTestCaseStart(const TestCase*) {} - - // Called after the test case ends. - virtual void OnTestCaseEnd(const TestCase*) {} - - // Called before the global set-up starts. - virtual void OnGlobalSetUpStart(const UnitTest*) {} - - // Called after the global set-up ends. - virtual void OnGlobalSetUpEnd(const UnitTest*) {} - - // Called before the global tear-down starts. - virtual void OnGlobalTearDownStart(const UnitTest*) {} - - // Called after the global tear-down ends. - virtual void OnGlobalTearDownEnd(const UnitTest*) {} - - // Called before the test starts. - virtual void OnTestStart(const TestInfo*) {} - - // Called after the test ends. - virtual void OnTestEnd(const TestInfo*) {} - - // Called after an assertion. - virtual void OnNewTestPartResult(const TestPartResult*) {} -}; - -// Constructs an empty TestPartResultArray. -TestPartResultArray::TestPartResultArray() - : list_(new internal::List<TestPartResult>) { -} - -// Destructs a TestPartResultArray. -TestPartResultArray::~TestPartResultArray() { - delete list_; -} - -// Appends a TestPartResult to the array. -void TestPartResultArray::Append(const TestPartResult& result) { - list_->PushBack(result); -} - -// Returns the TestPartResult at the given index (0-based). -const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { - if (index < 0 || index >= size()) { - printf("\nInvalid index (%d) into TestPartResultArray.\n", index); - abort(); - } - - const internal::ListNode<TestPartResult>* p = list_->Head(); - for (int i = 0; i < index; i++) { - p = p->next(); - } - - return p->element(); -} - -// Returns the number of TestPartResult objects in the array. -int TestPartResultArray::size() const { - return list_->size(); -} - -// The c'tor sets this object as the test part result reporter used by -// Google Test. The 'result' parameter specifies where to report the -// results. -ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - TestPartResultArray* result) - : old_reporter_(UnitTest::GetInstance()->impl()-> - test_part_result_reporter()), - result_(result) { - internal::UnitTestImpl* const impl = UnitTest::GetInstance()->impl(); - impl->set_test_part_result_reporter(this); -} - -// The d'tor restores the test part result reporter used by Google Test -// before. -ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - UnitTest::GetInstance()->impl()-> - set_test_part_result_reporter(old_reporter_); -} - -// Increments the test part result count and remembers the result. -// This method is from the TestPartResultReporterInterface interface. -void ScopedFakeTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - result_->Append(result); -} - -namespace internal { - -// This predicate-formatter checks that 'results' contains a test part -// failure of the given type and that the failure message contains the -// given substring. -AssertionResult HasOneFailure(const char* /* results_expr */, - const char* /* type_expr */, - const char* /* substr_expr */, - const TestPartResultArray& results, - TestPartResultType type, - const char* substr) { - const String expected( - type == TPRT_FATAL_FAILURE ? "1 fatal failure" : - "1 non-fatal failure"); - Message msg; - if (results.size() != 1) { - msg << "Expected: " << expected << "\n" - << " Actual: " << results.size() << " failures"; - for (int i = 0; i < results.size(); i++) { - msg << "\n" << results.GetTestPartResult(i); - } - return AssertionFailure(msg); - } - - const TestPartResult& r = results.GetTestPartResult(0); - if (r.type() != type) { - msg << "Expected: " << expected << "\n" - << " Actual:\n" - << r; - return AssertionFailure(msg); - } - - if (strstr(r.message(), substr) == NULL) { - msg << "Expected: " << expected << " containing \"" - << substr << "\"\n" - << " Actual:\n" - << r; - return AssertionFailure(msg); - } - - return AssertionSuccess(); -} - -// The constructor of SingleFailureChecker remembers where to look up -// test part results, what type of failure we expect, and what -// substring the failure message should contain. -SingleFailureChecker:: SingleFailureChecker( - const TestPartResultArray* results, - TestPartResultType type, - const char* substr) - : results_(results), - type_(type), - substr_(substr) {} - -// The destructor of SingleFailureChecker verifies that the given -// TestPartResultArray contains exactly one failure that has the given -// type and contains the given substring. If that's not the case, a -// non-fatal failure will be generated. -SingleFailureChecker::~SingleFailureChecker() { - EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); -} - -// Reports a test part result. -void UnitTestImpl::ReportTestPartResult(const TestPartResult& result) { - current_test_result()->AddTestPartResult(result); - result_printer()->OnNewTestPartResult(&result); -} - -// Returns the current test part result reporter. -TestPartResultReporterInterface* UnitTestImpl::test_part_result_reporter() { - return test_part_result_reporter_; -} - -// Sets the current test part result reporter. -void UnitTestImpl::set_test_part_result_reporter( - TestPartResultReporterInterface* reporter) { - test_part_result_reporter_ = reporter; -} - -// Gets the number of successful test cases. -int UnitTestImpl::successful_test_case_count() const { - return test_cases_.CountIf(TestCasePassed); -} - -// Gets the number of failed test cases. -int UnitTestImpl::failed_test_case_count() const { - return test_cases_.CountIf(TestCaseFailed); -} - -// Gets the number of all test cases. -int UnitTestImpl::total_test_case_count() const { - return test_cases_.size(); -} - -// Gets the number of all test cases that contain at least one test -// that should run. -int UnitTestImpl::test_case_to_run_count() const { - return test_cases_.CountIf(ShouldRunTestCase); -} - -// Gets the number of successful tests. -int UnitTestImpl::successful_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); -} - -// Gets the number of failed tests. -int UnitTestImpl::failed_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); -} - -// Gets the number of disabled tests. -int UnitTestImpl::disabled_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); -} - -// Gets the number of all tests. -int UnitTestImpl::total_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); -} - -// Gets the number of tests that should run. -int UnitTestImpl::test_to_run_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); -} - -// Returns the current OS stack trace as a String. -// -// The maximum number of stack frames to be included is specified by -// the gtest_stack_trace_depth flag. The skip_count parameter -// specifies the number of top frames to be skipped, which doesn't -// count against the number of frames to be included. -// -// For example, if Foo() calls Bar(), which in turn calls -// CurrentOsStackTraceExceptTop(1), Foo() will be included in the -// trace but Bar() and CurrentOsStackTraceExceptTop() won't. -String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - (void)skip_count; - return String(""); -} - -static TimeInMillis GetTimeInMillis() { -#ifdef _WIN32_WCE // We are on Windows CE - // Difference between 1970-01-01 and 1601-01-01 in miliseconds. - // http://analogous.blogspot.com/2005/04/epoch.html - const TimeInMillis kJavaEpochToWinFileTimeDelta = 11644473600000UL; - const DWORD kTenthMicrosInMilliSecond = 10000; - - SYSTEMTIME now_systime; - FILETIME now_filetime; - ULARGE_INTEGER now_int64; - // TODO(kenton): Shouldn't this just use GetSystemTimeAsFileTime()? - GetSystemTime(&now_systime); - if (SystemTimeToFileTime(&now_systime, &now_filetime)) { - now_int64.LowPart = now_filetime.dwLowDateTime; - now_int64.HighPart = now_filetime.dwHighDateTime; - now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - - kJavaEpochToWinFileTimeDelta; - return now_int64.QuadPart; - } - return 0; -#elif defined(_WIN32) && !defined(HAS_GETTIMEOFDAY) - __timeb64 now; -#ifdef _MSC_VER - // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 - // (deprecated function) there. - // TODO(kenton): Use GetTickCount()? Or use SystemTimeToFileTime() -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - _ftime64(&now); -#pragma warning(pop) // Restores the warning state. -#else - _ftime64(&now); -#endif // _MSC_VER - return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; -#elif defined(HAS_GETTIMEOFDAY) - struct timeval now; - gettimeofday(&now, NULL); - return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; -#else -#error "Don't know how to get the current time on your system." - return 0; -#endif -} - -// Utilities - -// class String - -// Returns the input enclosed in double quotes if it's not NULL; -// otherwise returns "(null)". For example, "\"Hello\"" is returned -// for input "Hello". -// -// This is useful for printing a C string in the syntax of a literal. -// -// Known issue: escape sequences are not handled yet. -String String::ShowCStringQuoted(const char* c_str) { - return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); -} - -// Copies at most length characters from str into a newly-allocated -// piece of memory of size length+1. The memory is allocated with new[]. -// A terminating null byte is written to the memory, and a pointer to it -// is returned. If str is NULL, NULL is returned. -static char* CloneString(const char* str, size_t length) { - if (str == NULL) { - return NULL; - } else { - char* const clone = new char[length + 1]; - // MSVC 8 deprecates strncpy(), so we want to suppress warning - // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - strncpy(clone, str, length); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - strncpy(clone, str, length); -#endif // GTEST_OS_WINDOWS - clone[length] = '\0'; - return clone; - } -} - -// Clones a 0-terminated C string, allocating memory using new. The -// caller is responsible for deleting[] the return value. Returns the -// cloned string, or NULL if the input is NULL. -const char * String::CloneCString(const char* c_str) { - return (c_str == NULL) ? - NULL : CloneString(c_str, strlen(c_str)); -} - -// Compares two C strings. Returns true iff they have the same content. -// -// Unlike strcmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CStringEquals(const char * lhs, const char * rhs) { - if ( lhs == NULL ) return rhs == NULL; - - if ( rhs == NULL ) return false; - - return strcmp(lhs, rhs) == 0; -} - -#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING - -// Converts an array of wide chars to a narrow string using the UTF-8 -// encoding, and streams the result to the given Message object. -static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len, - Message* msg) { - for (size_t i = 0; i != len; i++) { - // TODO(wan): consider allowing a testing::String object to - // contain '\0'. This will make it behave more like std::string, - // and will allow ToUtf8String() to return the correct encoding - // for '\0' s.t. we can get rid of the conditional here (and in - // several other places). - if (wstr[i]) { - *msg << internal::ToUtf8String(wstr[i]); - } else { - *msg << '\0'; - } - } -} - -#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING - -} // namespace internal - -#if GTEST_HAS_STD_WSTRING -// Converts the given wide string to a narrow string using the UTF-8 -// encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::std::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; -} -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_WSTRING -// Converts the given wide string to a narrow string using the UTF-8 -// encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; -} -#endif // GTEST_HAS_GLOBAL_WSTRING - -namespace internal { - -// Formats a value to be used in a failure message. - -// For a char value, we print it as a C++ char literal and as an -// unsigned integer (both in decimal and in hexadecimal). -String FormatForFailureMessage(char ch) { - const unsigned int ch_as_uint = ch; - // A String object cannot contain '\0', so we print "\\0" when ch is - // '\0'. - return String::Format("'%s' (%u, 0x%X)", - ch ? String::Format("%c", ch).c_str() : "\\0", - ch_as_uint, ch_as_uint); -} - -// For a wchar_t value, we print it as a C++ wchar_t literal and as an -// unsigned integer (both in decimal and in hexidecimal). -String FormatForFailureMessage(wchar_t wchar) { - // The C++ standard doesn't specify the exact size of the wchar_t - // type. It just says that it shall have the same size as another - // integral type, called its underlying type. - // - // Therefore, in order to print a wchar_t value in the numeric form, - // we first convert it to the largest integral type (UInt64) and - // then print the converted value. - // - // We use streaming to print the value as "%llu" doesn't work - // correctly with MSVC 7.1. - const UInt64 wchar_as_uint64 = wchar; - Message msg; - // A String object cannot contain '\0', so we print "\\0" when wchar is - // L'\0'. - msg << "L'" << (wchar ? ToUtf8String(wchar).c_str() : "\\0") << "' (" - << wchar_as_uint64 << ", 0x" << ::std::setbase(16) - << wchar_as_uint64 << ")"; - return msg.GetString(); -} - -} // namespace internal - -// AssertionResult constructor. -AssertionResult::AssertionResult(const internal::String& failure_message) - : failure_message_(failure_message) { -} - - -// Makes a successful assertion result. -AssertionResult AssertionSuccess() { - return AssertionResult(); -} - - -// Makes a failed assertion result with the given failure message. -AssertionResult AssertionFailure(const Message& message) { - return AssertionResult(message.GetString()); -} - -namespace internal { - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// expected_expression: "foo" -// actual_expression: "bar" -// expected_value: "5" -// actual_value: "6" -// -// The ignoring_case parameter is true iff the assertion is a -// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will -// be inserted into the message. -AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const String& expected_value, - const String& actual_value, - bool ignoring_case) { - Message msg; - msg << "Value of: " << actual_expression; - if (actual_value != actual_expression) { - msg << "\n Actual: " << actual_value; - } - - msg << "\nExpected: " << expected_expression; - if (ignoring_case) { - msg << " (ignoring case)"; - } - if (expected_value != expected_expression) { - msg << "\nWhich is: " << expected_value; - } - - return AssertionFailure(msg); -} - - -// Helper function for implementing ASSERT_NEAR. -AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error) { - const double diff = fabs(val1 - val2); - if (diff <= abs_error) return AssertionSuccess(); - - // TODO(wan): do not print the value of an expression if it's - // already a literal. - Message msg; - msg << "The difference between " << expr1 << " and " << expr2 - << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ", and\n" - << abs_error_expr << " evaluates to " << abs_error << "."; - return AssertionFailure(msg); -} - - -// Helper template for implementing FloatLE() and DoubleLE(). -template <typename RawType> -AssertionResult FloatingPointLE(const char* expr1, - const char* expr2, - RawType val1, - RawType val2) { - // Returns success if val1 is less than val2, - if (val1 < val2) { - return AssertionSuccess(); - } - - // or if val1 is almost equal to val2. - const FloatingPoint<RawType> lhs(val1), rhs(val2); - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - // Note that the above two checks will both fail if either val1 or - // val2 is NaN, as the IEEE floating-point standard requires that - // any predicate involving a NaN must return false. - - StrStream val1_ss; - val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) - << val1; - - StrStream val2_ss; - val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) - << val2; - - Message msg; - msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StrStreamToString(&val1_ss) << " vs " - << StrStreamToString(&val2_ss); - - return AssertionFailure(msg); -} - -} // namespace internal - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2) { - return internal::FloatingPointLE<float>(expr1, expr2, val1, val2); -} - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2) { - return internal::FloatingPointLE<double>(expr1, expr2, val1, val2); -} - -namespace internal { - -// The helper function for {ASSERT|EXPECT}_EQ with int or enum -// arguments. -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - if (expected == actual) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); -} - -// A macro for implementing the helper functions needed to implement -// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here -// just to avoid copy-and-paste of similar code. -#define GTEST_IMPL_CMP_HELPER(op_name, op)\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - BiggestInt val1, BiggestInt val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - Message msg;\ - msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - return AssertionFailure(msg);\ - }\ -} - -// Implements the helper function for {ASSERT|EXPECT}_NE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER(NE, !=) -// Implements the helper function for {ASSERT|EXPECT}_LE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER(LE, <=) -// Implements the helper function for {ASSERT|EXPECT}_LT with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER(LT, < ) -// Implements the helper function for {ASSERT|EXPECT}_GE with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER(GE, >=) -// Implements the helper function for {ASSERT|EXPECT}_GT with int or -// enum arguments. -GTEST_IMPL_CMP_HELPER(GT, > ) - -#undef GTEST_IMPL_CMP_HELPER - -// The helper function for {ASSERT|EXPECT}_STREQ. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - String::ShowCStringQuoted(expected), - String::ShowCStringQuoted(actual), - false); -} - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CaseInsensitiveCStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - String::ShowCStringQuoted(expected), - String::ShowCStringQuoted(actual), - true); -} - -// The helper function for {ASSERT|EXPECT}_STRNE. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - Message msg; - msg << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - return AssertionFailure(msg); - } -} - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CaseInsensitiveCStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - Message msg; - msg << "Expected: (" << s1_expression << ") != (" - << s2_expression << ") (ignoring case), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - return AssertionFailure(msg); - } -} - -} // namespace internal - -namespace { - -// Helper functions for implementing IsSubString() and IsNotSubstring(). - -// This group of overloaded functions return true iff needle is a -// substring of haystack. NULL is considered a substring of itself -// only. - -bool IsSubstringPred(const char* needle, const char* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; - - return strstr(haystack, needle) != NULL; -} - -bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; - - return wcsstr(haystack, needle) != NULL; -} - -// StringType here can be either ::std::string or ::std::wstring. -template <typename StringType> -bool IsSubstringPred(const StringType& needle, - const StringType& haystack) { - return haystack.find(needle) != StringType::npos; -} - -// This function implements either IsSubstring() or IsNotSubstring(), -// depending on the value of the expected_to_be_substring parameter. -// StringType here can be const char*, const wchar_t*, ::std::string, -// or ::std::wstring. -template <typename StringType> -AssertionResult IsSubstringImpl( - bool expected_to_be_substring, - const char* needle_expr, const char* haystack_expr, - const StringType& needle, const StringType& haystack) { - if (IsSubstringPred(needle, haystack) == expected_to_be_substring) - return AssertionSuccess(); - - const bool is_wide_string = sizeof(needle[0]) > 1; - const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; - return AssertionFailure( - Message() - << "Value of: " << needle_expr << "\n" - << " Actual: " << begin_string_quote << needle << "\"\n" - << "Expected: " << (expected_to_be_substring ? "" : "not ") - << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""); -} - -} // namespace - -// IsSubstring() and IsNotSubstring() check whether needle is a -// substring of haystack (NULL is considered a substring of itself -// only), and return an appropriate error message when they fail. - -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} - -#if GTEST_HAS_STD_STRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} -#endif // GTEST_HAS_STD_STRING - -#if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); -} - -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); -} -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -#ifdef GTEST_OS_WINDOWS - -namespace { - -// Helper function for IsHRESULT{SuccessFailure} predicates -AssertionResult HRESULTFailureHelper(const char* expr, - const char* expected, - long hr) { // NOLINT -#ifdef _WIN32_WCE - // Windows CE doesn't support FormatMessage. - const char error_text[] = ""; -#else - // Looks up the human-readable system message for the HRESULT code - // and since we're not passing any params to FormatMessage, we don't - // want inserts expanded. - const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; - const DWORD kBufSize = 4096; // String::Format can't exceed this length. - // Gets the system's human readable message string for this HRESULT. - char error_text[kBufSize] = { '\0' }; - DWORD message_length = ::FormatMessageA(kFlags, - 0, // no source, we're asking system - hr, // the error - 0, // no line width restrictions - error_text, // output buffer - kBufSize, // buf size - NULL); // no arguments for inserts - // Trims tailing white space (FormatMessage leaves a trailing cr-lf) - for (; message_length && isspace(error_text[message_length - 1]); - --message_length) { - error_text[message_length - 1] = '\0'; - } -#endif // _WIN32_WCE - - const String error_hex(String::Format("0x%08X ", hr)); - Message msg; - msg << "Expected: " << expr << " " << expected << ".\n" - << " Actual: " << error_hex << error_text << "\n"; - - return ::testing::AssertionFailure(msg); -} - -} // namespace - -AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT - if (SUCCEEDED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "succeeds", hr); -} - -AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT - if (FAILED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "fails", hr); -} - -#endif // GTEST_OS_WINDOWS - -// Utility functions for encoding Unicode text (wide strings) in -// UTF-8. - -// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 -// like this: -// -// Code-point length Encoding -// 0 - 7 bits 0xxxxxxx -// 8 - 11 bits 110xxxxx 10xxxxxx -// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx -// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - -// The maximum code-point a one-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1; - -// The maximum code-point a two-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; - -// The maximum code-point a three-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; - -// The maximum code-point a four-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; - -// Chops off the n lowest bits from a bit pattern. Returns the n -// lowest bits. As a side effect, the original bit pattern will be -// shifted to the right by n bits. -inline UInt32 ChopLowBits(UInt32* bits, int n) { - const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); - *bits >>= n; - return low_bits; -} - -// Converts a Unicode code-point to its UTF-8 encoding. -String ToUtf8String(wchar_t wchar) { - char str[5] = {}; // Initializes str to all '\0' characters. - - UInt32 code = static_cast<UInt32>(wchar); - if (code <= kMaxCodePoint1) { - str[0] = static_cast<char>(code); // 0xxxxxxx - } else if (code <= kMaxCodePoint2) { - str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[0] = static_cast<char>(0xC0 | code); // 110xxxxx - } else if (code <= kMaxCodePoint3) { - str[2] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[0] = static_cast<char>(0xE0 | code); // 1110xxxx - } else if (code <= kMaxCodePoint4) { - str[3] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[2] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[1] = static_cast<char>(0x80 | ChopLowBits(&code, 6)); // 10xxxxxx - str[0] = static_cast<char>(0xF0 | code); // 11110xxx - } else { - return String::Format("(Invalid Unicode 0x%llX)", - static_cast<UInt64>(wchar)); - } - - return String(str); -} - -// Converts a wide C string to a String using the UTF-8 encoding. -// NULL will be converted to "(null)". -String String::ShowWideCString(const wchar_t * wide_c_str) { - if (wide_c_str == NULL) return String("(null)"); - - StrStream ss; - while (*wide_c_str) { - ss << internal::ToUtf8String(*wide_c_str++); - } - - return internal::StrStreamToString(&ss); -} - -// Similar to ShowWideCString(), except that this function encloses -// the converted string in double quotes. -String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { - if (wide_c_str == NULL) return String("(null)"); - - return String::Format("L\"%s\"", - String::ShowWideCString(wide_c_str).c_str()); -} - -// Compares two wide C strings. Returns true iff they have the same -// content. -// -// Unlike wcscmp(), this function can handle NULL argument(s). A NULL -// C string is considered different to any non-NULL C string, -// including the empty string. -bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { - if (lhs == NULL) return rhs == NULL; - - if (rhs == NULL) return false; - - return wcscmp(lhs, rhs) == 0; -} - -// Helper function for *_STREQ on wide strings. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual) { - if (String::WideCStringEquals(expected, actual)) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - String::ShowWideCStringQuoted(expected), - String::ShowWideCStringQuoted(actual), - false); -} - -// Helper function for *_STRNE on wide strings. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2) { - if (!String::WideCStringEquals(s1, s2)) { - return AssertionSuccess(); - } - - Message msg; - msg << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: " - << String::ShowWideCStringQuoted(s1) - << " vs " << String::ShowWideCStringQuoted(s2); - return AssertionFailure(msg); -} - -// Compares two C strings, ignoring case. Returns true iff they have -// the same content. -// -// Unlike strcasecmp(), this function can handle NULL argument(s). A -// NULL C string is considered different to any non-NULL C string, -// including the empty string. -bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { - if ( lhs == NULL ) return rhs == NULL; - - if ( rhs == NULL ) return false; - -#ifdef GTEST_OS_WINDOWS - return _stricmp(lhs, rhs) == 0; -#else // GTEST_OS_WINDOWS - return strcasecmp(lhs, rhs) == 0; -#endif // GTEST_OS_WINDOWS -} - -// Constructs a String by copying a given number of chars from a -// buffer. E.g. String("hello", 3) will create the string "hel". -String::String(const char * buffer, size_t len) { - char * const temp = new char[ len + 1 ]; - memcpy(temp, buffer, len); - temp[ len ] = '\0'; - c_str_ = temp; -} - -// Compares this with another String. -// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 -// if this is greater than rhs. -int String::Compare(const String & rhs) const { - if ( c_str_ == NULL ) { - return rhs.c_str_ == NULL ? 0 : -1; // NULL < anything except NULL - } - - return rhs.c_str_ == NULL ? 1 : strcmp(c_str_, rhs.c_str_); -} - -// Returns true iff this String ends with the given suffix. *Any* -// String is considered to end with a NULL or empty suffix. -bool String::EndsWith(const char* suffix) const { - if (suffix == NULL || CStringEquals(suffix, "")) return true; - - if (c_str_ == NULL) return false; - - const size_t this_len = strlen(c_str_); - const size_t suffix_len = strlen(suffix); - return (this_len >= suffix_len) && - CStringEquals(c_str_ + this_len - suffix_len, suffix); -} - -// Returns true iff this String ends with the given suffix, ignoring case. -// Any String is considered to end with a NULL or empty suffix. -bool String::EndsWithCaseInsensitive(const char* suffix) const { - if (suffix == NULL || CStringEquals(suffix, "")) return true; - - if (c_str_ == NULL) return false; - - const size_t this_len = strlen(c_str_); - const size_t suffix_len = strlen(suffix); - return (this_len >= suffix_len) && - CaseInsensitiveCStringEquals(c_str_ + this_len - suffix_len, suffix); -} - -// Sets the 0-terminated C string this String object represents. The -// old string in this object is deleted, and this object will own a -// clone of the input string. This function copies only up to length -// bytes (plus a terminating null byte), or until the first null byte, -// whichever comes first. -// -// This function works even when the c_str parameter has the same -// value as that of the c_str_ field. -void String::Set(const char * c_str, size_t length) { - // Makes sure this works when c_str == c_str_ - const char* const temp = CloneString(c_str, length); - delete[] c_str_; - c_str_ = temp; -} - -// Assigns a C string to this object. Self-assignment works. -const String& String::operator=(const char* c_str) { - // Makes sure this works when c_str == c_str_ - if (c_str != c_str_) { - delete[] c_str_; - c_str_ = CloneCString(c_str); - } - return *this; -} - -// Formats a list of arguments to a String, using the same format -// spec string as for printf. -// -// We do not use the StringPrintf class as it is not universally -// available. -// -// The result is limited to 4096 characters (including the tailing 0). -// If 4096 characters are not enough to format the input, -// "<buffer exceeded>" is returned. -String String::Format(const char * format, ...) { - va_list args; - va_start(args, format); - - char buffer[4096]; - // MSVC 8 deprecates vsnprintf(), so we want to suppress warning - // 4996 (deprecated function) there. -#ifdef GTEST_OS_WINDOWS // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - const int size = - vsnprintf(buffer, sizeof(buffer)/sizeof(buffer[0]) - 1, format, args); -#endif // GTEST_OS_WINDOWS - va_end(args); - - return String(size >= 0 ? buffer : "<buffer exceeded>"); -} - -// Converts the buffer in a StrStream to a String, converting NUL -// bytes to "\\0" along the way. -String StrStreamToString(StrStream* ss) { -#if GTEST_HAS_STD_STRING - const ::std::string& str = ss->str(); - const char* const start = str.c_str(); - const char* const end = start + str.length(); -#else - const char* const start = ss->str(); - const char* const end = start + ss->pcount(); -#endif // GTEST_HAS_STD_STRING - - // We need to use a helper StrStream to do this transformation - // because String doesn't support push_back(). - StrStream helper; - for (const char* ch = start; ch != end; ++ch) { - if (*ch == '\0') { - helper << "\\0"; // Replaces NUL with "\\0"; - } else { - helper.put(*ch); - } - } - -#if GTEST_HAS_STD_STRING - return String(helper.str().c_str()); -#else - const String str(helper.str(), helper.pcount()); - helper.freeze(false); - ss->freeze(false); - return str; -#endif // GTEST_HAS_STD_STRING -} - -// Appends the user-supplied message to the Google-Test-generated message. -String AppendUserMessage(const String& gtest_msg, - const Message& user_msg) { - // Appends the user message if it's non-empty. - const String user_msg_string = user_msg.GetString(); - if (user_msg_string.empty()) { - return gtest_msg; - } - - Message msg; - msg << gtest_msg << "\n" << user_msg_string; - - return msg.GetString(); -} - -} // namespace internal - -// Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os << result.file_name() << ":" - << result.line_number() << ": " - << (result.type() == TPRT_SUCCESS ? "Success" : - result.type() == TPRT_FATAL_FAILURE ? "Fatal failure" : - "Non-fatal failure") << ":\n" - << result.message() << std::endl; -} - -namespace internal { -// class TestResult - -// Creates an empty TestResult. -TestResult::TestResult() - : death_test_count_(0), - elapsed_time_(0) { -} - -// D'tor. -TestResult::~TestResult() { -} - -// Adds a test part result to the list. -void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_.PushBack(test_part_result); -} - -// Adds a test property to the list. If a property with the same key as the -// supplied property is already represented, the value of this test_property -// replaces the old value for that key. -void TestResult::RecordProperty(const TestProperty& test_property) { - if (!ValidateTestProperty(test_property)) { - return; - } - MutexLock lock(&test_properites_mutex_); - ListNode<TestProperty>* const node_with_matching_key = - test_properties_.FindIf(TestPropertyKeyIs(test_property.key())); - if (node_with_matching_key == NULL) { - test_properties_.PushBack(test_property); - return; - } - TestProperty& property_with_matching_key = node_with_matching_key->element(); - property_with_matching_key.SetValue(test_property.value()); -} - -// Adds a failure if the key is a reserved attribute of Google Test testcase tags. -// Returns true if the property is valid. -bool TestResult::ValidateTestProperty(const TestProperty& test_property) { - String key(test_property.key()); - if (key == "name" || key == "status" || key == "time" || key == "classname") { - ADD_FAILURE() - << "Reserved key used in RecordProperty(): " - << key - << " ('name', 'status', 'time', and 'classname' are reserved by " - << GTEST_NAME << ")"; - return false; - } - return true; -} - -// Clears the object. -void TestResult::Clear() { - test_part_results_.Clear(); - test_properties_.Clear(); - death_test_count_ = 0; - elapsed_time_ = 0; -} - -// Returns true iff the test part passed. -static bool TestPartPassed(const TestPartResult & result) { - return result.passed(); -} - -// Gets the number of successful test parts. -int TestResult::successful_part_count() const { - return test_part_results_.CountIf(TestPartPassed); -} - -// Returns true iff the test part failed. -static bool TestPartFailed(const TestPartResult & result) { - return result.failed(); -} - -// Gets the number of failed test parts. -int TestResult::failed_part_count() const { - return test_part_results_.CountIf(TestPartFailed); -} - -// Returns true iff the test part fatally failed. -static bool TestPartFatallyFailed(const TestPartResult & result) { - return result.fatally_failed(); -} - -// Returns true iff the test fatally failed. -bool TestResult::HasFatalFailure() const { - return test_part_results_.CountIf(TestPartFatallyFailed) > 0; -} - -// Gets the number of all test parts. This is the sum of the number -// of successful test parts and the number of failed test parts. -int TestResult::total_part_count() const { - return test_part_results_.size(); -} - -} // namespace internal - -// class Test - -// Creates a Test object. - -// The c'tor saves the values of all Google Test flags. -Test::Test() - : gtest_flag_saver_(new internal::GTestFlagSaver) { -} - -// The d'tor restores the values of all Google Test flags. -Test::~Test() { - delete gtest_flag_saver_; -} - -// Sets up the test fixture. -// -// A sub-class may override this. -void Test::SetUp() { -} - -// Tears down the test fixture. -// -// A sub-class may override this. -void Test::TearDown() { -} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const char* key, const char* value) { - UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); -} - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const char* key, int value) { - Message value_message; - value_message << value; - RecordProperty(key, value_message.GetString().c_str()); -} - -#ifdef GTEST_OS_WINDOWS -// We are on Windows. - -// Adds an "exception thrown" fatal failure to the current test. -static void AddExceptionThrownFailure(DWORD exception_code, - const char* location) { - Message message; - message << "Exception thrown with code 0x" << std::setbase(16) << - exception_code << std::setbase(10) << " in " << location << "."; - - UnitTest* const unit_test = UnitTest::GetInstance(); - unit_test->AddTestPartResult( - TPRT_FATAL_FAILURE, - static_cast<const char *>(NULL), - // We have no info about the source file where the exception - // occurred. - -1, // We have no info on which line caused the exception. - message.GetString(), - internal::String("")); -} - -#endif // GTEST_OS_WINDOWS - -// Google Test requires all tests in the same test case to use the same test -// fixture class. This function checks if the current test has the -// same fixture class as the first test in the current test case. If -// yes, it returns true; otherwise it generates a Google Test failure and -// returns false. -bool Test::HasSameFixtureClass() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - const TestCase* const test_case = impl->current_test_case(); - - // Info about the first test in the current test case. - const internal::TestInfoImpl* const first_test_info = - test_case->test_info_list().Head()->element()->impl(); - const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); - const char* const first_test_name = first_test_info->name(); - - // Info about the current test. - const internal::TestInfoImpl* const this_test_info = - impl->current_test_info()->impl(); - const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); - const char* const this_test_name = this_test_info->name(); - - if (this_fixture_id != first_fixture_id) { - // Is the first test defined using TEST? - const bool first_is_TEST = first_fixture_id == internal::GetTypeId<Test>(); - // Is this test defined using TEST? - const bool this_is_TEST = this_fixture_id == internal::GetTypeId<Test>(); - - if (first_is_TEST || this_is_TEST) { - // The user mixed TEST and TEST_F in this test case - we'll tell - // him/her how to fix it. - - // Gets the name of the TEST and the name of the TEST_F. Note - // that first_is_TEST and this_is_TEST cannot both be true, as - // the fixture IDs are different for the two tests. - const char* const TEST_name = - first_is_TEST ? first_test_name : this_test_name; - const char* const TEST_F_name = - first_is_TEST ? this_test_name : first_test_name; - - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class, so mixing TEST_F and TEST in the same test case is\n" - << "illegal. In test case " << this_test_info->test_case_name() - << ",\n" - << "test " << TEST_F_name << " is defined using TEST_F but\n" - << "test " << TEST_name << " is defined using TEST. You probably\n" - << "want to change the TEST to TEST_F or move it to another test\n" - << "case."; - } else { - // The user defined two fixture classes with the same name in - // two namespaces - we'll tell him/her how to fix it. - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class. However, in test case " - << this_test_info->test_case_name() << ",\n" - << "you defined test " << first_test_name - << " and test " << this_test_name << "\n" - << "using two different test fixture classes. This can happen if\n" - << "the two classes are from different namespaces or translation\n" - << "units and have the same name. You should probably rename one\n" - << "of the classes to put the tests into different test cases."; - } - return false; - } - - return true; -} - -// Runs the test and updates the test result. -void Test::Run() { - if (!HasSameFixtureClass()) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); -#ifdef GTEST_OS_WINDOWS - // We are on Windows. - impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - SetUp(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); - } - - // We will run the test only if SetUp() had no fatal failure. - if (!HasFatalFailure()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - TestBody(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "the test body"); - } - } - - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - TearDown(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); - } - -#else // We are on Linux or Mac - exceptions are disabled. - impl->os_stack_trace_getter()->UponLeavingGTest(); - SetUp(); - - // We will run the test only if SetUp() was successful. - if (!HasFatalFailure()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - TestBody(); - } - - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - TearDown(); -#endif // GTEST_OS_WINDOWS -} - - -// Returns true iff the current test has a fatal failure. -bool Test::HasFatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); -} - -// class TestInfo - -// Constructs a TestInfo object. -TestInfo::TestInfo(const char* test_case_name, - const char* name, - internal::TypeId fixture_class_id, - TestMaker maker) { - impl_ = new internal::TestInfoImpl(this, test_case_name, name, - fixture_class_id, maker); -} - -// Destructs a TestInfo object. -TestInfo::~TestInfo() { - delete impl_; -} - -// Creates a TestInfo object and registers it with the UnitTest -// singleton; returns the created object. -// -// Arguments: -// -// test_case_name: name of the test case -// name: name of the test -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -// maker: pointer to the function that creates a test object -TestInfo* TestInfo::MakeAndRegisterInstance( - const char* test_case_name, - const char* name, - internal::TypeId fixture_class_id, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - TestMaker maker) { - TestInfo* const test_info = - new TestInfo(test_case_name, name, fixture_class_id, maker); - internal::GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); - return test_info; -} - -// Returns the test case name. -const char* TestInfo::test_case_name() const { - return impl_->test_case_name(); -} - -// Returns the test name. -const char* TestInfo::name() const { - return impl_->name(); -} - -// Returns true if this test should run. -bool TestInfo::should_run() const { return impl_->should_run(); } - -// Returns the result of the test. -const internal::TestResult* TestInfo::result() const { return impl_->result(); } - -// Increments the number of death tests encountered in this test so -// far. -int TestInfo::increment_death_test_count() { - return impl_->result()->increment_death_test_count(); -} - -namespace { - -// A predicate that checks the test name of a TestInfo against a known -// value. -// -// This is used for implementation of the TestCase class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestNameIs is copyable. -class TestNameIs { - public: - // Constructor. - // - // TestNameIs has NO default constructor. - explicit TestNameIs(const char* name) - : name_(name) {} - - // Returns true iff the test name of test_info matches name_. - bool operator()(const TestInfo * test_info) const { - return test_info && internal::String(test_info->name()).Compare(name_) == 0; - } - - private: - internal::String name_; -}; - -} // namespace - -// Finds and returns a TestInfo with the given name. If one doesn't -// exist, returns NULL. -TestInfo * TestCase::GetTestInfo(const char* test_name) { - // Can we find a TestInfo with the given name? - internal::ListNode<TestInfo *> * const node = test_info_list_->FindIf( - TestNameIs(test_name)); - - // Returns the TestInfo found. - return node ? node->element() : NULL; -} - -namespace internal { - -// Creates the test object, runs it, records its result, and then -// deletes it. -void TestInfoImpl::Run() { - if (!should_run_) return; - - // Tells UnitTest where to store test result. - UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(parent_); - - // Notifies the unit test event listener that a test is about to - // start. - UnitTestEventListenerInterface* const result_printer = - impl->result_printer(); - result_printer->OnTestStart(parent_); - - const TimeInMillis start = GetTimeInMillis(); - - impl->os_stack_trace_getter()->UponLeavingGTest(); -#ifdef GTEST_OS_WINDOWS - // We are on Windows. - Test* test = NULL; - - __try { - // Creates the test object. - test = (*maker_)(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), - "the test fixture's constructor"); - return; - } -#else // We are on Linux or Mac OS - exceptions are disabled. - - // TODO(wan): If test->Run() throws, test won't be deleted. This is - // not a problem now as we don't use exceptions. If we were to - // enable exceptions, we should revise the following to be - // exception-safe. - - // Creates the test object. - Test* test = (*maker_)(); -#endif // GTEST_OS_WINDOWS - - // Runs the test only if the constructor of the test fixture didn't - // generate a fatal failure. - if (!Test::HasFatalFailure()) { - test->Run(); - } - - // Deletes the test object. - impl->os_stack_trace_getter()->UponLeavingGTest(); - delete test; - test = NULL; - - result_.set_elapsed_time(GetTimeInMillis() - start); - - // Notifies the unit test event listener that a test has just finished. - result_printer->OnTestEnd(parent_); - - // Tells UnitTest to stop associating assertion results to this - // test. - impl->set_current_test_info(NULL); -} - -} // namespace internal - -// class TestCase - -// Gets the number of successful tests in this test case. -int TestCase::successful_test_count() const { - return test_info_list_->CountIf(TestPassed); -} - -// Gets the number of failed tests in this test case. -int TestCase::failed_test_count() const { - return test_info_list_->CountIf(TestFailed); -} - -int TestCase::disabled_test_count() const { - return test_info_list_->CountIf(TestDisabled); -} - -// Get the number of tests in this test case that should run. -int TestCase::test_to_run_count() const { - return test_info_list_->CountIf(ShouldRunTest); -} - -// Gets the number of all tests. -int TestCase::total_test_count() const { - return test_info_list_->size(); -} - -// Creates a TestCase with the given name. -// -// Arguments: -// -// name: name of the test case -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -TestCase::TestCase(const char* name, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) - : name_(name), - set_up_tc_(set_up_tc), - tear_down_tc_(tear_down_tc), - should_run_(false), - elapsed_time_(0) { - test_info_list_ = new internal::List<TestInfo *>; -} - -// Destructor of TestCase. -TestCase::~TestCase() { - // Deletes every Test in the collection. - test_info_list_->ForEach(internal::Delete<TestInfo>); - - // Then deletes the Test collection. - delete test_info_list_; - test_info_list_ = NULL; -} - -// Adds a test to this test case. Will delete the test upon -// destruction of the TestCase object. -void TestCase::AddTestInfo(TestInfo * test_info) { - test_info_list_->PushBack(test_info); -} - -// Runs every test in this TestCase. -void TestCase::Run() { - if (!should_run_) return; - - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_case(this); - - UnitTestEventListenerInterface * const result_printer = - impl->result_printer(); - - result_printer->OnTestCaseStart(this); - impl->os_stack_trace_getter()->UponLeavingGTest(); - set_up_tc_(); - - const internal::TimeInMillis start = internal::GetTimeInMillis(); - test_info_list_->ForEach(internal::TestInfoImpl::RunTest); - elapsed_time_ = internal::GetTimeInMillis() - start; - - impl->os_stack_trace_getter()->UponLeavingGTest(); - tear_down_tc_(); - result_printer->OnTestCaseEnd(this); - impl->set_current_test_case(NULL); -} - -// Clears the results of all tests in this test case. -void TestCase::ClearResult() { - test_info_list_->ForEach(internal::TestInfoImpl::ClearTestResult); -} - - -// class UnitTestEventListenerInterface - -// The virtual d'tor. -UnitTestEventListenerInterface::~UnitTestEventListenerInterface() { -} - -// A result printer that never prints anything. Used in the child process -// of an exec-style death test to avoid needless output clutter. -class NullUnitTestResultPrinter : public UnitTestEventListenerInterface {}; - -// Formats a countable noun. Depending on its quantity, either the -// singular form or the plural form is used. e.g. -// -// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". -// FormatCountableNoun(5, "book", "books") returns "5 books". -static internal::String FormatCountableNoun(int count, - const char * singular_form, - const char * plural_form) { - return internal::String::Format("%d %s", count, - count == 1 ? singular_form : plural_form); -} - -// Formats the count of tests. -static internal::String FormatTestCount(int test_count) { - return FormatCountableNoun(test_count, "test", "tests"); -} - -// Formats the count of test cases. -static internal::String FormatTestCaseCount(int test_case_count) { - return FormatCountableNoun(test_case_count, "test case", "test cases"); -} - -// Converts a TestPartResultType enum to human-friendly string -// representation. Both TPRT_NONFATAL_FAILURE and TPRT_FATAL_FAILURE -// are translated to "Failure", as the user usually doesn't care about -// the difference between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResultType type) { - switch (type) { - case TPRT_SUCCESS: - return "Success"; - - case TPRT_NONFATAL_FAILURE: - case TPRT_FATAL_FAILURE: - return "Failure"; - } - - return "Unknown result type"; -} - -// Prints a TestPartResult. -static void PrintTestPartResult( - const TestPartResult & test_part_result) { - const char * const file_name = test_part_result.file_name(); - - printf("%s", file_name == NULL ? "unknown file" : file_name); - if (test_part_result.line_number() >= 0) { - printf(":%d", test_part_result.line_number()); - } - printf(": %s\n", TestPartResultTypeToString(test_part_result.type())); - printf("%s\n", test_part_result.message()); - fflush(stdout); -} - -// class PrettyUnitTestResultPrinter - -namespace internal { - -enum GTestColor { - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW -}; - -#ifdef _WIN32 - -// Returns the character attribute for the given color. -WORD GetColorAttribute(GTestColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - } - return 0; -} - -#else - -// Returns the ANSI color code for the given color. -const char* GetAnsiColorCode(GTestColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - }; - return NULL; -} - -#endif // _WIN32 - -// Returns true iff Google Test should use colors in the output. -bool ShouldUseColor(bool stdout_is_tty) { - const char* const gtest_color = GTEST_FLAG(color).c_str(); - - if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { -#ifdef _WIN32 - // On Windows the TERM variable is usually not set, but the - // console there does support colors. - return stdout_is_tty; -#else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = GetEnv("TERM"); - const bool term_supports_color = - String::CStringEquals(term, "xterm") || - String::CStringEquals(term, "xterm-color") || - String::CStringEquals(term, "cygwin"); - return stdout_is_tty && term_supports_color; -#endif // _WIN32 - } - - return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || - String::CaseInsensitiveCStringEquals(gtest_color, "true") || - String::CaseInsensitiveCStringEquals(gtest_color, "t") || - String::CStringEquals(gtest_color, "1"); - // We take "yes", "true", "t", and "1" as meaning "yes". If the - // value is neither one of these nor "auto", we treat it as "no" to - // be conservative. -} - -// Helpers for printing colored strings to stdout. Note that on Windows, we -// cannot simply emit special characters and have the terminal change colors. -// This routine must actually emit the characters rather than return a string -// that would be colored when printed, as can be done on Linux. -void ColoredPrintf(GTestColor color, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - static const bool use_color = ShouldUseColor(isatty(fileno(stdout)) != 0); - // The '!= 0' comparison is necessary to satisfy MSVC 7.1. - - if (!use_color) { - vprintf(fmt, args); - va_end(args); - return; - } - -#ifdef _WIN32 - const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; - - SetConsoleTextAttribute(stdout_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - vprintf(fmt, args); - - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); -#else - printf("\033[0;3%sm", GetAnsiColorCode(color)); - vprintf(fmt, args); - printf("\033[m"); // Resets the terminal to default. -#endif // _WIN32 - va_end(args); -} - -} // namespace internal - -using internal::ColoredPrintf; -using internal::COLOR_RED; -using internal::COLOR_GREEN; -using internal::COLOR_YELLOW; - -// This class implements the UnitTestEventListenerInterface interface. -// -// Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public UnitTestEventListenerInterface { - public: - PrettyUnitTestResultPrinter() {} - static void PrintTestName(const char * test_case, const char * test) { - printf("%s.%s", test_case, test); - } - - // The following methods override what's in the - // UnitTestEventListenerInterface class. - virtual void OnUnitTestStart(const UnitTest * unit_test); - virtual void OnGlobalSetUpStart(const UnitTest*); - virtual void OnTestCaseStart(const TestCase * test_case); - virtual void OnTestStart(const TestInfo * test_info); - virtual void OnNewTestPartResult(const TestPartResult * result); - virtual void OnTestEnd(const TestInfo * test_info); - virtual void OnGlobalTearDownStart(const UnitTest*); - virtual void OnUnitTestEnd(const UnitTest * unit_test); - - private: - internal::String test_case_name_; -}; - -// Called before the unit test starts. -void PrettyUnitTestResultPrinter::OnUnitTestStart( - const UnitTest * unit_test) { - const char * const filter = GTEST_FLAG(filter).c_str(); - - // Prints the filter if it's not *. This reminds the user that some - // tests may be skipped. - if (!internal::String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME, filter); - } - - const internal::UnitTestImpl* const impl = unit_test->impl(); - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("Running %s from %s.\n", - FormatTestCount(impl->test_to_run_count()).c_str(), - FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnGlobalSetUpStart(const UnitTest*) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment set-up.\n"); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestCaseStart( - const TestCase * test_case) { - test_case_name_ = test_case->name(); - const internal::String counts = - FormatCountableNoun(test_case->test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s\n", counts.c_str(), test_case_name_.c_str()); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo * test_info) { - ColoredPrintf(COLOR_GREEN, "[ RUN ] "); - PrintTestName(test_case_name_.c_str(), test_info->name()); - printf("\n"); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo * test_info) { - if (test_info->result()->Passed()) { - ColoredPrintf(COLOR_GREEN, "[ OK ] "); - } else { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - } - PrintTestName(test_case_name_.c_str(), test_info->name()); - printf("\n"); - fflush(stdout); -} - -// Called after an assertion failure. -void PrettyUnitTestResultPrinter::OnNewTestPartResult( - const TestPartResult * result) { - // If the test part succeeded, we don't need to do anything. - if (result->type() == TPRT_SUCCESS) - return; - - // Print failure message from the assertion (e.g. expected this and got that). - PrintTestPartResult(*result); - fflush(stdout); -} - -void PrettyUnitTestResultPrinter::OnGlobalTearDownStart(const UnitTest*) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment tear-down\n"); - fflush(stdout); -} - -namespace internal { - -// Internal helper for printing the list of failed tests. -static void PrintFailedTestsPretty(const UnitTestImpl* impl) { - const int failed_test_count = impl->failed_test_count(); - if (failed_test_count == 0) { - return; - } - - for (const internal::ListNode<TestCase*>* node = impl->test_cases()->Head(); - node != NULL; node = node->next()) { - const TestCase* const tc = node->element(); - if (!tc->should_run() || (tc->failed_test_count() == 0)) { - continue; - } - for (const internal::ListNode<TestInfo*>* tinode = - tc->test_info_list().Head(); - tinode != NULL; tinode = tinode->next()) { - const TestInfo* const ti = tinode->element(); - if (!tc->ShouldRunTest(ti) || tc->TestPassed(ti)) { - continue; - } - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s.%s\n", ti->test_case_name(), ti->name()); - } - } -} - -} // namespace internal - -void PrettyUnitTestResultPrinter::OnUnitTestEnd( - const UnitTest * unit_test) { - const internal::UnitTestImpl* const impl = unit_test->impl(); - - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("%s from %s ran.\n", - FormatTestCount(impl->test_to_run_count()).c_str(), - FormatTestCaseCount(impl->test_case_to_run_count()).c_str()); - ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(impl->successful_test_count()).c_str()); - - int num_failures = impl->failed_test_count(); - if (!impl->Passed()) { - const int failed_test_count = impl->failed_test_count(); - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); - internal::PrintFailedTestsPretty(impl); - printf("\n%2d FAILED %s\n", num_failures, - num_failures == 1 ? "TEST" : "TESTS"); - } - - int num_disabled = impl->disabled_test_count(); - if (num_disabled) { - if (!num_failures) { - printf("\n"); // Add a spacer if no FAILURE banner is displayed. - } - ColoredPrintf(COLOR_YELLOW, - " YOU HAVE %d DISABLED %s\n\n", - num_disabled, - num_disabled == 1 ? "TEST" : "TESTS"); - } - // Ensure that Google Test output is printed before, e.g., heapchecker output. - fflush(stdout); -} - -// End PrettyUnitTestResultPrinter - -// class UnitTestEventsRepeater -// -// This class forwards events to other event listeners. -class UnitTestEventsRepeater : public UnitTestEventListenerInterface { - public: - typedef internal::List<UnitTestEventListenerInterface *> Listeners; - typedef internal::ListNode<UnitTestEventListenerInterface *> ListenersNode; - UnitTestEventsRepeater() {} - virtual ~UnitTestEventsRepeater(); - void AddListener(UnitTestEventListenerInterface *listener); - - virtual void OnUnitTestStart(const UnitTest* unit_test); - virtual void OnUnitTestEnd(const UnitTest* unit_test); - virtual void OnGlobalSetUpStart(const UnitTest* unit_test); - virtual void OnGlobalSetUpEnd(const UnitTest* unit_test); - virtual void OnGlobalTearDownStart(const UnitTest* unit_test); - virtual void OnGlobalTearDownEnd(const UnitTest* unit_test); - virtual void OnTestCaseStart(const TestCase* test_case); - virtual void OnTestCaseEnd(const TestCase* test_case); - virtual void OnTestStart(const TestInfo* test_info); - virtual void OnTestEnd(const TestInfo* test_info); - virtual void OnNewTestPartResult(const TestPartResult* result); - - private: - Listeners listeners_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTestEventsRepeater); -}; - -UnitTestEventsRepeater::~UnitTestEventsRepeater() { - for (ListenersNode* listener = listeners_.Head(); - listener != NULL; - listener = listener->next()) { - delete listener->element(); - } -} - -void UnitTestEventsRepeater::AddListener( - UnitTestEventListenerInterface *listener) { - listeners_.PushBack(listener); -} - -// Since the methods are identical, use a macro to reduce boilerplate. -// This defines a member that repeats the call to all listeners. -#define GTEST_REPEATER_METHOD(Name, Type) \ -void UnitTestEventsRepeater::Name(const Type* parameter) { \ - for (ListenersNode* listener = listeners_.Head(); \ - listener != NULL; \ - listener = listener->next()) { \ - listener->element()->Name(parameter); \ - } \ -} - -GTEST_REPEATER_METHOD(OnUnitTestStart, UnitTest) -GTEST_REPEATER_METHOD(OnUnitTestEnd, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalSetUpStart, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalSetUpEnd, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalTearDownStart, UnitTest) -GTEST_REPEATER_METHOD(OnGlobalTearDownEnd, UnitTest) -GTEST_REPEATER_METHOD(OnTestCaseStart, TestCase) -GTEST_REPEATER_METHOD(OnTestCaseEnd, TestCase) -GTEST_REPEATER_METHOD(OnTestStart, TestInfo) -GTEST_REPEATER_METHOD(OnTestEnd, TestInfo) -GTEST_REPEATER_METHOD(OnNewTestPartResult, TestPartResult) - -#undef GTEST_REPEATER_METHOD - -// End PrettyUnitTestResultPrinter - -// This class generates an XML output file. -class XmlUnitTestResultPrinter : public UnitTestEventListenerInterface { - public: - explicit XmlUnitTestResultPrinter(const char* output_file); - - virtual void OnUnitTestEnd(const UnitTest* unit_test); - - private: - // Is c a whitespace character that is normalized to a space character - // when it appears in an XML attribute value? - static bool IsNormalizableWhitespace(char c) { - return c == 0x9 || c == 0xA || c == 0xD; - } - - // May c appear in a well-formed XML document? - static bool IsValidXmlCharacter(char c) { - return IsNormalizableWhitespace(c) || c >= 0x20; - } - - // Returns an XML-escaped copy of the input string str. If - // is_attribute is true, the text is meant to appear as an attribute - // value, and normalizable whitespace is preserved by replacing it - // with character references. - static internal::String EscapeXml(const char* str, - bool is_attribute); - - // Convenience wrapper around EscapeXml when str is an attribute value. - static internal::String EscapeXmlAttribute(const char* str) { - return EscapeXml(str, true); - } - - // Convenience wrapper around EscapeXml when str is not an attribute value. - static internal::String EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } - - // Prints an XML representation of a TestInfo object. - static void PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo* test_info); - - // Prints an XML representation of a TestCase object - static void PrintXmlTestCase(FILE* out, const TestCase* test_case); - - // Prints an XML summary of unit_test to output stream out. - static void PrintXmlUnitTest(FILE* out, const UnitTest* unit_test); - - // Produces a string representing the test properties in a result as space - // delimited XML attributes based on the property key="value" pairs. - // When the String is not empty, it includes a space at the beginning, - // to delimit this attribute from prior attributes. - static internal::String TestPropertiesAsXmlAttributes( - const internal::TestResult* result); - - // The output file. - const internal::String output_file_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(XmlUnitTestResultPrinter); -}; - -// Creates a new XmlUnitTestResultPrinter. -XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) - : output_file_(output_file) { - if (output_file_.c_str() == NULL || output_file_.empty()) { - fprintf(stderr, "XML output file may not be null\n"); - fflush(stderr); - exit(EXIT_FAILURE); - } -} - -// Called after the unit test ends. -void XmlUnitTestResultPrinter::OnUnitTestEnd(const UnitTest* unit_test) { - FILE* xmlout = NULL; - internal::FilePath output_file(output_file_); - internal::FilePath output_dir(output_file.RemoveFileName()); - - if (output_dir.CreateDirectoriesRecursively()) { - // MSVC 8 deprecates fopen(), so we want to suppress warning 4996 - // (deprecated function) there. -#ifdef GTEST_OS_WINDOWS - // We are on Windows. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - xmlout = fopen(output_file_.c_str(), "w"); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - xmlout = fopen(output_file_.c_str(), "w"); -#endif // GTEST_OS_WINDOWS - } - if (xmlout == NULL) { - // TODO(wan): report the reason of the failure. - // - // We don't do it for now as: - // - // 1. There is no urgent need for it. - // 2. It's a bit involved to make the errno variable thread-safe on - // all three operating systems (Linux, Windows, and Mac OS). - // 3. To interpret the meaning of errno in a thread-safe way, - // we need the strerror_r() function, which is not available on - // Windows. - fprintf(stderr, - "Unable to open file \"%s\"\n", - output_file_.c_str()); - fflush(stderr); - exit(EXIT_FAILURE); - } - PrintXmlUnitTest(xmlout, unit_test); - fclose(xmlout); -} - -// Returns an XML-escaped copy of the input string str. If is_attribute -// is true, the text is meant to appear as an attribute value, and -// normalizable whitespace is preserved by replacing it with character -// references. -// -// Invalid XML characters in str, if any, are stripped from the output. -// It is expected that most, if not all, of the text processed by this -// module will consist of ordinary English text. -// If this module is ever modified to produce version 1.1 XML output, -// most invalid characters can be retained using character references. -// TODO(wan): It might be nice to have a minimally invasive, human-readable -// escaping scheme for invalid characters, rather than dropping them. -internal::String XmlUnitTestResultPrinter::EscapeXml(const char* str, - bool is_attribute) { - Message m; - - if (str != NULL) { - for (const char* src = str; *src; ++src) { - switch (*src) { - case '<': - m << "<"; - break; - case '>': - m << ">"; - break; - case '&': - m << "&"; - break; - case '\'': - if (is_attribute) - m << "'"; - else - m << '\''; - break; - case '"': - if (is_attribute) - m << """; - else - m << '"'; - break; - default: - if (IsValidXmlCharacter(*src)) { - if (is_attribute && IsNormalizableWhitespace(*src)) - m << internal::String::Format("&#x%02X;", unsigned(*src)); - else - m << *src; - } - break; - } - } - } - - return m.GetString(); -} - - -// The following routines generate an XML representation of a UnitTest -// object. -// -// This is how Google Test concepts map to the DTD: -// -// <testsuite name="AllTests"> <-- corresponds to a UnitTest object -// <testsuite name="testcase-name"> <-- corresponds to a TestCase object -// <testcase name="test-name"> <-- corresponds to a TestInfo object -// <failure message="..." /> -// <failure message="..." /> <-- individual assertion failures -// <failure message="..." /> -// </testcase> -// </testsuite> -// </testsuite> - -// Prints an XML representation of a TestInfo object. -// TODO(wan): There is also value in printing properties with the plain printer. -void XmlUnitTestResultPrinter::PrintXmlTestInfo(FILE* out, - const char* test_case_name, - const TestInfo* test_info) { - const internal::TestResult * const result = test_info->result(); - const internal::List<TestPartResult> &results = result->test_part_results(); - fprintf(out, - " <testcase name=\"%s\" status=\"%s\" time=\"%s\" " - "classname=\"%s\"%s", - EscapeXmlAttribute(test_info->name()).c_str(), - test_info->should_run() ? "run" : "notrun", - internal::StreamableToString(result->elapsed_time()).c_str(), - EscapeXmlAttribute(test_case_name).c_str(), - TestPropertiesAsXmlAttributes(result).c_str()); - - int failures = 0; - for (const internal::ListNode<TestPartResult>* part_node = results.Head(); - part_node != NULL; - part_node = part_node->next()) { - const TestPartResult& part = part_node->element(); - if (part.failed()) { - const internal::String message = - internal::String::Format("%s:%d\n%s", part.file_name(), - part.line_number(), part.message()); - if (++failures == 1) - fprintf(out, ">\n"); - fprintf(out, - " <failure message=\"%s\" type=\"\"/>\n", - EscapeXmlAttribute(message.c_str()).c_str()); - } - } - - if (failures == 0) - fprintf(out, " />\n"); - else - fprintf(out, " </testcase>\n"); -} - -// Prints an XML representation of a TestCase object -void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, - const TestCase* test_case) { - fprintf(out, - " <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" " - "disabled=\"%d\" ", - EscapeXmlAttribute(test_case->name()).c_str(), - test_case->total_test_count(), - test_case->failed_test_count(), - test_case->disabled_test_count()); - fprintf(out, - "errors=\"0\" time=\"%s\">\n", - internal::StreamableToString(test_case->elapsed_time()).c_str()); - for (const internal::ListNode<TestInfo*>* info_node = - test_case->test_info_list().Head(); - info_node != NULL; - info_node = info_node->next()) { - PrintXmlTestInfo(out, test_case->name(), info_node->element()); - } - fprintf(out, " </testsuite>\n"); -} - -// Prints an XML summary of unit_test to output stream out. -void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, - const UnitTest* unit_test) { - const internal::UnitTestImpl* const impl = unit_test->impl(); - fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - fprintf(out, - "<testsuite tests=\"%d\" failures=\"%d\" disabled=\"%d\" " - "errors=\"0\" time=\"%s\" ", - impl->total_test_count(), - impl->failed_test_count(), - impl->disabled_test_count(), - internal::StreamableToString(impl->elapsed_time()).c_str()); - fprintf(out, "name=\"AllTests\">\n"); - for (const internal::ListNode<TestCase*>* case_node = - impl->test_cases()->Head(); - case_node != NULL; - case_node = case_node->next()) { - PrintXmlTestCase(out, case_node->element()); - } - fprintf(out, "</testsuite>\n"); -} - -// Produces a string representing the test properties in a result as space -// delimited XML attributes based on the property key="value" pairs. -internal::String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( - const internal::TestResult* result) { - using internal::TestProperty; - Message attributes; - const internal::List<TestProperty>& properties = result->test_properties(); - for (const internal::ListNode<TestProperty>* property_node = - properties.Head(); - property_node != NULL; - property_node = property_node->next()) { - const TestProperty& property = property_node->element(); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; - } - return attributes.GetString(); -} - -// End XmlUnitTestResultPrinter - -namespace internal { - -// Class ScopedTrace - -// Pushes the given source file location and message onto a per-thread -// trace stack maintained by Google Test. -// L < UnitTest::mutex_ -ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { - TraceInfo trace; - trace.file = file; - trace.line = line; - trace.message = message.GetString(); - - UnitTest::GetInstance()->PushGTestTrace(trace); -} - -// Pops the info pushed by the c'tor. -// L < UnitTest::mutex_ -ScopedTrace::~ScopedTrace() { - UnitTest::GetInstance()->PopGTestTrace(); -} - - -// class OsStackTraceGetter - -// Returns the current OS stack trace as a String. Parameters: -// -// max_depth - the maximum number of stack frames to be included -// in the trace. -// skip_count - the number of top frames to be skipped; doesn't count -// against max_depth. -// -// L < mutex_ -// We use "L < mutex_" to denote that the function may acquire mutex_. -String OsStackTraceGetter::CurrentStackTrace(int, int) { - return String(""); -} - -// L < mutex_ -void OsStackTraceGetter::UponLeavingGTest() { -} - -const char* const -OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME " internal frames ..."; - -} // namespace internal - -// class UnitTest - -// Gets the singleton UnitTest object. The first time this method is -// called, a UnitTest object is constructed and returned. Consecutive -// calls will return the same object. -// -// We don't protect this under mutex_ as a user is not supposed to -// call this before main() starts, from which point on the return -// value will never change. -UnitTest * UnitTest::GetInstance() { - // When compiled with MSVC 7.1 in optimized mode, destroying the - // UnitTest object upon exiting the program messes up the exit code, - // causing successful tests to appear failed. We have to use a - // different implementation in this case to bypass the compiler bug. - // This implementation makes the compiler happy, at the cost of - // leaking the UnitTest object. -#if _MSC_VER == 1310 && !defined(_DEBUG) // MSVC 7.1 and optimized build. - static UnitTest* const instance = new UnitTest; - return instance; -#else - static UnitTest instance; - return &instance; -#endif // _MSC_VER==1310 && !defined(_DEBUG) -} - -// Registers and returns a global test environment. When a test -// program is run, all global test environments will be set-up in the -// order they were registered. After all tests in the program have -// finished, all global test environments will be torn-down in the -// *reverse* order they were registered. -// -// The UnitTest object takes ownership of the given environment. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -Environment* UnitTest::AddEnvironment(Environment* env) { - if (env == NULL) { - return NULL; - } - - impl_->environments()->PushBack(env); - impl_->environments_in_reverse_order()->PushFront(env); - return env; -} - -// Adds a TestPartResult to the current TestResult object. All Google Test -// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call -// this to report their results. The user code should use the -// assertion macros instead of calling this directly. -// L < mutex_ -void UnitTest::AddTestPartResult(TestPartResultType result_type, - const char* file_name, - int line_number, - const internal::String& message, - const internal::String& os_stack_trace) { - Message msg; - msg << message; - - internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack()->size() > 0) { - msg << "\n" << GTEST_NAME << " trace:"; - - for (internal::ListNode<internal::TraceInfo>* node = - impl_->gtest_trace_stack()->Head(); - node != NULL; - node = node->next()) { - const internal::TraceInfo& trace = node->element(); - msg << "\n" << trace.file << ":" << trace.line << ": " << trace.message; - } - } - - if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { - msg << "\nStack trace:\n" << os_stack_trace; - } - - const TestPartResult result = - TestPartResult(result_type, file_name, line_number, - msg.GetString().c_str()); - impl_->test_part_result_reporter()->ReportTestPartResult(result); - - // If this is a failure and the user wants the debugger to break on - // failures ... - if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) { - // ... then we generate a seg fault. - *static_cast<int*>(NULL) = 1; - } -} - -// Creates and adds a property to the current TestResult. If a property matching -// the supplied value already exists, updates its value instead. -void UnitTest::RecordPropertyForCurrentTest(const char* key, - const char* value) { - const internal::TestProperty test_property(key, value); - impl_->current_test_result()->RecordProperty(test_property); -} - -// Runs all tests in this UnitTest object and prints the result. -// Returns 0 if successful, or 1 otherwise. -// -// We don't protect this under mutex_, as we only support calling it -// from the main thread. -int UnitTest::Run() { -#ifdef GTEST_OS_WINDOWS - -#if !defined(_WIN32_WCE) - // SetErrorMode doesn't exist on CE. - if (GTEST_FLAG(catch_exceptions)) { - // The user wants Google Test to catch exceptions thrown by the tests. - - // This lets fatal errors be handled by us, instead of causing pop-ups. - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); - } -#endif // _WIN32_WCE - - __try { - return impl_->RunAllTests(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); - fflush(stdout); - return 1; - } - -#else - // We are on Linux or Mac OS. There is no exception of any kind. - - return impl_->RunAllTests(); -#endif // GTEST_OS_WINDOWS -} - -// Returns the TestCase object for the test that's currently running, -// or NULL if no test is running. -// L < mutex_ -const TestCase* UnitTest::current_test_case() const { - internal::MutexLock lock(&mutex_); - return impl_->current_test_case(); -} - -// Returns the TestInfo object for the test that's currently running, -// or NULL if no test is running. -// L < mutex_ -const TestInfo* UnitTest::current_test_info() const { - internal::MutexLock lock(&mutex_); - return impl_->current_test_info(); -} - -// Creates an empty UnitTest. -UnitTest::UnitTest() { - impl_ = new internal::UnitTestImpl(this); -} - -// Destructor of UnitTest. -UnitTest::~UnitTest() { - delete impl_; -} - -// Pushes a trace defined by SCOPED_TRACE() on to the per-thread -// Google Test trace stack. -// L < mutex_ -void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PushFront(trace); -} - -// Pops a trace from the per-thread Google Test trace stack. -// L < mutex_ -void UnitTest::PopGTestTrace() { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack()->PopFront(NULL); -} - -namespace internal { - -UnitTestImpl::UnitTestImpl(UnitTest* parent) - : parent_(parent), - test_cases_(), - last_death_test_case_(NULL), - current_test_case_(NULL), - current_test_info_(NULL), - ad_hoc_test_result_(), - result_printer_(NULL), - os_stack_trace_getter_(NULL), -#ifdef GTEST_HAS_DEATH_TEST - elapsed_time_(0), - internal_run_death_test_flag_(NULL), - death_test_factory_(new DefaultDeathTestFactory) { -#else - elapsed_time_(0) { -#endif // GTEST_HAS_DEATH_TEST - // We do the assignment here instead of in the initializer list, as - // doing that latter causes MSVC to issue a warning about using - // 'this' in initializers. - test_part_result_reporter_ = this; -} - -UnitTestImpl::~UnitTestImpl() { - // Deletes every TestCase. - test_cases_.ForEach(internal::Delete<TestCase>); - - // Deletes every Environment. - environments_.ForEach(internal::Delete<Environment>); - - // Deletes the current test result printer. - delete result_printer_; - - delete os_stack_trace_getter_; -} - -// A predicate that checks the name of a TestCase against a known -// value. -// -// This is used for implementation of the UnitTest class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestCaseNameIs is copyable. -class TestCaseNameIs { - public: - // Constructor. - explicit TestCaseNameIs(const String& name) - : name_(name) {} - - // Returns true iff the name of test_case matches name_. - bool operator()(const TestCase* test_case) const { - return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; - } - - private: - String name_; -}; - -// Finds and returns a TestCase with the given name. If one doesn't -// exist, creates one and returns it. -// -// Arguments: -// -// test_case_name: name of the test case -// set_up_tc: pointer to the function that sets up the test case -// tear_down_tc: pointer to the function that tears down the test case -TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) { - // Can we find a TestCase with the given name? - internal::ListNode<TestCase*>* node = test_cases_.FindIf( - TestCaseNameIs(test_case_name)); - - if (node == NULL) { - // No. Let's create one. - TestCase* const test_case = - new TestCase(test_case_name, set_up_tc, tear_down_tc); - - // Is this a death test case? - if (String(test_case_name).EndsWith("DeathTest")) { - // Yes. Inserts the test case after the last death test case - // defined so far. - node = test_cases_.InsertAfter(last_death_test_case_, test_case); - last_death_test_case_ = node; - } else { - // No. Appends to the end of the list. - test_cases_.PushBack(test_case); - node = test_cases_.Last(); - } - } - - // Returns the TestCase found. - return node->element(); -} - -// Helpers for setting up / tearing down the given environment. They -// are for use in the List::ForEach() method. -static void SetUpEnvironment(Environment* env) { env->SetUp(); } -static void TearDownEnvironment(Environment* env) { env->TearDown(); } - -// Runs all tests in this UnitTest object, prints the result, and -// returns 0 if all tests are successful, or 1 otherwise. If any -// exception is thrown during a test on Windows, this test is -// considered to be failed, but the rest of the tests will still be -// run. (We disable exceptions on Linux and Mac OS X, so the issue -// doesn't apply there.) -int UnitTestImpl::RunAllTests() { - // True iff Google Test is initialized before RUN_ALL_TESTS() is called. - const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); - - // Lists all the tests and exits if the --gtest_list_tests - // flag was specified. - if (GTEST_FLAG(list_tests)) { - ListAllTests(); - return 0; - } - - // True iff we are in a subprocess for running a thread-safe-style - // death test. - bool in_subprocess_for_death_test = false; - -#ifdef GTEST_HAS_DEATH_TEST - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); - in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); -#endif // GTEST_HAS_DEATH_TEST - - UnitTestEventListenerInterface * const printer = result_printer(); - - // Compares the full test names with the filter to decide which - // tests to run. - const bool has_tests_to_run = FilterTests() > 0; - // True iff at least one test has failed. - bool failed = false; - - // How many times to repeat the tests? We don't want to repeat them - // when we are inside the subprocess of a death test. - const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); - // Repeats forever if the repeat count is negative. - const bool forever = repeat < 0; - for (int i = 0; forever || i != repeat; i++) { - if (repeat != 1) { - printf("\nRepeating all tests (iteration %d) . . .\n\n", i + 1); - } - - // Tells the unit test event listener that the tests are about to - // start. - printer->OnUnitTestStart(parent_); - - const TimeInMillis start = GetTimeInMillis(); - - // Runs each test case if there is at least one test to run. - if (has_tests_to_run) { - // Sets up all environments beforehand. - printer->OnGlobalSetUpStart(parent_); - environments_.ForEach(SetUpEnvironment); - printer->OnGlobalSetUpEnd(parent_); - - // Runs the tests only if there was no fatal failure during global - // set-up. - if (!Test::HasFatalFailure()) { - test_cases_.ForEach(TestCase::RunTestCase); - } - - // Tears down all environments in reverse order afterwards. - printer->OnGlobalTearDownStart(parent_); - environments_in_reverse_order_.ForEach(TearDownEnvironment); - printer->OnGlobalTearDownEnd(parent_); - } - - elapsed_time_ = GetTimeInMillis() - start; - - // Tells the unit test event listener that the tests have just - // finished. - printer->OnUnitTestEnd(parent_); - - // Gets the result and clears it. - if (!Passed()) { - failed = true; - } - ClearResult(); - } - - if (!gtest_is_initialized_before_run_all_tests) { - ColoredPrintf( - COLOR_RED, "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" - "This test program did NOT call %s() before calling RUN_ALL_TESTS(). " - "This is INVALID. Soon " GTEST_NAME - " will start to enforce the valid usage. " - "Please fix it ASAP, or IT WILL START TO FAIL.\n", - "testing::ParseGTestFlags" - ); // NOLINT - } - - // Returns 0 if all tests passed, or 1 other wise. - return failed ? 1 : 0; -} - -// Compares the name of each test with the user-specified filter to -// decide whether the test should be run, then records the result in -// each TestCase and TestInfo object. -// Returns the number of tests that should run. -int UnitTestImpl::FilterTests() { - int num_runnable_tests = 0; - for (const internal::ListNode<TestCase *> *test_case_node = - test_cases_.Head(); - test_case_node != NULL; - test_case_node = test_case_node->next()) { - TestCase * const test_case = test_case_node->element(); - const String &test_case_name = test_case->name(); - test_case->set_should_run(false); - - for (const internal::ListNode<TestInfo *> *test_info_node = - test_case->test_info_list().Head(); - test_info_node != NULL; - test_info_node = test_info_node->next()) { - TestInfo * const test_info = test_info_node->element(); - const String test_name(test_info->name()); - // A test is disabled if test case name or test name matches - // kDisableTestPattern. - const bool is_disabled = - internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern, - test_case_name.c_str()) || - internal::UnitTestOptions::PatternMatchesString(kDisableTestPattern, - test_name.c_str()); - test_info->impl()->set_is_disabled(is_disabled); - - const bool should_run = !is_disabled && - internal::UnitTestOptions::FilterMatchesTest(test_case_name, - test_name); - test_info->impl()->set_should_run(should_run); - test_case->set_should_run(test_case->should_run() || should_run); - if (should_run) { - num_runnable_tests++; - } - } - } - return num_runnable_tests; -} - -// Lists all tests by name. -void UnitTestImpl::ListAllTests() { - for (const internal::ListNode<TestCase*>* test_case_node = test_cases_.Head(); - test_case_node != NULL; - test_case_node = test_case_node->next()) { - const TestCase* const test_case = test_case_node->element(); - - // Prints the test case name following by an indented list of test nodes. - printf("%s.\n", test_case->name()); - - for (const internal::ListNode<TestInfo*>* test_info_node = - test_case->test_info_list().Head(); - test_info_node != NULL; - test_info_node = test_info_node->next()) { - const TestInfo* const test_info = test_info_node->element(); - - printf(" %s\n", test_info->name()); - } - } - fflush(stdout); -} - -// Sets the unit test result printer. -// -// Does nothing if the input and the current printer object are the -// same; otherwise, deletes the old printer object and makes the -// input the current printer. -void UnitTestImpl::set_result_printer( - UnitTestEventListenerInterface* result_printer) { - if (result_printer_ != result_printer) { - delete result_printer_; - result_printer_ = result_printer; - } -} - -// Returns the current unit test result printer if it is not NULL; -// otherwise, creates an appropriate result printer, makes it the -// current printer, and returns it. -UnitTestEventListenerInterface* UnitTestImpl::result_printer() { - if (result_printer_ != NULL) { - return result_printer_; - } - -#ifdef GTEST_HAS_DEATH_TEST - if (internal_run_death_test_flag_.get() != NULL) { - result_printer_ = new NullUnitTestResultPrinter; - return result_printer_; - } -#endif // GTEST_HAS_DEATH_TEST - - UnitTestEventsRepeater *repeater = new UnitTestEventsRepeater; - const String& output_format = internal::UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - repeater->AddListener(new XmlUnitTestResultPrinter( - internal::UnitTestOptions::GetOutputFile().c_str())); - } else if (output_format != "") { - printf("WARNING: unrecognized output format \"%s\" ignored.\n", - output_format.c_str()); - fflush(stdout); - } - repeater->AddListener(new PrettyUnitTestResultPrinter); - result_printer_ = repeater; - return result_printer_; -} - -// Sets the OS stack trace getter. -// -// Does nothing if the input and the current OS stack trace getter are -// the same; otherwise, deletes the old getter and makes the input the -// current getter. -void UnitTestImpl::set_os_stack_trace_getter( - OsStackTraceGetterInterface* getter) { - if (os_stack_trace_getter_ != getter) { - delete os_stack_trace_getter_; - os_stack_trace_getter_ = getter; - } -} - -// Returns the current OS stack trace getter if it is not NULL; -// otherwise, creates an OsStackTraceGetter, makes it the current -// getter, and returns it. -OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { - if (os_stack_trace_getter_ == NULL) { - os_stack_trace_getter_ = new OsStackTraceGetter; - } - - return os_stack_trace_getter_; -} - -// Returns the TestResult for the test that's currently running, or -// the TestResult for the ad hoc test if no test is running. -internal::TestResult* UnitTestImpl::current_test_result() { - return current_test_info_ ? - current_test_info_->impl()->result() : &ad_hoc_test_result_; -} - -// TestInfoImpl constructor. -TestInfoImpl::TestInfoImpl(TestInfo* parent, - const char* test_case_name, - const char* name, - TypeId fixture_class_id, - TestMaker maker) : - parent_(parent), - test_case_name_(String(test_case_name)), - name_(String(name)), - fixture_class_id_(fixture_class_id), - should_run_(false), - is_disabled_(false), - maker_(maker) { -} - -// TestInfoImpl destructor. -TestInfoImpl::~TestInfoImpl() { -} - -} // namespace internal - -namespace internal { - -// Parses a string as a command line flag. The string should have -// the format "--flag=value". When def_optional is true, the "=value" -// part can be omitted. -// -// Returns the value of the flag, or NULL if the parsing failed. -const char* ParseFlagValue(const char* str, - const char* flag, - bool def_optional) { - // str and flag must not be NULL. - if (str == NULL || flag == NULL) return NULL; - - // The flag must start with "--" followed by GTEST_FLAG_PREFIX. - const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX, flag); - const size_t flag_len = flag_str.GetLength(); - if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; - - // Skips the flag name. - const char* flag_end = str + flag_len; - - // When def_optional is true, it's OK to not have a "=value" part. - if (def_optional && (flag_end[0] == '\0')) { - return flag_end; - } - - // If def_optional is true and there are more characters after the - // flag name, or if def_optional is false, there must be a '=' after - // the flag name. - if (flag_end[0] != '=') return NULL; - - // Returns the string after "=". - return flag_end + 1; -} - -// Parses a string for a bool flag, in the form of either -// "--flag=value" or "--flag". -// -// In the former case, the value is taken as true as long as it does -// not start with '0', 'f', or 'F'. -// -// In the latter case, the value is taken as true. -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseBoolFlag(const char* str, const char* flag, bool* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, true); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Converts the string value to a bool. - *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); - return true; -} - -// Parses a string for an Int32 flag, in the form of -// "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Sets *value to the value of the flag. - return ParseInt32(Message() << "The value of flag --" << flag, - value_str, value); -} - -// Parses a string for a string flag, in the form of -// "--flag=value". -// -// On success, stores the value of the flag in *value, and returns -// true. On failure, returns false without changing *value. -bool ParseStringFlag(const char* str, const char* flag, String* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); - - // Aborts if the parsing failed. - if (value_str == NULL) return false; - - // Sets *value to the value of the flag. - *value = value_str; - return true; -} - -// The internal implementation of ParseGTestFlags(). -// -// The type parameter CharType can be instantiated to either char or -// wchar_t. -template <typename CharType> -void ParseGTestFlagsImpl(int* argc, CharType** argv) { - g_parse_gtest_flags_called = true; - if (*argc <= 0) return; - -#ifdef GTEST_HAS_DEATH_TEST - g_argvs.clear(); - for (int i = 0; i != *argc; i++) { - g_argvs.push_back(StreamableToString(argv[i])); - } -#endif // GTEST_HAS_DEATH_TEST - - for (int i = 1; i != *argc; i++) { - const String arg_string = StreamableToString(argv[i]); - const char* const arg = arg_string.c_str(); - - using internal::ParseBoolFlag; - using internal::ParseInt32Flag; - using internal::ParseStringFlag; - - // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) - ) { - // Yes. Shift the remainder of the argv list left by one. Note - // that argv has (*argc + 1) elements, the last one always being - // NULL. The following loop moves the trailing NULL element as - // well. - for (int j = i; j != *argc; j++) { - argv[j] = argv[j + 1]; - } - - // Decrements the argument count. - (*argc)--; - - // We also need to decrement the iterator as we just removed - // an element. - i--; - } - } -} - -} // namespace internal - -// Parses a command line for the flags that Google Test recognizes. -// Whenever a Google Test flag is seen, it is removed from argv, and *argc -// is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -void ParseGTestFlags(int* argc, char** argv) { - internal::g_executable_path = argv[0]; - internal::ParseGTestFlagsImpl(argc, argv); -} - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -#ifdef GTEST_OS_WINDOWS -void ParseGTestFlags(int* argc, wchar_t** argv) { - // g_executable_path uses normal characters rather than wide chars, so call - // StreamableToString to convert argv[0] to normal characters (utf8 encoding). - internal::g_executable_path = internal::StreamableToString(argv[0]); - internal::ParseGTestFlagsImpl(argc, argv); -} -#endif // GTEST_OS_WINDOWS - -} // namespace testing diff --git a/src/gtest/gtest.h b/src/gtest/gtest.h deleted file mode 100644 index 4e3d7bcb..00000000 --- a/src/gtest/gtest.h +++ /dev/null @@ -1,1243 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines the public API for Google Test. It should be -// included by any test program that uses Google Test. -// -// IMPORTANT NOTE: Due to limitation of the C++ language, we have to -// leave some internal implementation details in this header file. -// They are clearly marked by comments like this: -// -// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -// -// Such code is NOT meant to be used by a user directly, and is subject -// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user -// program! -// -// Acknowledgment: Google Test borrowed the idea of automatic test -// registration from Barthelemy Dagenais' (barthelemy@prologique.com) -// easyUnit framework. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -#define GTEST_INCLUDE_GTEST_GTEST_H_ - -#ifndef GTEST_NOT_MAC_FRAMEWORK_MODE -// Protobuf never uses gTest in "mac framework mode". -#define GTEST_NOT_MAC_FRAMEWORK_MODE -#endif - -// The following platform macros are used throughout Google Test: -// _WIN32_WCE Windows CE (set in project files) -// __SYMBIAN32__ Symbian (set by Symbian tool chain) -// -// Note that even though _MSC_VER and _WIN32_WCE really indicate a compiler -// and a Win32 implementation, respectively, we use them to indicate the -// combination of compiler - Win 32 API - C library, since the code currently -// only supports: -// Windows proper with Visual C++ and MS C library (_MSC_VER && !_WIN32_WCE) and -// Windows Mobile with Visual C++ and no C library (_WIN32_WCE). - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes -// will be in the framework headers folder along with gtest.h. Define -// GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on the -// Mac and are not using it as a framework. More info on frameworks -// available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-death-test.h" // NOLINT -#include "gtest-internal.h" // NOLINT -#include "gtest-message.h" // NOLINT -#include "gtest-string.h" // NOLINT -#include "gtest_prod.h" // NOLINT -#else -#include <gtest/internal/gtest-internal.h> -#include <gtest/internal/gtest-string.h> -#include <gtest/gtest-death-test.h> -#include <gtest/gtest-message.h> -#include <gtest/gtest_prod.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -// Depending on the platform, different string classes are available. -// On Windows, ::std::string compiles only when exceptions are -// enabled. On Linux, in addition to ::std::string, Google also makes -// use of class ::string, which has the same interface as -// ::std::string, but has a different implementation. -// -// The user can tell us whether ::std::string is available in his -// environment by defining the macro GTEST_HAS_STD_STRING to either 1 -// or 0 on the compiler command line. He can also define -// GTEST_HAS_GLOBAL_STRING to 1 to indicate that ::string is available -// AND is a distinct type to ::std::string, or define it to 0 to -// indicate otherwise. -// -// If the user's ::std::string and ::string are the same class due to -// aliasing, he should define GTEST_HAS_STD_STRING to 1 and -// GTEST_HAS_GLOBAL_STRING to 0. -// -// If the user doesn't define GTEST_HAS_STD_STRING and/or -// GTEST_HAS_GLOBAL_STRING, they are defined heuristically. - -namespace testing { - -// The upper limit for valid stack trace depths. -const int kMaxStackTraceDepth = 100; - -// This flag specifies the maximum number of stack frames to be -// printed in a failure message. -GTEST_DECLARE_int32(stack_trace_depth); - -// This flag controls whether Google Test includes Google Test internal -// stack frames in failure stack traces. -GTEST_DECLARE_bool(show_internal_stack_frames); - -// The possible outcomes of a test part (i.e. an assertion or an -// explicit SUCCEED(), FAIL(), or ADD_FAILURE()). -enum TestPartResultType { - TPRT_SUCCESS, // Succeeded. - TPRT_NONFATAL_FAILURE, // Failed but the test can continue. - TPRT_FATAL_FAILURE // Failed and the test should be terminated. -}; - -namespace internal { - -class GTestFlagSaver; - -// Converts a streamable value to a String. A NULL pointer is -// converted to "(null)". When the input value is a ::string, -// ::std::string, ::wstring, or ::std::wstring object, each NUL -// character in it is replaced with "\\0". -// Declared in gtest-internal.h but defined here, so that it has access -// to the definition of the Message class, required by the ARM -// compiler. -template <typename T> -String StreamableToString(const T& streamable) { - return (Message() << streamable).GetString(); -} - -} // namespace internal - -// A class for indicating whether an assertion was successful. When -// the assertion wasn't successful, the AssertionResult object -// remembers a non-empty message that described how it failed. -// -// This class is useful for defining predicate-format functions to be -// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). -// -// The constructor of AssertionResult is private. To create an -// instance of this class, use one of the factory functions -// (AssertionSuccess() and AssertionFailure()). -// -// For example, in order to be able to write: -// -// // Verifies that Foo() returns an even number. -// EXPECT_PRED_FORMAT1(IsEven, Foo()); -// -// you just need to define: -// -// testing::AssertionResult IsEven(const char* expr, int n) { -// if ((n % 2) == 0) return testing::AssertionSuccess(); -// -// Message msg; -// msg << "Expected: " << expr << " is even\n" -// << " Actual: it's " << n; -// return testing::AssertionFailure(msg); -// } -// -// If Foo() returns 5, you will see the following message: -// -// Expected: Foo() is even -// Actual: it's 5 -class AssertionResult { - public: - // Declares factory functions for making successful and failed - // assertion results as friends. - friend AssertionResult AssertionSuccess(); - friend AssertionResult AssertionFailure(const Message&); - - // Returns true iff the assertion succeeded. - operator bool() const { return failure_message_.c_str() == NULL; } // NOLINT - - // Returns the assertion's failure message. - const char* failure_message() const { return failure_message_.c_str(); } - - private: - // The default constructor. It is used when the assertion succeeded. - AssertionResult() {} - - // The constructor used when the assertion failed. - explicit AssertionResult(const internal::String& failure_message); - - // Stores the assertion's failure message. - internal::String failure_message_; -}; - -// Makes a successful assertion result. -AssertionResult AssertionSuccess(); - -// Makes a failed assertion result with the given failure message. -AssertionResult AssertionFailure(const Message& msg); - -// The abstract class that all tests inherit from. -// -// In Google Test, a unit test program contains one or many TestCases, and -// each TestCase contains one or many Tests. -// -// When you define a test using the TEST macro, you don't need to -// explicitly derive from Test - the TEST macro automatically does -// this for you. -// -// The only time you derive from Test is when defining a test fixture -// to be used a TEST_F. For example: -// -// class FooTest : public testing::Test { -// protected: -// virtual void SetUp() { ... } -// virtual void TearDown() { ... } -// ... -// }; -// -// TEST_F(FooTest, Bar) { ... } -// TEST_F(FooTest, Baz) { ... } -// -// Test is not copyable. -class Test { - public: - friend class internal::TestInfoImpl; - - // Defines types for pointers to functions that set up and tear down - // a test case. - typedef void (*SetUpTestCaseFunc)(); - typedef void (*TearDownTestCaseFunc)(); - - // The d'tor is virtual as we intend to inherit from Test. - virtual ~Test(); - - // Returns true iff the current test has a fatal failure. - static bool HasFatalFailure(); - - // Logs a property for the current test. Only the last value for a given - // key is remembered. - // These are public static so they can be called from utility functions - // that are not members of the test fixture. - // The arguments are const char* instead strings, as Google Test is used - // on platforms where string doesn't compile. - // - // Note that a driving consideration for these RecordProperty methods - // was to produce xml output suited to the Greenspan charting utility, - // which at present will only chart values that fit in a 32-bit int. It - // is the user's responsibility to restrict their values to 32-bit ints - // if they intend them to be used with Greenspan. - static void RecordProperty(const char* key, const char* value); - static void RecordProperty(const char* key, int value); - - protected: - // Creates a Test object. - Test(); - - // Sets up the stuff shared by all tests in this test case. - // - // Google Test will call Foo::SetUpTestCase() before running the first - // test in test case Foo. Hence a sub-class can define its own - // SetUpTestCase() method to shadow the one defined in the super - // class. - static void SetUpTestCase() {} - - // Tears down the stuff shared by all tests in this test case. - // - // Google Test will call Foo::TearDownTestCase() after running the last - // test in test case Foo. Hence a sub-class can define its own - // TearDownTestCase() method to shadow the one defined in the super - // class. - static void TearDownTestCase() {} - - // Sets up the test fixture. - virtual void SetUp(); - - // Tears down the test fixture. - virtual void TearDown(); - - private: - // Returns true iff the current test has the same fixture class as - // the first test in the current test case. - static bool HasSameFixtureClass(); - - // Runs the test after the test fixture has been set up. - // - // A sub-class must implement this to define the test logic. - // - // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. - // Instead, use the TEST or TEST_F macro. - virtual void TestBody() = 0; - - // Sets up, executes, and tears down the test. - void Run(); - - // Uses a GTestFlagSaver to save and restore all Google Test flags. - const internal::GTestFlagSaver* const gtest_flag_saver_; - - // Often a user mis-spells SetUp() as Setup() and spends a long time - // wondering why it is never called by Google Test. The declaration of - // the following method is solely for catching such an error at - // compile time: - // - // - The return type is deliberately chosen to be not void, so it - // will be a conflict if a user declares void Setup() in his test - // fixture. - // - // - This method is private, so it will be another compiler error - // if a user calls it from his test fixture. - // - // DO NOT OVERRIDE THIS FUNCTION. - // - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } - - // We disallow copying Tests. - GTEST_DISALLOW_COPY_AND_ASSIGN(Test); -}; - - -// Defines the type of a function pointer that creates a Test object -// when invoked. -typedef Test* (*TestMaker)(); - - -// A TestInfo object stores the following information about a test: -// -// Test case name -// Test name -// Whether the test should be run -// A function pointer that creates the test object when invoked -// Test result -// -// The constructor of TestInfo registers itself with the UnitTest -// singleton such that the RUN_ALL_TESTS() macro knows which tests to -// run. -class TestInfo { - public: - // Destructs a TestInfo object. This function is not virtual, so - // don't inherit from TestInfo. - ~TestInfo(); - - // Creates a TestInfo object and registers it with the UnitTest - // singleton; returns the created object. - // - // Arguments: - // - // test_case_name: name of the test case - // name: name of the test - // fixture_class_id: ID of the test fixture class - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - // maker: pointer to the function that creates a test object - // - // This is public only because it's needed by the TEST and TEST_F macros. - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - static TestInfo* MakeAndRegisterInstance( - const char* test_case_name, - const char* name, - internal::TypeId fixture_class_id, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - TestMaker maker); - - // Returns the test case name. - const char* test_case_name() const; - - // Returns the test name. - const char* name() const; - - // Returns true if this test should run. - // - // Google Test allows the user to filter the tests by their full names. - // The full name of a test Bar in test case Foo is defined as - // "Foo.Bar". Only the tests that match the filter will run. - // - // A filter is a colon-separated list of glob (not regex) patterns, - // optionally followed by a '-' and a colon-separated list of - // negative patterns (tests to exclude). A test is run if it - // matches one of the positive patterns and does not match any of - // the negative patterns. - // - // For example, *A*:Foo.* is a filter that matches any string that - // contains the character 'A' or starts with "Foo.". - bool should_run() const; - - // Returns the result of the test. - const internal::TestResult* result() const; - private: -#ifdef GTEST_HAS_DEATH_TEST - friend class internal::DefaultDeathTestFactory; -#endif - friend class internal::TestInfoImpl; - friend class internal::UnitTestImpl; - friend class Test; - friend class TestCase; - - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count(); - - // Accessors for the implementation object. - internal::TestInfoImpl* impl() { return impl_; } - const internal::TestInfoImpl* impl() const { return impl_; } - - // Constructs a TestInfo object. - TestInfo(const char* test_case_name, const char* name, - internal::TypeId fixture_class_id, TestMaker maker); - - // An opaque implementation object. - internal::TestInfoImpl* impl_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(TestInfo); -}; - -// An Environment object is capable of setting up and tearing down an -// environment. The user should subclass this to define his own -// environment(s). -// -// An Environment object does the set-up and tear-down in virtual -// methods SetUp() and TearDown() instead of the constructor and the -// destructor, as: -// -// 1. You cannot safely throw from a destructor. This is a problem -// as in some cases Google Test is used where exceptions are enabled, and -// we may want to implement ASSERT_* using exceptions where they are -// available. -// 2. You cannot use ASSERT_* directly in a constructor or -// destructor. -class Environment { - public: - // The d'tor is virtual as we need to subclass Environment. - virtual ~Environment() {} - - // Override this to define how to set up the environment. - virtual void SetUp() {} - - // Override this to define how to tear down the environment. - virtual void TearDown() {} - private: - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } -}; - -// A UnitTest consists of a list of TestCases. -// -// This is a singleton class. The only instance of UnitTest is -// created when UnitTest::GetInstance() is first called. This -// instance is never deleted. -// -// UnitTest is not copyable. -// -// This class is thread-safe as long as the methods are called -// according to their specification. -class UnitTest { - public: - // Gets the singleton UnitTest object. The first time this method - // is called, a UnitTest object is constructed and returned. - // Consecutive calls will return the same object. - static UnitTest* GetInstance(); - - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); - - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - void AddTestPartResult(TestPartResultType result_type, - const char* file_name, - int line_number, - const internal::String& message, - const internal::String& os_stack_trace); - - // Adds a TestProperty to the current TestResult object. If the result already - // contains a property with the same key, the value will be updated. - void RecordPropertyForCurrentTest(const char* key, const char* value); - - // Runs all tests in this UnitTest object and prints the result. - // Returns 0 if successful, or 1 otherwise. - // - // This method can only be called from the main thread. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - int Run() GTEST_MUST_USE_RESULT; - - // Returns the TestCase object for the test that's currently running, - // or NULL if no test is running. - const TestCase* current_test_case() const; - - // Returns the TestInfo object for the test that's currently running, - // or NULL if no test is running. - const TestInfo* current_test_info() const; - - // Accessors for the implementation object. - internal::UnitTestImpl* impl() { return impl_; } - const internal::UnitTestImpl* impl() const { return impl_; } - private: - // ScopedTrace is a friend as it needs to modify the per-thread - // trace stack, which is a private member of UnitTest. - friend class internal::ScopedTrace; - - // Creates an empty UnitTest. - UnitTest(); - - // D'tor - virtual ~UnitTest(); - - // Pushes a trace defined by SCOPED_TRACE() on to the per-thread - // Google Test trace stack. - void PushGTestTrace(const internal::TraceInfo& trace); - - // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace(); - - // Protects mutable state in *impl_. This is mutable as some const - // methods need to lock it too. - mutable internal::Mutex mutex_; - - // Opaque implementation object. This field is never changed once - // the object is constructed. We don't mark it as const here, as - // doing so will cause a warning in the constructor of UnitTest. - // Mutable state in *impl_ is protected by mutex_. - internal::UnitTestImpl* impl_; - - // We disallow copying UnitTest. - GTEST_DISALLOW_COPY_AND_ASSIGN(UnitTest); -}; - -// A convenient wrapper for adding an environment for the test -// program. -// -// You should call this before RUN_ALL_TESTS() is called, probably in -// main(). If you use gtest_main, you need to call this before main() -// starts for it to take effect. For example, you can define a global -// variable like this: -// -// testing::Environment* const foo_env = -// testing::AddGlobalTestEnvironment(new FooEnvironment); -// -// However, we strongly recommend you to write your own main() and -// call AddGlobalTestEnvironment() there, as relying on initialization -// of global variables makes the code harder to read and may cause -// problems when you register multiple environments from different -// translation units and the environments have dependencies among them -// (remember that the compiler doesn't guarantee the order in which -// global variables from different translation units are initialized). -inline Environment* AddGlobalTestEnvironment(Environment* env) { - return UnitTest::GetInstance()->AddEnvironment(env); -} - -// Parses a command line for the flags that Google Test recognizes. -// Whenever a Google Test flag is seen, it is removed from argv, and *argc -// is decremented. -// -// No value is returned. Instead, the Google Test flag variables are -// updated. -void ParseGTestFlags(int* argc, char** argv); - -// This overloaded version can be used in Windows programs compiled in -// UNICODE mode. -#ifdef GTEST_OS_WINDOWS -void ParseGTestFlags(int* argc, wchar_t** argv); -#endif // GTEST_OS_WINDOWS - -namespace internal { - -// These overloaded versions handle ::std::string and ::std::wstring. -#if GTEST_HAS_STD_STRING -inline String FormatForFailureMessage(const ::std::string& str) { - return (Message() << '"' << str << '"').GetString(); -} -#endif // GTEST_HAS_STD_STRING -#if GTEST_HAS_STD_WSTRING -inline String FormatForFailureMessage(const ::std::wstring& wstr) { - return (Message() << "L\"" << wstr << '"').GetString(); -} -#endif // GTEST_HAS_STD_WSTRING - -// These overloaded versions handle ::string and ::wstring. -#if GTEST_HAS_GLOBAL_STRING -inline String FormatForFailureMessage(const ::string& str) { - return (Message() << '"' << str << '"').GetString(); -} -#endif // GTEST_HAS_GLOBAL_STRING -#if GTEST_HAS_GLOBAL_WSTRING -inline String FormatForFailureMessage(const ::wstring& wstr) { - return (Message() << "L\"" << wstr << '"').GetString(); -} -#endif // GTEST_HAS_GLOBAL_WSTRING - -// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) -// operand to be used in a failure message. The type (but not value) -// of the other operand may affect the format. This allows us to -// print a char* as a raw pointer when it is compared against another -// char*, and print it as a C string when it is compared against an -// std::string object, for example. -// -// The default implementation ignores the type of the other operand. -// Some specialized versions are used to handle formatting wide or -// narrow C strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template <typename T1, typename T2> -String FormatForComparisonFailureMessage(const T1& value, - const T2& /* other_operand */) { - return FormatForFailureMessage(value); -} - -// The helper function for {ASSERT|EXPECT}_EQ. -template <typename T1, typename T2> -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { - if (expected == actual) { - return AssertionSuccess(); - } - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); -} - -// With this overloaded version, we allow anonymous enums to be used -// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums -// can be implicitly cast to BiggestInt. -AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual); - -// The helper class for {ASSERT|EXPECT}_EQ. The template argument -// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() -// is a null pointer literal. The following default implementation is -// for lhs_is_null_literal being false. -template <bool lhs_is_null_literal> -class EqHelper { - public: - // This templatized version is for the general case. - template <typename T1, typename T2> - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } - - // With this overloaded version, we allow anonymous enums to be used - // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous - // enums can be implicitly cast to BiggestInt. - // - // Even though its body looks the same as the above version, we - // cannot merge the two, as it will make anonymous enums unhappy. - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } -}; - -// This specialization is used when the first argument to ASSERT_EQ() -// is a null pointer literal. -template <> -class EqHelper<true> { - public: - // We define two overloaded versions of Compare(). The first - // version will be picked when the second argument to ASSERT_EQ() is - // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or - // EXPECT_EQ(false, a_bool). - template <typename T1, typename T2> - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } - - // This version will be picked when the second argument to - // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). - template <typename T1, typename T2> - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - T2* actual) { - // We already know that 'expected' is a null pointer. - return CmpHelperEQ(expected_expression, actual_expression, - static_cast<T2*>(NULL), actual); - } -}; - -// A macro for implementing the helper functions needed to implement -// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste -// of similar code. -// -// For each templatized helper function, we also define an overloaded -// version for BiggestInt in order to reduce code bloat and allow -// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled -// with gcc 4. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -#define GTEST_IMPL_CMP_HELPER(op_name, op)\ -template <typename T1, typename T2>\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - const T1& val1, const T2& val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - Message msg;\ - msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - return AssertionFailure(msg);\ - }\ -}\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - BiggestInt val1, BiggestInt val2); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - -// Implements the helper function for {ASSERT|EXPECT}_NE -GTEST_IMPL_CMP_HELPER(NE, !=) -// Implements the helper function for {ASSERT|EXPECT}_LE -GTEST_IMPL_CMP_HELPER(LE, <=) -// Implements the helper function for {ASSERT|EXPECT}_LT -GTEST_IMPL_CMP_HELPER(LT, < ) -// Implements the helper function for {ASSERT|EXPECT}_GE -GTEST_IMPL_CMP_HELPER(GE, >=) -// Implements the helper function for {ASSERT|EXPECT}_GT -GTEST_IMPL_CMP_HELPER(GT, > ) - -#undef GTEST_IMPL_CMP_HELPER - -// The helper function for {ASSERT|EXPECT}_STREQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); - -// The helper function for {ASSERT|EXPECT}_STRCASEEQ. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); - -// The helper function for {ASSERT|EXPECT}_STRNE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); - -// The helper function for {ASSERT|EXPECT}_STRCASENE. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); - - -// Helper function for *_STREQ on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual); - -// Helper function for *_STRNE on wide strings. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); - -} // namespace internal - -// IsSubstring() and IsNotSubstring() are intended to be used as the -// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by -// themselves. They check whether needle is a substring of haystack -// (NULL is considered a substring of itself only), and return an -// appropriate error message when they fail. -// -// The {needle,haystack}_expr arguments are the stringified -// expressions that generated the two real arguments. -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); -#if GTEST_HAS_STD_STRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); -#endif // GTEST_HAS_STD_STRING -#if GTEST_HAS_STD_WSTRING -AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); -AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); -#endif // GTEST_HAS_STD_WSTRING - -namespace internal { - -// Helper template function for comparing floating-points. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -template <typename RawType> -AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, - const char* actual_expression, - RawType expected, - RawType actual) { - const FloatingPoint<RawType> lhs(expected), rhs(actual); - - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } - - StrStream expected_ss; - expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) - << expected; - - StrStream actual_ss; - actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) - << actual; - - return EqFailure(expected_expression, - actual_expression, - StrStreamToString(&expected_ss), - StrStreamToString(&actual_ss), - false); -} - -// Helper function for implementing ASSERT_NEAR. -// -// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error); - -// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. -// A class that enables one to stream messages to assertion macros -class AssertHelper { - public: - // Constructor. - AssertHelper(TestPartResultType type, const char* file, int line, - const char* message); - // Message assignment is a semantic trick to enable assertion - // streaming; see the GTEST_MESSAGE macro below. - void operator=(const Message& message) const; - private: - TestPartResultType const type_; - const char* const file_; - int const line_; - String const message_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(AssertHelper); -}; - -} // namespace internal - -// Macros for indicating success/failure in test code. - -// ADD_FAILURE unconditionally adds a failure to the current test. -// SUCCEED generates a success - it doesn't automatically make the -// current test successful, as a test is only successful when it has -// no failure. -// -// EXPECT_* verifies that a certain condition is satisfied. If not, -// it behaves like ADD_FAILURE. In particular: -// -// EXPECT_TRUE verifies that a Boolean condition is true. -// EXPECT_FALSE verifies that a Boolean condition is false. -// -// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except -// that they will also abort the current function on failure. People -// usually want the fail-fast behavior of FAIL and ASSERT_*, but those -// writing data-driven tests often find themselves using ADD_FAILURE -// and EXPECT_* more. -// -// Examples: -// -// EXPECT_TRUE(server.StatusIsOK()); -// ASSERT_FALSE(server.HasPendingRequest(port)) -// << "There are still pending requests " << "on port " << port; - -// Generates a nonfatal failure with a generic message. -#define ADD_FAILURE() GTEST_NONFATAL_FAILURE("Failed") - -// Generates a fatal failure with a generic message. -#define FAIL() GTEST_FATAL_FAILURE("Failed") - -// Generates a success with a generic message. -#define SUCCEED() GTEST_SUCCESS("Succeeded") - -// Boolean assertions. -#define EXPECT_TRUE(condition) \ - GTEST_TEST_BOOLEAN(condition, #condition, false, true, \ - GTEST_NONFATAL_FAILURE) -#define EXPECT_FALSE(condition) \ - GTEST_TEST_BOOLEAN(!(condition), #condition, true, false, \ - GTEST_NONFATAL_FAILURE) -#define ASSERT_TRUE(condition) \ - GTEST_TEST_BOOLEAN(condition, #condition, false, true, \ - GTEST_FATAL_FAILURE) -#define ASSERT_FALSE(condition) \ - GTEST_TEST_BOOLEAN(!(condition), #condition, true, false, \ - GTEST_FATAL_FAILURE) - -// Includes the auto-generated header that implements a family of -// generic predicate assertion macros. -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest_pred_impl.h" // NOLINT -#else -#include <gtest/gtest_pred_impl.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -// Macros for testing equalities and inequalities. -// -// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual -// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 -// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 -// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 -// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 -// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 -// -// When they are not, Google Test prints both the tested expressions and -// their actual values. The values must be compatible built-in types, -// or you will get a compiler error. By "compatible" we mean that the -// values can be compared by the respective operator. -// -// Note: -// -// 1. It is possible to make a user-defined type work with -// {ASSERT|EXPECT}_??(), but that requires overloading the -// comparison operators and is thus discouraged by the Google C++ -// Usage Guide. Therefore, you are advised to use the -// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are -// equal. -// -// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on -// pointers (in particular, C strings). Therefore, if you use it -// with two C strings, you are testing how their locations in memory -// are related, not how their content is related. To compare two C -// strings by content, use {ASSERT|EXPECT}_STR*(). -// -// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to -// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you -// what the actual value is when it fails, and similarly for the -// other comparisons. -// -// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() -// evaluate their arguments, which is undefined. -// -// 5. These macros evaluate their arguments exactly once. -// -// Examples: -// -// EXPECT_NE(5, Foo()); -// EXPECT_EQ(NULL, a_pointer); -// ASSERT_LT(i, array_size); -// ASSERT_GT(records.size(), 0) << "There is no record left."; - -#define EXPECT_EQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal:: \ - EqHelper<GTEST_IS_NULL_LITERAL(expected)>::Compare, \ - expected, actual) -#define EXPECT_NE(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) -#define EXPECT_LE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define EXPECT_LT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define EXPECT_GE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define EXPECT_GT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -#define ASSERT_EQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal:: \ - EqHelper<GTEST_IS_NULL_LITERAL(expected)>::Compare, \ - expected, actual) -#define ASSERT_NE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) -#define ASSERT_LE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define ASSERT_LT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define ASSERT_GE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define ASSERT_GT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) - -// C String Comparisons. All tests treat NULL and any non-NULL string -// as different. Two NULLs are equal. -// -// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 -// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 -// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case -// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case -// -// For wide or narrow string objects, you can use the -// {ASSERT|EXPECT}_??() macros. -// -// Don't depend on the order in which the arguments are evaluated, -// which is undefined. -// -// These macros evaluate their arguments exactly once. - -#define EXPECT_STREQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) -#define EXPECT_STRNE(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define EXPECT_STRCASEEQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define EXPECT_STRCASENE(s1, s2)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -#define ASSERT_STREQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) -#define ASSERT_STRNE(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) -#define ASSERT_STRCASEEQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define ASSERT_STRCASENE(s1, s2)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) - -// Macros for comparing floating-point numbers. -// -// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): -// Tests that two float values are almost equal. -// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): -// Tests that two double values are almost equal. -// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): -// Tests that v1 and v2 are within the given distance to each other. -// -// Google Test uses ULP-based comparison to automatically pick a default -// error bound that is appropriate for the operands. See the -// FloatingPoint template class in gtest-internal.h if you are -// interested in the implementation details. - -#define EXPECT_FLOAT_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ - expected, actual) - -#define EXPECT_DOUBLE_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ - expected, actual) - -#define ASSERT_FLOAT_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ - expected, actual) - -#define ASSERT_DOUBLE_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ - expected, actual) - -#define EXPECT_NEAR(val1, val2, abs_error)\ - EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) - -#define ASSERT_NEAR(val1, val2, abs_error)\ - ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) - -// These predicate format functions work on floating-point values, and -// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. -// -// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); - -// Asserts that val1 is less than, or almost equal to, val2. Fails -// otherwise. In particular, it fails if either val1 or val2 is NaN. -AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2); -AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2); - - -#ifdef GTEST_OS_WINDOWS - -// Macros that test for HRESULT failure and success, these are only useful -// on Windows, and rely on Windows SDK macros and APIs to compile. -// -// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) -// -// When expr unexpectedly fails or succeeds, Google Test prints the expected result -// and the actual result with both a human-readable string representation of -// the error, if available, as well as the hex result code. -#define EXPECT_HRESULT_SUCCEEDED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -#define ASSERT_HRESULT_SUCCEEDED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) - -#define EXPECT_HRESULT_FAILED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -#define ASSERT_HRESULT_FAILED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) - -#endif // GTEST_OS_WINDOWS - - -// Causes a trace (including the source file path, the current line -// number, and the given message) to be included in every test failure -// message generated by code in the current scope. The effect is -// undone when the control leaves the current scope. -// -// The message argument can be anything streamable to std::ostream. -// -// In the implementation, we include the current line number as part -// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s -// to appear in the same block - as long as they are on different -// lines. -#define SCOPED_TRACE(message) \ - ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN(gtest_trace_, __LINE__)(\ - __FILE__, __LINE__, ::testing::Message() << (message)) - - -// Defines a test. -// -// The first parameter is the name of the test case, and the second -// parameter is the name of the test within the test case. -// -// The convention is to end the test case name with "Test". For -// example, a test case for the Foo class can be named FooTest. -// -// The user should put his test code between braces after using this -// macro. Example: -// -// TEST(FooTest, InitializesCorrectly) { -// Foo foo; -// EXPECT_TRUE(foo.StatusIsOK()); -// } - -#define TEST(test_case_name, test_name)\ - GTEST_TEST(test_case_name, test_name, ::testing::Test) - - -// Defines a test that uses a test fixture. -// -// The first parameter is the name of the test fixture class, which -// also doubles as the test case name. The second parameter is the -// name of the test within the test case. -// -// A test fixture class must be declared earlier. The user should put -// his test code between braces after using this macro. Example: -// -// class FooTest : public testing::Test { -// protected: -// virtual void SetUp() { b_.AddElement(3); } -// -// Foo a_; -// Foo b_; -// }; -// -// TEST_F(FooTest, InitializesCorrectly) { -// EXPECT_TRUE(a_.StatusIsOK()); -// } -// -// TEST_F(FooTest, ReturnsElementCountCorrectly) { -// EXPECT_EQ(0, a_.size()); -// EXPECT_EQ(1, b_.size()); -// } - -#define TEST_F(test_fixture, test_name)\ - GTEST_TEST(test_fixture, test_name, test_fixture) - -// Use this macro in main() to run all tests. It returns 0 if all -// tests are successful, or 1 otherwise. -// -// RUN_ALL_TESTS() should be invoked after the command line has been -// parsed by ParseGTestFlags(). - -#define RUN_ALL_TESTS()\ - (::testing::UnitTest::GetInstance()->Run()) - -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/src/gtest/gtest_main.cc b/src/gtest/gtest_main.cc deleted file mode 100644 index c216bd2d..00000000 --- a/src/gtest/gtest_main.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include <iostream> - -#include <gtest/gtest.h> - -int main(int argc, char **argv) { - std::cout << "Running main() from gtest_main.cc\n"; - - testing::ParseGTestFlags(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/src/gtest/gtest_pred_impl.h b/src/gtest/gtest_pred_impl.h deleted file mode 100644 index 984f7930..00000000 --- a/src/gtest/gtest_pred_impl.h +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// 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. - -// This file is AUTOMATICALLY GENERATED on 06/22/2008 by command -// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! -// -// Implements a family of generic predicate assertion macros. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ - -// Makes sure this header is not included before gtest.h. -#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ - -// This header implements a family of generic predicate assertion -// macros: -// -// ASSERT_PRED_FORMAT1(pred_format, v1) -// ASSERT_PRED_FORMAT2(pred_format, v1, v2) -// ... -// -// where pred_format is a function or functor that takes n (in the -// case of ASSERT_PRED_FORMATn) values and their source expression -// text, and returns a testing::AssertionResult. See the definition -// of ASSERT_EQ in gtest.h for an example. -// -// If you don't care about formatting, you can use the more -// restrictive version: -// -// ASSERT_PRED1(pred, v1) -// ASSERT_PRED2(pred, v1, v2) -// ... -// -// where pred is an n-ary function or functor that returns bool, -// and the values v1, v2, ..., must support the << operator for -// streaming to std::ostream. -// -// We also define the EXPECT_* variations. -// -// For now we only support predicates whose arity is at most 5. -// Please email googletestframework@googlegroups.com if you need -// support for higher arities. - -// GTEST_ASSERT is the basic statement to which all of the assertions -// in this file reduce. Don't use this in your code. - -#define GTEST_ASSERT(expression, on_failure) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER \ - if (const ::testing::AssertionResult gtest_ar = (expression)) \ - ; \ - else \ - on_failure(gtest_ar.failure_message()) - - -// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -template <typename Pred, - typename T1> -AssertionResult AssertPred1Helper(const char* pred_text, - const char* e1, - Pred pred, - const T1& v1) { - if (pred(v1)) return AssertionSuccess(); - - Message msg; - msg << pred_text << "(" - << e1 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. -// Don't use this in your code. -#define GTEST_PRED_FORMAT1(pred_format, v1, on_failure)\ - GTEST_ASSERT(pred_format(#v1, v1),\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use -// this in your code. -#define GTEST_PRED1(pred, v1, on_failure)\ - GTEST_ASSERT(::testing::AssertPred1Helper(#pred, \ - #v1, \ - pred, \ - v1), on_failure) - -// Unary predicate assertion macros. -#define EXPECT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1(pred_format, v1, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED1(pred, v1) \ - GTEST_PRED1(pred, v1, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1(pred_format, v1, GTEST_FATAL_FAILURE) -#define ASSERT_PRED1(pred, v1) \ - GTEST_PRED1(pred, v1, GTEST_FATAL_FAILURE) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -template <typename Pred, - typename T1, - typename T2> -AssertionResult AssertPred2Helper(const char* pred_text, - const char* e1, - const char* e2, - Pred pred, - const T1& v1, - const T2& v2) { - if (pred(v1, v2)) return AssertionSuccess(); - - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. -// Don't use this in your code. -#define GTEST_PRED_FORMAT2(pred_format, v1, v2, on_failure)\ - GTEST_ASSERT(pred_format(#v1, #v2, v1, v2),\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use -// this in your code. -#define GTEST_PRED2(pred, v1, v2, on_failure)\ - GTEST_ASSERT(::testing::AssertPred2Helper(#pred, \ - #v1, \ - #v2, \ - pred, \ - v1, \ - v2), on_failure) - -// Binary predicate assertion macros. -#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2(pred_format, v1, v2, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED2(pred, v1, v2) \ - GTEST_PRED2(pred, v1, v2, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2(pred_format, v1, v2, GTEST_FATAL_FAILURE) -#define ASSERT_PRED2(pred, v1, v2) \ - GTEST_PRED2(pred, v1, v2, GTEST_FATAL_FAILURE) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -template <typename Pred, - typename T1, - typename T2, - typename T3> -AssertionResult AssertPred3Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3) { - if (pred(v1, v2, v3)) return AssertionSuccess(); - - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. -// Don't use this in your code. -#define GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, on_failure)\ - GTEST_ASSERT(pred_format(#v1, #v2, #v3, v1, v2, v3),\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use -// this in your code. -#define GTEST_PRED3(pred, v1, v2, v3, on_failure)\ - GTEST_ASSERT(::testing::AssertPred3Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - pred, \ - v1, \ - v2, \ - v3), on_failure) - -// Ternary predicate assertion macros. -#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE) -#define ASSERT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3(pred, v1, v2, v3, GTEST_FATAL_FAILURE) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -template <typename Pred, - typename T1, - typename T2, - typename T3, - typename T4> -AssertionResult AssertPred4Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4) { - if (pred(v1, v2, v3, v4)) return AssertionSuccess(); - - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. -// Don't use this in your code. -#define GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use -// this in your code. -#define GTEST_PRED4(pred, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT(::testing::AssertPred4Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4), on_failure) - -// 4-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE) -#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE) - - - -// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -template <typename Pred, - typename T1, - typename T2, - typename T3, - typename T4, - typename T5> -AssertionResult AssertPred5Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - const char* e5, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4, - const T5& v5) { - if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); - - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ", " - << e5 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4 - << "\n" << e5 << " evaluates to " << v5; - return AssertionFailure(msg); -} - -// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. -// Don't use this in your code. -#define GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ - on_failure) - -// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use -// this in your code. -#define GTEST_PRED5(pred, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT(::testing::AssertPred5Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - #v5, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4, \ - v5), on_failure) - -// 5-ary predicate assertion macros. -#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE) -#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE) -#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE) -#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE) - - - -#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/src/gtest/gtest_prod.h b/src/gtest/gtest_prod.h deleted file mode 100644 index da80ddc6..00000000 --- a/src/gtest/gtest_prod.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2006, Google Inc. -// All rights reserved. -// -// 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: wan@google.com (Zhanyong Wan) -// -// Google C++ Testing Framework definitions useful in production code. - -#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ -#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ - -// When you need to test the private or protected members of a class, -// use the FRIEND_TEST macro to declare your tests as friends of the -// class. For example: -// -// class MyClass { -// private: -// void MyMethod(); -// FRIEND_TEST(MyClassTest, MyMethod); -// }; -// -// class MyClassTest : public testing::Test { -// // ... -// }; -// -// TEST_F(MyClassTest, MyMethod) { -// // Can call MyClass::MyMethod() here. -// } - -#define FRIEND_TEST(test_case_name, test_name)\ -friend class test_case_name##_##test_name##_Test - -#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/src/gtest/internal/gtest-death-test-internal.h b/src/gtest/internal/gtest-death-test-internal.h deleted file mode 100644 index b49c6e47..00000000 --- a/src/gtest/internal/gtest-death-test-internal.h +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file defines internal utilities needed for implementing -// death tests. They are subject to change without notice. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ - -#include <gtest/internal/gtest-internal.h> - -namespace testing { -namespace internal { - -GTEST_DECLARE_string(internal_run_death_test); - -// Names of the flags (needed for parsing Google Test flags). -const char kDeathTestStyleFlag[] = "death_test_style"; -const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; - -#ifdef GTEST_HAS_DEATH_TEST - -// DeathTest is a class that hides much of the complexity of the -// GTEST_DEATH_TEST macro. It is abstract; its static Create method -// returns a concrete class that depends on the prevailing death test -// style, as defined by the --gtest_death_test_style and/or -// --gtest_internal_run_death_test flags. - -// In describing the results of death tests, these terms are used with -// the corresponding definitions: -// -// exit status: The integer exit information in the format specified -// by wait(2) -// exit code: The integer code passed to exit(3), _exit(2), or -// returned from main() -class DeathTest { - public: - // Create returns false if there was an error determining the - // appropriate action to take for the current death test; for example, - // if the gtest_death_test_style flag is set to an invalid value. - // The LastMessage method will return a more detailed message in that - // case. Otherwise, the DeathTest pointer pointed to by the "test" - // argument is set. If the death test should be skipped, the pointer - // is set to NULL; otherwise, it is set to the address of a new concrete - // DeathTest object that controls the execution of the current test. - static bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); - DeathTest(); - virtual ~DeathTest() { } - - // A helper class that aborts a death test when it's deleted. - class ReturnSentinel { - public: - explicit ReturnSentinel(DeathTest* test) : test_(test) { } - ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } - private: - DeathTest* const test_; - GTEST_DISALLOW_COPY_AND_ASSIGN(ReturnSentinel); - } GTEST_ATTRIBUTE_UNUSED; - - // An enumeration of possible roles that may be taken when a death - // test is encountered. EXECUTE means that the death test logic should - // be executed immediately. OVERSEE means that the program should prepare - // the appropriate environment for a child process to execute the death - // test, then wait for it to complete. - enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; - - // An enumeration of the two reasons that a test might be aborted. - enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; - - // Assumes one of the above roles. - virtual TestRole AssumeRole() = 0; - - // Waits for the death test to finish and returns its status. - virtual int Wait() = 0; - - // Returns true if the death test passed; that is, the test process - // exited during the test, its exit status matches a user-supplied - // predicate, and its stderr output matches a user-supplied regular - // expression. - // The user-supplied predicate may be a macro expression rather - // than a function pointer or functor, or else Wait and Passed could - // be combined. - virtual bool Passed(bool exit_status_ok) = 0; - - // Signals that the death test did not die as expected. - virtual void Abort(AbortReason reason) = 0; - - // Returns a human-readable outcome message regarding the outcome of - // the last death test. - static const char* LastMessage(); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN(DeathTest); -}; - -// Factory interface for death tests. May be mocked out for testing. -class DeathTestFactory { - public: - virtual ~DeathTestFactory() { } - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) = 0; -}; - -// A concrete DeathTestFactory implementation for normal use. -class DefaultDeathTestFactory : public DeathTestFactory { - public: - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); -}; - -// Returns true if exit_status describes a process that was terminated -// by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status); - -// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, -// ASSERT_EXIT*, and EXPECT_EXIT*. -#define GTEST_DEATH_TEST(statement, predicate, regex, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER \ - if (true) { \ - const ::testing::internal::RE& gtest_regex = (regex); \ - ::testing::internal::DeathTest* gtest_dt; \ - if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ - __FILE__, __LINE__, >est_dt)) { \ - goto GTEST_CONCAT_TOKEN(gtest_label_, __LINE__); \ - } \ - if (gtest_dt != NULL) { \ - ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ - gtest_dt_ptr(gtest_dt); \ - switch (gtest_dt->AssumeRole()) { \ - case ::testing::internal::DeathTest::OVERSEE_TEST: \ - if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ - goto GTEST_CONCAT_TOKEN(gtest_label_, __LINE__); \ - } \ - break; \ - case ::testing::internal::DeathTest::EXECUTE_TEST: { \ - ::testing::internal::DeathTest::ReturnSentinel \ - gtest_sentinel(gtest_dt); \ - { statement; } \ - gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ - break; \ - } \ - } \ - } \ - } else \ - GTEST_CONCAT_TOKEN(gtest_label_, __LINE__): \ - fail(::testing::internal::DeathTest::LastMessage()) -// The symbol "fail" here expands to something into which a message -// can be streamed. - -// A struct representing the parsed contents of the -// --gtest_internal_run_death_test flag, as it existed when -// RUN_ALL_TESTS was called. -struct InternalRunDeathTestFlag { - String file; - int line; - int index; - int status_fd; -}; - -// Returns a newly created InternalRunDeathTestFlag object with fields -// initialized from the GTEST_FLAG(internal_run_death_test) flag if -// the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); - -#endif // GTEST_HAS_DEATH_TEST - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/src/gtest/internal/gtest-filepath.h b/src/gtest/internal/gtest-filepath.h deleted file mode 100644 index 6f63718d..00000000 --- a/src/gtest/internal/gtest-filepath.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// 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: keith.ray@gmail.com (Keith Ray) -// -// Google Test filepath utilities -// -// This header file declares classes and functions used internally by -// Google Test. They are subject to change without notice. -// -// This file is #included in testing/base/internal/gtest-internal.h -// Do not include this header file separately! - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-string.h" // NOLINT -#else -#include <gtest/internal/gtest-string.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - - -namespace testing { -namespace internal { - -// FilePath - a class for file and directory pathname manipulation which -// handles platform-specific conventions (like the pathname separator). -// Used for helper functions for naming files in a directory for xml output. -// Except for Set methods, all methods are const or static, which provides an -// "immutable value object" -- useful for peace of mind. -// A FilePath with a value ending in a path separator ("like/this/") represents -// a directory, otherwise it is assumed to represent a file. In either case, -// it may or may not represent an actual file or directory in the file system. -// Names are NOT checked for syntax correctness -- no checking for illegal -// characters, malformed paths, etc. - -class FilePath { - public: - FilePath() : pathname_("") { } - FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } - explicit FilePath(const char* pathname) : pathname_(pathname) { } - explicit FilePath(const String& pathname) : pathname_(pathname) { } - - void Set(const FilePath& rhs) { - pathname_ = rhs.pathname_; - } - - String ToString() const { return pathname_; } - const char* c_str() const { return pathname_.c_str(); } - - // Given directory = "dir", base_name = "test", number = 0, - // extension = "xml", returns "dir/test.xml". If number is greater - // than zero (e.g., 12), returns "dir/test_12.xml". - // On Windows platform, uses \ as the separator rather than /. - static FilePath MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension); - - // Returns a pathname for a file that does not currently exist. The pathname - // will be directory/base_name.extension or - // directory/base_name_<number>.extension if directory/base_name.extension - // already exists. The number will be incremented until a pathname is found - // that does not already exist. - // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. - // There could be a race condition if two or more processes are calling this - // function at the same time -- they could both pick the same filename. - static FilePath GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension); - - // If input name has a trailing separator character, removes it and returns - // the name, otherwise return the name string unmodified. - // On Windows platform, uses \ as the separator, other platforms use /. - FilePath RemoveTrailingPathSeparator() const; - - // Returns a copy of the FilePath with the directory part removed. - // Example: FilePath("path/to/file").RemoveDirectoryName() returns - // FilePath("file"). If there is no directory part ("just_a_file"), it returns - // the FilePath unmodified. If there is no file part ("just_a_dir/") it - // returns an empty FilePath (""). - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveDirectoryName() const; - - // RemoveFileName returns the directory path with the filename removed. - // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". - // If the FilePath is "a_file" or "/a_file", RemoveFileName returns - // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does - // not have a file, like "just/a/dir/", it returns the FilePath unmodified. - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveFileName() const; - - // Returns a copy of the FilePath with the case-insensitive extension removed. - // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns - // FilePath("dir/file"). If a case-insensitive extension is not - // found, returns a copy of the original FilePath. - FilePath RemoveExtension(const char* extension) const; - - // Creates directories so that path exists. Returns true if successful or if - // the directories already exist; returns false if unable to create - // directories for any reason. Will also return false if the FilePath does - // not represent a directory (that is, it doesn't end with a path separator). - bool CreateDirectoriesRecursively() const; - - // Create the directory so that path exists. Returns true if successful or - // if the directory already exists; returns false if unable to create the - // directory for any reason, including if the parent directory does not - // exist. Not named "CreateDirectory" because that's a macro on Windows. - bool CreateFolder() const; - - // Returns true if FilePath describes something in the file-system, - // either a file, directory, or whatever, and that something exists. - bool FileOrDirectoryExists() const; - - // Returns true if pathname describes a directory in the file-system - // that exists. - bool DirectoryExists() const; - - // Returns true if FilePath ends with a path separator, which indicates that - // it is intended to represent a directory. Returns false otherwise. - // This does NOT check that a directory (or file) actually exists. - bool IsDirectory() const; - - private: - String pathname_; - - // Don't implement operator= because it is banned by the style guide. - FilePath& operator=(const FilePath& rhs); -}; // class FilePath - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/src/gtest/internal/gtest-internal.h b/src/gtest/internal/gtest-internal.h deleted file mode 100644 index 2be1b4ac..00000000 --- a/src/gtest/internal/gtest-internal.h +++ /dev/null @@ -1,569 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file declares functions and macros used internally by -// Google Test. They are subject to change without notice. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-port.h" // NOLINT -#else -#include <gtest/internal/gtest-port.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -#ifdef GTEST_OS_LINUX -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#endif // GTEST_OS_LINUX - -#include <iomanip> // NOLINT -#include <limits> // NOLINT - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-string.h" // NOLINT -#include "gtest-filepath.h" // NOLINT -#else -#include <gtest/internal/gtest-string.h> -#include <gtest/internal/gtest-filepath.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -// Due to C++ preprocessor weirdness, we need double indirection to -// concatenate two tokens when one of them is __LINE__. Writing -// -// foo ## __LINE__ -// -// will result in the token foo__LINE__, instead of foo followed by -// the current line number. For more details, see -// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 -#define GTEST_CONCAT_TOKEN(foo, bar) GTEST_CONCAT_TOKEN_IMPL(foo, bar) -#define GTEST_CONCAT_TOKEN_IMPL(foo, bar) foo ## bar - -// Google Test defines the testing::Message class to allow construction of -// test messages via the << operator. The idea is that anything -// streamable to std::ostream can be streamed to a testing::Message. -// This allows a user to use his own types in Google Test assertions by -// overloading the << operator. -// -// util/gtl/stl_logging-inl.h overloads << for STL containers. These -// overloads cannot be defined in the std namespace, as that will be -// undefined behavior. Therefore, they are defined in the global -// namespace instead. -// -// C++'s symbol lookup rule (i.e. Koenig lookup) says that these -// overloads are visible in either the std namespace or the global -// namespace, but not other namespaces, including the testing -// namespace which Google Test's Message class is in. -// -// To allow STL containers (and other types that has a << operator -// defined in the global namespace) to be used in Google Test assertions, -// testing::Message must access the custom << operator from the global -// namespace. Hence this helper function. -// -// Note: Jeffrey Yasskin suggested an alternative fix by "using -// ::operator<<;" in the definition of Message's operator<<. That fix -// doesn't require a helper function, but unfortunately doesn't -// compile with MSVC. -template <typename T> -inline void GTestStreamToHelper(std::ostream* os, const T& val) { - *os << val; -} - -namespace testing { - -// Forward declaration of classes. - -class Message; // Represents a failure message. -class TestCase; // A collection of related tests. -class TestPartResult; // Result of a test part. -class TestInfo; // Information about a test. -class UnitTest; // A collection of test cases. -class UnitTestEventListenerInterface; // Listens to Google Test events. -class AssertionResult; // Result of an assertion. - -namespace internal { - -struct TraceInfo; // Information about a trace point. -class ScopedTrace; // Implements scoped trace. -class TestInfoImpl; // Opaque implementation of TestInfo -class TestResult; // Result of a single Test. -class UnitTestImpl; // Opaque implementation of UnitTest - -template <typename E> class List; // A generic list. -template <typename E> class ListNode; // A node in a generic list. - -// A secret type that Google Test users don't know about. It has no -// definition on purpose. Therefore it's impossible to create a -// Secret object, which is what we want. -class Secret; - -// Two overloaded helpers for checking at compile time whether an -// expression is a null pointer literal (i.e. NULL or any 0-valued -// compile-time integral constant). Their return values have -// different sizes, so we can use sizeof() to test which version is -// picked by the compiler. These helpers have no implementations, as -// we only need their signatures. -// -// Given IsNullLiteralHelper(x), the compiler will pick the first -// version if x can be implicitly converted to Secret*, and pick the -// second version otherwise. Since Secret is a secret and incomplete -// type, the only expression a user can write that has type Secret* is -// a null pointer literal. Therefore, we know that x is a null -// pointer literal if and only if the first version is picked by the -// compiler. -char IsNullLiteralHelper(Secret* p); -char (&IsNullLiteralHelper(...))[2]; // NOLINT - -// A compile-time bool constant that is true if and only if x is a -// null pointer literal (i.e. NULL or any 0-valued compile-time -// integral constant). -#ifdef __SYMBIAN32__ // Symbian -// Passing non-POD classes through ellipsis (...) crashes the ARM compiler. -// The Nokia Symbian compiler tries to instantiate a copy constructor for -// objects passed through ellipsis (...), failing for uncopyable objects. -// Hence we define this to false (and lose support for NULL detection). -#define GTEST_IS_NULL_LITERAL(x) false -#else // ! __SYMBIAN32__ -#define GTEST_IS_NULL_LITERAL(x) \ - (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) -#endif // __SYMBIAN32__ - -// Appends the user-supplied message to the Google-Test-generated message. -String AppendUserMessage(const String& gtest_msg, - const Message& user_msg); - -// A helper class for creating scoped traces in user programs. -class ScopedTrace { - public: - // The c'tor pushes the given source file location and message onto - // a trace stack maintained by Google Test. - ScopedTrace(const char* file, int line, const Message& message); - - // The d'tor pops the info pushed by the c'tor. - // - // Note that the d'tor is not virtual in order to be efficient. - // Don't inherit from ScopedTrace! - ~ScopedTrace(); - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN(ScopedTrace); -} GTEST_ATTRIBUTE_UNUSED; // A ScopedTrace object does its job in its - // c'tor and d'tor. Therefore it doesn't - // need to be used otherwise. - -// Converts a streamable value to a String. A NULL pointer is -// converted to "(null)". When the input value is a ::string, -// ::std::string, ::wstring, or ::std::wstring object, each NUL -// character in it is replaced with "\\0". -// Declared here but defined in gtest.h, so that it has access -// to the definition of the Message class, required by the ARM -// compiler. -template <typename T> -String StreamableToString(const T& streamable); - -// Formats a value to be used in a failure message. - -#ifdef __SYMBIAN32__ - -// These are needed as the Nokia Symbian Compiler cannot decide between -// const T& and const T* in a function template. The Nokia compiler _can_ -// decide between class template specializations for T and T*, so a -// tr1::type_traits-like is_pointer works, and we can overload on that. - -// This overload makes sure that all pointers (including -// those to char or wchar_t) are printed as raw pointers. -template <typename T> -inline String FormatValueForFailureMessage(internal::true_type dummy, - T* pointer) { - return StreamableToString(static_cast<const void*>(pointer)); -} - -template <typename T> -inline String FormatValueForFailureMessage(internal::false_type dummy, - const T& value) { - return StreamableToString(value); -} - -template <typename T> -inline String FormatForFailureMessage(const T& value) { - return FormatValueForFailureMessage( - typename internal::is_pointer<T>::type(), value); -} - -#else - -template <typename T> -inline String FormatForFailureMessage(const T& value) { - return StreamableToString(value); -} - -// This overload makes sure that all pointers (including -// those to char or wchar_t) are printed as raw pointers. -template <typename T> -inline String FormatForFailureMessage(T* pointer) { - return StreamableToString(static_cast<const void*>(pointer)); -} - -#endif // __SYMBIAN32__ - -// These overloaded versions handle narrow and wide characters. -String FormatForFailureMessage(char ch); -String FormatForFailureMessage(wchar_t wchar); - -// When this operand is a const char* or char*, and the other operand -// is a ::std::string or ::string, we print this operand as a C string -// rather than a pointer. We do the same for wide strings. - -// This internal macro is used to avoid duplicated code. -#define GTEST_FORMAT_IMPL(operand2_type, operand1_printer)\ -inline String FormatForComparisonFailureMessage(\ - operand2_type::value_type* str, const operand2_type& operand2) {\ - return operand1_printer(str);\ -}\ -inline String FormatForComparisonFailureMessage(\ - const operand2_type::value_type* str, const operand2_type& operand2) {\ - return operand1_printer(str);\ -} - -#if GTEST_HAS_STD_STRING -GTEST_FORMAT_IMPL(::std::string, String::ShowCStringQuoted) -#endif // GTEST_HAS_STD_STRING -#if GTEST_HAS_STD_WSTRING -GTEST_FORMAT_IMPL(::std::wstring, String::ShowWideCStringQuoted) -#endif // GTEST_HAS_STD_WSTRING - -#if GTEST_HAS_GLOBAL_STRING -GTEST_FORMAT_IMPL(::string, String::ShowCStringQuoted) -#endif // GTEST_HAS_GLOBAL_STRING -#if GTEST_HAS_GLOBAL_WSTRING -GTEST_FORMAT_IMPL(::wstring, String::ShowWideCStringQuoted) -#endif // GTEST_HAS_GLOBAL_WSTRING - -#undef GTEST_FORMAT_IMPL - -// Constructs and returns the message for an equality assertion -// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. -// -// The first four parameters are the expressions used in the assertion -// and their values, as strings. For example, for ASSERT_EQ(foo, bar) -// where foo is 5 and bar is 6, we have: -// -// expected_expression: "foo" -// actual_expression: "bar" -// expected_value: "5" -// actual_value: "6" -// -// The ignoring_case parameter is true iff the assertion is a -// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will -// be inserted into the message. -AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const String& expected_value, - const String& actual_value, - bool ignoring_case); - - -// This template class represents an IEEE floating-point number -// (either single-precision or double-precision, depending on the -// template parameters). -// -// The purpose of this class is to do more sophisticated number -// comparison. (Due to round-off error, etc, it's very unlikely that -// two floating-points will be equal exactly. Hence a naive -// comparison by the == operation often doesn't work.) -// -// Format of IEEE floating-point: -// -// The most-significant bit being the leftmost, an IEEE -// floating-point looks like -// -// sign_bit exponent_bits fraction_bits -// -// Here, sign_bit is a single bit that designates the sign of the -// number. -// -// For float, there are 8 exponent bits and 23 fraction bits. -// -// For double, there are 11 exponent bits and 52 fraction bits. -// -// More details can be found at -// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. -// -// Template parameter: -// -// RawType: the raw floating-point type (either float or double) -template <typename RawType> -class FloatingPoint { - public: - // Defines the unsigned integer type that has the same size as the - // floating point number. - typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits; - - // Constants. - - // # of bits in a number. - static const size_t kBitCount = 8*sizeof(RawType); - - // # of fraction bits in a number. - static const size_t kFractionBitCount = - std::numeric_limits<RawType>::digits - 1; - - // # of exponent bits in a number. - static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; - - // The mask for the sign bit. - static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); - - // The mask for the fraction bits. - static const Bits kFractionBitMask = - ~static_cast<Bits>(0) >> (kExponentBitCount + 1); - - // The mask for the exponent bits. - static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); - - // How many ULP's (Units in the Last Place) we want to tolerate when - // comparing two numbers. The larger the value, the more error we - // allow. A 0 value means that two numbers must be exactly the same - // to be considered equal. - // - // The maximum error of a single floating-point operation is 0.5 - // units in the last place. On Intel CPU's, all floating-point - // calculations are done with 80-bit precision, while double has 64 - // bits. Therefore, 4 should be enough for ordinary use. - // - // See the following article for more details on ULP: - // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. - static const size_t kMaxUlps = 4; - - // Constructs a FloatingPoint from a raw floating-point number. - // - // On an Intel CPU, passing a non-normalized NAN (Not a Number) - // around may change its bits, although the new value is guaranteed - // to be also a NAN. Therefore, don't expect this constructor to - // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) : value_(x) {} - - // Static methods - - // Reinterprets a bit pattern as a floating-point number. - // - // This function is needed to test the AlmostEquals() method. - static RawType ReinterpretBits(const Bits bits) { - FloatingPoint fp(0); - fp.bits_ = bits; - return fp.value_; - } - - // Returns the floating-point number that represent positive infinity. - static RawType Infinity() { - return ReinterpretBits(kExponentBitMask); - } - - // Non-static methods - - // Returns the bits that represents this number. - const Bits &bits() const { return bits_; } - - // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & bits_; } - - // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & bits_; } - - // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & bits_; } - - // Returns true iff this is NAN (not a number). - bool is_nan() const { - // It's a NAN if the exponent bits are all ones and the fraction - // bits are not entirely zeros. - return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); - } - - // Returns true iff this number is at most kMaxUlps ULP's away from - // rhs. In particular, this function: - // - // - returns false if either number is (or both are) NAN. - // - treats really large numbers as almost equal to infinity. - // - thinks +0.0 and -0.0 are 0 DLP's apart. - bool AlmostEquals(const FloatingPoint& rhs) const { - // The IEEE standard says that any comparison operation involving - // a NAN must return false. - if (is_nan() || rhs.is_nan()) return false; - - return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps; - } - - private: - // Converts an integer from the sign-and-magnitude representation to - // the biased representation. More precisely, let N be 2 to the - // power of (kBitCount - 1), an integer x is represented by the - // unsigned number x + N. - // - // For instance, - // - // -N + 1 (the most negative number representable using - // sign-and-magnitude) is represented by 1; - // 0 is represented by N; and - // N - 1 (the biggest number representable using - // sign-and-magnitude) is represented by 2N - 1. - // - // Read http://en.wikipedia.org/wiki/Signed_number_representations - // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits &sam) { - if (kSignBitMask & sam) { - // sam represents a negative number. - return ~sam + 1; - } else { - // sam represents a positive number. - return kSignBitMask | sam; - } - } - - // Given two numbers in the sign-and-magnitude representation, - // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, - const Bits &sam2) { - const Bits biased1 = SignAndMagnitudeToBiased(sam1); - const Bits biased2 = SignAndMagnitudeToBiased(sam2); - return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); - } - - union { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; -}; - -// Typedefs the instances of the FloatingPoint template class that we -// care to use. -typedef FloatingPoint<float> Float; -typedef FloatingPoint<double> Double; - -// In order to catch the mistake of putting tests that use different -// test fixture classes in the same test case, we need to assign -// unique IDs to fixture classes and compare them. The TypeId type is -// used to hold such IDs. The user should treat TypeId as an opaque -// type: the only operation allowed on TypeId values is to compare -// them for equality using the == operator. -typedef void* TypeId; - -// GetTypeId<T>() returns the ID of type T. Different values will be -// returned for different types. Calling the function twice with the -// same type argument is guaranteed to return the same ID. -template <typename T> -inline TypeId GetTypeId() { - static bool dummy = false; - // The compiler is required to create an instance of the static - // variable dummy for each T used to instantiate the template. - // Therefore, the address of dummy is guaranteed to be unique. - return &dummy; -} - -#ifdef GTEST_OS_WINDOWS - -// Predicate-formatters for implementing the HRESULT checking macros -// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} -// We pass a long instead of HRESULT to avoid causing an -// include dependency for the HRESULT type. -AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT -AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT - -#endif // GTEST_OS_WINDOWS - -} // namespace internal -} // namespace testing - -#define GTEST_MESSAGE(message, result_type) \ - ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ - = ::testing::Message() - -#define GTEST_FATAL_FAILURE(message) \ - return GTEST_MESSAGE(message, ::testing::TPRT_FATAL_FAILURE) - -#define GTEST_NONFATAL_FAILURE(message) \ - GTEST_MESSAGE(message, ::testing::TPRT_NONFATAL_FAILURE) - -#define GTEST_SUCCESS(message) \ - GTEST_MESSAGE(message, ::testing::TPRT_SUCCESS) - -#define GTEST_TEST_BOOLEAN(boolexpr, booltext, actual, expected, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER \ - if (boolexpr) \ - ; \ - else \ - fail("Value of: " booltext "\n Actual: " #actual "\nExpected: " #expected) - -// Helper macro for defining tests. -#define GTEST_TEST(test_case_name, test_name, parent_class)\ -class test_case_name##_##test_name##_Test : public parent_class {\ - public:\ - test_case_name##_##test_name##_Test() {}\ - static ::testing::Test* NewTest() {\ - return new test_case_name##_##test_name##_Test;\ - }\ - private:\ - virtual void TestBody();\ - static ::testing::TestInfo* const test_info_;\ - GTEST_DISALLOW_COPY_AND_ASSIGN(test_case_name##_##test_name##_Test);\ -};\ -\ -::testing::TestInfo* const test_case_name##_##test_name##_Test::test_info_ =\ - ::testing::TestInfo::MakeAndRegisterInstance(\ - #test_case_name, \ - #test_name, \ - ::testing::internal::GetTypeId< parent_class >(), \ - parent_class::SetUpTestCase, \ - parent_class::TearDownTestCase, \ - test_case_name##_##test_name##_Test::NewTest);\ -void test_case_name##_##test_name##_Test::TestBody() - - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/src/gtest/internal/gtest-port.h b/src/gtest/internal/gtest-port.h deleted file mode 100644 index 36d5a149..00000000 --- a/src/gtest/internal/gtest-port.h +++ /dev/null @@ -1,596 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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. -// -// Authors: wan@google.com (Zhanyong Wan) -// -// Low-level types and utilities for porting Google Test to various -// platforms. They are subject to change without notice. DO NOT USE -// THEM IN USER CODE. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ - -#ifndef GTEST_NOT_MAC_FRAMEWORK_MODE -// Protobuf never uses gTest in "mac framework mode". -#define GTEST_NOT_MAC_FRAMEWORK_MODE -#endif - -// The user can define the following macros in the build script to -// control Google Test's behavior: -// -// GTEST_HAS_STD_STRING - Define it to 1/0 to indicate that -// std::string does/doesn't work (Google Test can be -// used where std::string is unavailable). Leave -// it undefined to let Google Test define it. -// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string -// is/isn't available (some systems define ::string, -// which is different to std::string). Leave it -// undefined to let Google Test define it. - -// This header defines the following utilities: -// -// Macros indicating the name of the Google C++ Testing Framework project: -// GTEST_NAME - a string literal of the project name. -// GTEST_FLAG_PREFIX - a string literal of the prefix all Google -// Test flag names share. -// GTEST_FLAG_PREFIX_UPPER - a string literal of the prefix all Google -// Test flag names share, in upper case. -// -// Macros indicating the current platform: -// GTEST_OS_LINUX - defined iff compiled on Linux. -// GTEST_OS_MAC - defined iff compiled on Mac OS X. -// GTEST_OS_WINDOWS - defined iff compiled on Windows. -// Note that it is possible that none of the GTEST_OS_ macros are defined. -// -// Macros indicating available Google Test features: -// GTEST_HAS_DEATH_TEST - defined iff death tests are supported. -// -// Macros for basic C++ coding: -// GTEST_AMBIGUOUS_ELSE_BLOCKER - for disabling a gcc warning. -// GTEST_ATTRIBUTE_UNUSED - declares that a class' instances don't have to -// be used. -// GTEST_DISALLOW_COPY_AND_ASSIGN() - disables copy ctor and operator=. -// GTEST_MUST_USE_RESULT - declares that a function's result must be used. -// -// Synchronization: -// Mutex, MutexLock, ThreadLocal, GetThreadCount() -// - synchronization primitives. -// -// Template meta programming: -// is_pointer - as in TR1; needed on Symbian only. -// -// Smart pointers: -// scoped_ptr - as in TR2. -// -// Regular expressions: -// RE - a simple regular expression class using the POSIX -// Extended Regular Expression syntax. Not available on -// Windows. -// -// Logging: -// GTEST_LOG() - logs messages at the specified severity level. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. -// -// Stderr capturing: -// CaptureStderr() - starts capturing stderr. -// GetCapturedStderr() - stops capturing stderr and returns the captured -// string. -// -// Integer types: -// TypeWithSize - maps an integer to a int type. -// Int32, UInt32, Int64, UInt64, TimeInMillis -// - integers of known sizes. -// BiggestInt - the biggest signed integer type. -// -// Command-line utilities: -// GTEST_FLAG() - references a flag. -// GTEST_DECLARE_*() - declares a flag. -// GTEST_DEFINE_*() - defines a flag. -// GetArgvs() - returns the command line as a vector of strings. -// -// Environment variable utilities: -// GetEnv() - gets the value of an environment variable. -// BoolFromGTestEnv() - parses a bool environment variable. -// Int32FromGTestEnv() - parses an Int32 environment variable. -// StringFromGTestEnv() - parses a string environment variable. - -#include <sys/types.h> - -#include <stdlib.h> -#include <stdio.h> - -#define GTEST_NAME "Google Test" -#define GTEST_FLAG_PREFIX "gtest_" -#define GTEST_FLAG_PREFIX_UPPER "GTEST_" - -// Determines the platform on which Google Test is compiled. -#ifdef _MSC_VER -// TODO(kenton): GTEST_OS_WINDOWS is currently used to mean both "The OS is -// Windows" and "The compiler is MSVC". These meanings really should be -// separated in order to better support Windows compilers other than MSVC. -// Then again, the macro _WIN32 is already a good way to check for the first -// case and _MSC_VER is a good way to check for the latter, so maybe -// GTEST_OS_WINDOWS should be removed? -#define GTEST_OS_WINDOWS -#elif defined __APPLE__ -#define GTEST_OS_MAC -#elif defined __linux__ -#define GTEST_OS_LINUX -#endif // _MSC_VER - -// Determines whether ::std::string and ::string are available. - -#ifndef GTEST_HAS_STD_STRING -// The user didn't tell us whether ::std::string is available, so we -// need to figure it out. - -#ifdef GTEST_OS_WINDOWS -// Assumes that exceptions are enabled by default. -#ifndef _HAS_EXCEPTIONS -#define _HAS_EXCEPTIONS 1 -#endif // _HAS_EXCEPTIONS -// GTEST_HAS_EXCEPTIONS is non-zero iff exceptions are enabled. It is -// always defined, while _HAS_EXCEPTIONS is defined only on Windows. -#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -// On Windows, we can use ::std::string if the compiler version is VS -// 2005 or above, or if exceptions are enabled. -#define GTEST_HAS_STD_STRING ((_MSC_VER >= 1400) || GTEST_HAS_EXCEPTIONS) -#else // We are on Linux or Mac OS. -#define GTEST_HAS_EXCEPTIONS 0 -#define GTEST_HAS_STD_STRING 1 -#endif // GTEST_OS_WINDOWS - -#endif // GTEST_HAS_STD_STRING - -#ifndef GTEST_HAS_GLOBAL_STRING -// The user didn't tell us whether ::string is available, so we need -// to figure it out. - -#define GTEST_HAS_GLOBAL_STRING 0 - -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING -#include <string> // NOLINT -#endif // GTEST_HAS_STD_STRING || GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_STD_STRING -#include <sstream> // NOLINT -#else -#include <strstream> // NOLINT -#endif // GTEST_HAS_STD_STRING - -// Determines whether to support death tests. -#if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) -#define GTEST_HAS_DEATH_TEST -// On some platforms, <regex.h> needs someone to define size_t, and -// won't compile if being #included first. Therefore it's important -// that we #include it after <sys/types.h>. -#include <regex.h> -#include <vector> -#include <fcntl.h> -#include <sys/mman.h> -#endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) - -// Defines some utility macros. - -// The GNU compiler emits a warning if nested "if" statements are followed by -// an "else" statement and braces are not used to explicitly disambiguate the -// "else" binding. This leads to problems with code like: -// -// if (gate) -// ASSERT_*(condition) << "Some message"; -// -// The "switch (0) case 0:" idiom is used to suppress this. -#ifdef __INTEL_COMPILER -#define GTEST_AMBIGUOUS_ELSE_BLOCKER -#else -#define GTEST_AMBIGUOUS_ELSE_BLOCKER switch (0) case 0: // NOLINT -#endif - -// Use this annotation at the end of a struct / class definition to -// prevent the compiler from optimizing away instances that are never -// used. This is useful when all interesting logic happens inside the -// c'tor and / or d'tor. Example: -// -// struct Foo { -// Foo() { ... } -// } GTEST_ATTRIBUTE_UNUSED; -#if defined(GTEST_OS_WINDOWS) || (defined(GTEST_OS_LINUX) && defined(SWIG)) -#define GTEST_ATTRIBUTE_UNUSED -#else -#define GTEST_ATTRIBUTE_UNUSED __attribute__ ((unused)) -#endif // GTEST_OS_WINDOWS || (GTEST_OS_LINUX && SWIG) - -// A macro to disallow the evil copy constructor and operator= functions -// This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_COPY_AND_ASSIGN(type)\ - type(const type &);\ - void operator=(const type &) - -// Tell the compiler to warn about unused return values for functions declared -// with this macro. The macro should be used on function declarations -// following the argument list: -// -// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT; -#if defined(__GNUC__) \ - && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ - && !defined(COMPILER_ICC) -#define GTEST_MUST_USE_RESULT __attribute__ ((warn_unused_result)) -#else -#define GTEST_MUST_USE_RESULT -#endif // (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4) - -namespace testing { - -class Message; - -namespace internal { - -class String; - -// std::strstream is deprecated. However, we have to use it on -// Windows as std::stringstream won't compile on Windows when -// exceptions are disabled. We use std::stringstream on other -// platforms to avoid compiler warnings there. -#if GTEST_HAS_STD_STRING -typedef ::std::stringstream StrStream; -#else -typedef ::std::strstream StrStream; -#endif // GTEST_HAS_STD_STRING - -// Defines scoped_ptr. - -// This implementation of scoped_ptr is PARTIAL - it only contains -// enough stuff to satisfy Google Test's need. -template <typename T> -class scoped_ptr { - public: - explicit scoped_ptr(T* p = NULL) : ptr_(p) {} - ~scoped_ptr() { reset(); } - - T& operator*() const { return *ptr_; } - T* operator->() const { return ptr_; } - T* get() const { return ptr_; } - - T* release() { - T* const ptr = ptr_; - ptr_ = NULL; - return ptr; - } - - void reset(T* p = NULL) { - if (p != ptr_) { - if (sizeof(T) > 0) { // Makes sure T is a complete type. - delete ptr_; - } - ptr_ = p; - } - } - private: - T* ptr_; - - GTEST_DISALLOW_COPY_AND_ASSIGN(scoped_ptr); -}; - -#ifdef GTEST_HAS_DEATH_TEST - -// Defines RE. Currently only needed for death tests. - -// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended -// Regular Expression syntax. -class RE { - public: - // Constructs an RE from a string. -#if GTEST_HAS_STD_STRING - RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT -#endif // GTEST_HAS_STD_STRING - -#if GTEST_HAS_GLOBAL_STRING - RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - - RE(const char* regex) { Init(regex); } // NOLINT - ~RE(); - - // Returns the string representation of the regex. - const char* pattern() const { return pattern_; } - - // Returns true iff str contains regular expression re. - - // TODO(wan): make PartialMatch() work when str contains NUL - // characters. -#if GTEST_HAS_STD_STRING - static bool PartialMatch(const ::std::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } -#endif // GTEST_HAS_STD_STRING - -#if GTEST_HAS_GLOBAL_STRING - static bool PartialMatch(const ::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } -#endif // GTEST_HAS_GLOBAL_STRING - - static bool PartialMatch(const char* str, const RE& re); - - private: - void Init(const char* regex); - - // We use a const char* instead of a string, as Google Test may be used - // where string is not available. We also do not use Google Test's own - // String type here, in order to simplify dependencies between the - // files. - const char* pattern_; - regex_t regex_; - bool is_valid_; -}; - -#endif // GTEST_HAS_DEATH_TEST - -// Defines logging utilities: -// GTEST_LOG() - logs messages at the specified severity level. -// LogToStderr() - directs all log messages to stderr. -// FlushInfoLog() - flushes informational log messages. - -enum GTestLogSeverity { - GTEST_INFO, - GTEST_WARNING, - GTEST_ERROR, - GTEST_FATAL -}; - -void GTestLog(GTestLogSeverity severity, const char* file, - int line, const char* msg); - -#define GTEST_LOG(severity, msg)\ - ::testing::internal::GTestLog(\ - ::testing::internal::GTEST_##severity, __FILE__, __LINE__, \ - (::testing::Message() << (msg)).GetString().c_str()) - -inline void LogToStderr() {} -inline void FlushInfoLog() { fflush(NULL); } - -// Defines the stderr capturer: -// CaptureStderr - starts capturing stderr. -// GetCapturedStderr - stops capturing stderr and returns the captured string. - -#ifdef GTEST_HAS_DEATH_TEST - -// A copy of all command line arguments. Set by ParseGTestFlags(). -extern ::std::vector<String> g_argvs; - -void CaptureStderr(); -// GTEST_HAS_DEATH_TEST implies we have ::std::string. -::std::string GetCapturedStderr(); -const ::std::vector<String>& GetArgvs(); - -#endif // GTEST_HAS_DEATH_TEST - -// Defines synchronization primitives. - -// A dummy implementation of synchronization primitives (mutex, lock, -// and thread-local variable). Necessary for compiling Google Test where -// mutex is not supported - using Google Test in multiple threads is not -// supported on such platforms. - -class Mutex { - public: - Mutex() {} - explicit Mutex(int unused) {} - void AssertHeld() const {} - enum { NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX = 0 }; -}; - -// We cannot call it MutexLock directly as the ctor declaration would -// conflict with a macro named MutexLock, which is defined on some -// platforms. Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(Mutex*) {} // NOLINT -}; - -typedef GTestMutexLock MutexLock; - -template <typename T> -class ThreadLocal { - public: - T* pointer() { return &value_; } - const T* pointer() const { return &value_; } - const T& get() const { return value_; } - void set(const T& value) { value_ = value; } - private: - T value_; -}; - -// There's no portable way to detect the number of threads, so we just -// return 0 to indicate that we cannot detect it. -// CHANGED FOR PROTOBUF: The protobuf tests do not use multiple threads, -// so we know there is one thread. -inline size_t GetThreadCount() { return 1; } - -// Defines tr1::is_pointer (only needed for Symbian). - -#ifdef __SYMBIAN32__ - -// Symbian does not have tr1::type_traits, so we define our own is_pointer -// These are needed as the Nokia Symbian Compiler cannot decide between -// const T& and const T* in a function template. - -template <bool bool_value> -struct bool_constant { - typedef bool_constant<bool_value> type; - static const bool value = bool_value; -}; -template <bool bool_value> const bool bool_constant<bool_value>::value; - -typedef bool_constant<false> false_type; -typedef bool_constant<true> true_type; - -template <typename T> -struct is_pointer : public false_type {}; - -template <typename T> -struct is_pointer<T*> : public true_type {}; - -#endif // __SYMBIAN32__ - -// Defines BiggestInt as the biggest signed integer type the compiler -// supports. - -#ifdef GTEST_OS_WINDOWS -typedef __int64 BiggestInt; -#else -typedef long long BiggestInt; // NOLINT -#endif // GTEST_OS_WINDOWS - -// The maximum number a BiggestInt can represent. This definition -// works no matter BiggestInt is represented in one's complement or -// two's complement. -// -// We cannot rely on numeric_limits in STL, as __int64 and long long -// are not part of standard C++ and numeric_limits doesn't need to be -// defined for them. -const BiggestInt kMaxBiggestInt = - ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); - -// This template class serves as a compile-time function from size to -// type. It maps a size in bytes to a primitive type with that -// size. e.g. -// -// TypeWithSize<4>::UInt -// -// is typedef-ed to be unsigned int (unsigned integer made up of 4 -// bytes). -// -// Such functionality should belong to STL, but I cannot find it -// there. -// -// Google Test uses this class in the implementation of floating-point -// comparison. -// -// For now it only handles UInt (unsigned int) as that's all Google Test -// needs. Other types can be easily added in the future if need -// arises. -template <size_t size> -class TypeWithSize { - public: - // This prevents the user from using TypeWithSize<N> with incorrect - // values of N. - typedef void UInt; -}; - -// The specialization for size 4. -template <> -class TypeWithSize<4> { - public: - // unsigned int has size 4 in both gcc and MSVC. - // - // As base/basictypes.h doesn't compile on Windows, we cannot use - // uint32, uint64, and etc here. - typedef int Int; - typedef unsigned int UInt; -}; - -// The specialization for size 8. -template <> -class TypeWithSize<8> { - public: -#ifdef GTEST_OS_WINDOWS - typedef __int64 Int; - typedef unsigned __int64 UInt; -#else - typedef long long Int; // NOLINT - typedef unsigned long long UInt; // NOLINT -#endif // GTEST_OS_WINDOWS -}; - -// Integer types of known sizes. -typedef TypeWithSize<4>::Int Int32; -typedef TypeWithSize<4>::UInt UInt32; -typedef TypeWithSize<8>::Int Int64; -typedef TypeWithSize<8>::UInt UInt64; -typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. - -// Utilities for command line flags and environment variables. - -// A wrapper for getenv() that works on Linux, Windows, and Mac OS. -inline const char* GetEnv(const char* name) { -#ifdef _WIN32_WCE // We are on Windows CE. - // CE has no environment variables. - return NULL; -#elif defined(GTEST_OS_WINDOWS) // We are on Windows proper. - // MSVC 8 deprecates getenv(), so we want to suppress warning 4996 - // (deprecated function) there. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. - return getenv(name); -#pragma warning(pop) // Restores the warning state. -#else // We are on Linux or Mac OS. - return getenv(name); -#endif -} - -// Macro for referencing flags. -#define GTEST_FLAG(name) FLAGS_gtest_##name - -// Macros for declaring flags. -#define GTEST_DECLARE_bool(name) extern bool GTEST_FLAG(name) -#define GTEST_DECLARE_int32(name) \ - extern ::testing::internal::Int32 GTEST_FLAG(name) -#define GTEST_DECLARE_string(name) \ - extern ::testing::internal::String GTEST_FLAG(name) - -// Macros for defining flags. -#define GTEST_DEFINE_bool(name, default_val, doc) \ - bool GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_int32(name, default_val, doc) \ - ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) -#define GTEST_DEFINE_string(name, default_val, doc) \ - ::testing::internal::String GTEST_FLAG(name) = (default_val) - -// Parses 'str' for a 32-bit signed integer. If successful, writes the result -// to *value and returns true; otherwise leaves *value unchanged and returns -// false. -// TODO(chandlerc): Find a better way to refactor flag and environment parsing -// out of both gtest-port.cc and gtest.cc to avoid exporting this utility -// function. -bool ParseInt32(const Message& src_text, const char* str, Int32* value); - -// Parses a bool/Int32/string from the environment variable -// corresponding to the given Google Test flag. -bool BoolFromGTestEnv(const char* flag, bool default_val); -Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); -const char* StringFromGTestEnv(const char* flag, const char* default_val); - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/src/gtest/internal/gtest-string.h b/src/gtest/internal/gtest-string.h deleted file mode 100644 index 3d20c0fc..00000000 --- a/src/gtest/internal/gtest-string.h +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2005, Google Inc. -// All rights reserved. -// -// 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. -// -// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) -// -// The Google C++ Testing Framework (Google Test) -// -// This header file declares the String class and functions used internally by -// Google Test. They are subject to change without notice. They should not used -// by code external to Google Test. -// -// This header file is #included by testing/base/internal/gtest-internal.h. -// It should not be #included by other files. - -#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ -#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ - -#include <string.h> - -#if defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) -// When using Google Test on the Mac as a framework, all the includes will be -// in the framework headers folder along with gtest.h. -// Define GTEST_NOT_MAC_FRAMEWORK_MODE if you are building Google Test on -// the Mac and are not using it as a framework. -// More info on frameworks available here: -// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/ -// Concepts/WhatAreFrameworks.html. -#include "gtest-port.h" // NOLINT -#else -#include <gtest/internal/gtest-port.h> -#endif // defined(__APPLE__) && !defined(GTEST_NOT_MAC_FRAMEWORK_MODE) - -namespace testing { -namespace internal { - -// String - a UTF-8 string class. -// -// We cannot use std::string as Microsoft's STL implementation in -// Visual C++ 7.1 has problems when exception is disabled. There is a -// hack to work around this, but we've seen cases where the hack fails -// to work. -// -// Also, String is different from std::string in that it can represent -// both NULL and the empty string, while std::string cannot represent -// NULL. -// -// NULL and the empty string are considered different. NULL is less -// than anything (including the empty string) except itself. -// -// This class only provides minimum functionality necessary for -// implementing Google Test. We do not intend to implement a full-fledged -// string class here. -// -// Since the purpose of this class is to provide a substitute for -// std::string on platforms where it cannot be used, we define a copy -// constructor and assignment operators such that we don't need -// conditional compilation in a lot of places. -// -// In order to make the representation efficient, the d'tor of String -// is not virtual. Therefore DO NOT INHERIT FROM String. -class String { - public: - // Static utility methods - - // Returns the input if it's not NULL, otherwise returns "(null)". - // This function serves two purposes: - // - // 1. ShowCString(NULL) has type 'const char *', instead of the - // type of NULL (which is int). - // - // 2. In MSVC, streaming a null char pointer to StrStream generates - // an access violation, so we need to convert NULL to "(null)" - // before streaming it. - static inline const char* ShowCString(const char* c_str) { - return c_str ? c_str : "(null)"; - } - - // Returns the input enclosed in double quotes if it's not NULL; - // otherwise returns "(null)". For example, "\"Hello\"" is returned - // for input "Hello". - // - // This is useful for printing a C string in the syntax of a literal. - // - // Known issue: escape sequences are not handled yet. - static String ShowCStringQuoted(const char* c_str); - - // Clones a 0-terminated C string, allocating memory using new. The - // caller is responsible for deleting the return value using - // delete[]. Returns the cloned string, or NULL if the input is - // NULL. - // - // This is different from strdup() in string.h, which allocates - // memory using malloc(). - static const char* CloneCString(const char* c_str); - - // Compares two C strings. Returns true iff they have the same content. - // - // Unlike strcmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CStringEquals(const char* lhs, const char* rhs); - - // Converts a wide C string to a String using the UTF-8 encoding. - // NULL will be converted to "(null)". If an error occurred during - // the conversion, "(failed to convert from wide string)" is - // returned. - static String ShowWideCString(const wchar_t* wide_c_str); - - // Similar to ShowWideCString(), except that this function encloses - // the converted string in double quotes. - static String ShowWideCStringQuoted(const wchar_t* wide_c_str); - - // Compares two wide C strings. Returns true iff they have the same - // content. - // - // Unlike wcscmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); - - // Compares two C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike strcasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CaseInsensitiveCStringEquals(const char* lhs, - const char* rhs); - - // Formats a list of arguments to a String, using the same format - // spec string as for printf. - // - // We do not use the StringPrintf class as it is not universally - // available. - // - // The result is limited to 4096 characters (including the tailing - // 0). If 4096 characters are not enough to format the input, - // "<buffer exceeded>" is returned. - static String Format(const char* format, ...); - - // C'tors - - // The default c'tor constructs a NULL string. - String() : c_str_(NULL) {} - - // Constructs a String by cloning a 0-terminated C string. - String(const char* c_str) : c_str_(NULL) { // NOLINT - *this = c_str; - } - - // Constructs a String by copying a given number of chars from a - // buffer. E.g. String("hello", 3) will create the string "hel". - String(const char* buffer, size_t len); - - // The copy c'tor creates a new copy of the string. The two - // String objects do not share content. - String(const String& str) : c_str_(NULL) { - *this = str; - } - - // D'tor. String is intended to be a final class, so the d'tor - // doesn't need to be virtual. - ~String() { delete[] c_str_; } - - // Returns true iff this is an empty string (i.e. ""). - bool empty() const { - return (c_str_ != NULL) && (*c_str_ == '\0'); - } - - // Compares this with another String. - // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 - // if this is greater than rhs. - int Compare(const String& rhs) const; - - // Returns true iff this String equals the given C string. A NULL - // string and a non-NULL string are considered not equal. - bool operator==(const char* c_str) const { - return CStringEquals(c_str_, c_str); - } - - // Returns true iff this String doesn't equal the given C string. A NULL - // string and a non-NULL string are considered not equal. - bool operator!=(const char* c_str) const { - return !CStringEquals(c_str_, c_str); - } - - // Returns true iff this String ends with the given suffix. *Any* - // String is considered to end with a NULL or empty suffix. - bool EndsWith(const char* suffix) const; - - // Returns true iff this String ends with the given suffix, not considering - // case. Any String is considered to end with a NULL or empty suffix. - bool EndsWithCaseInsensitive(const char* suffix) const; - - // Returns the length of the encapsulated string, or -1 if the - // string is NULL. - int GetLength() const { - return c_str_ ? static_cast<int>(strlen(c_str_)) : -1; - } - - // Gets the 0-terminated C string this String object represents. - // The String object still owns the string. Therefore the caller - // should NOT delete the return value. - const char* c_str() const { return c_str_; } - - // Sets the 0-terminated C string this String object represents. - // The old string in this object is deleted, and this object will - // own a clone of the input string. This function copies only up to - // length bytes (plus a terminating null byte), or until the first - // null byte, whichever comes first. - // - // This function works even when the c_str parameter has the same - // value as that of the c_str_ field. - void Set(const char* c_str, size_t length); - - // Assigns a C string to this object. Self-assignment works. - const String& operator=(const char* c_str); - - // Assigns a String object to this object. Self-assignment works. - const String& operator=(const String &rhs) { - *this = rhs.c_str_; - return *this; - } - - private: - const char* c_str_; -}; - -// Streams a String to an ostream. -inline ::std::ostream& operator <<(::std::ostream& os, const String& str) { - // We call String::ShowCString() to convert NULL to "(null)". - // Otherwise we'll get an access violation on Windows. - return os << String::ShowCString(str.c_str()); -} - -// Gets the content of the StrStream's buffer as a String. Each '\0' -// character in the buffer is replaced with "\\0". -String StrStreamToString(StrStream* stream); - -// Converts a streamable value to a String. A NULL pointer is -// converted to "(null)". When the input value is a ::string, -// ::std::string, ::wstring, or ::std::wstring object, each NUL -// character in it is replaced with "\\0". - -// Declared here but defined in gtest.h, so that it has access -// to the definition of the Message class, required by the ARM -// compiler. -template <typename T> -String StreamableToString(const T& streamable); - -} // namespace internal -} // namespace testing - -#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ |