diff options
Diffstat (limited to 'src')
30 files changed, 520 insertions, 110 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b88e32ea..46190713 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,7 +111,7 @@ nobase_include_HEADERS = \ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 9:2:0 -export-dynamic -no-undefined +libprotobuf_lite_la_LDFLAGS = -version-info 10:0:0 -export-dynamic -no-undefined libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \ google/protobuf/stubs/atomicops_internals_x86_msvc.cc \ @@ -126,7 +126,6 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/arenastring.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_message_util.cc \ - google/protobuf/map_field.cc \ google/protobuf/message_lite.cc \ google/protobuf/repeated_field.cc \ google/protobuf/wire_format_lite.cc \ @@ -136,7 +135,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 9:2:0 -export-dynamic -no-undefined +libprotobuf_la_LDFLAGS = -version-info 10:0:0 -export-dynamic -no-undefined libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/stubs/strutil.cc \ @@ -150,6 +149,7 @@ libprotobuf_la_SOURCES = \ google/protobuf/dynamic_message.cc \ google/protobuf/extension_set_heavy.cc \ google/protobuf/generated_message_reflection.cc \ + google/protobuf/map_field.cc \ google/protobuf/message.cc \ google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.cc \ @@ -166,7 +166,7 @@ libprotobuf_la_SOURCES = \ google/protobuf/compiler/parser.cc libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 9:2:0 -export-dynamic -no-undefined +libprotoc_la_LDFLAGS = -version-info 10:0:0 -export-dynamic -no-undefined libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ @@ -260,7 +260,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/javanano/javanano_message_field.cc \ google/protobuf/compiler/javanano/javanano_message.h \ google/protobuf/compiler/javanano/javanano_primitive_field.cc \ - google/protobuf/compiler/python/python_generator.cc + google/protobuf/compiler/python/python_generator.cc \ + google/protobuf/compiler/ruby/ruby_generator.cc bin_PROGRAMS = protoc protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 1cb6441e..18536781 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -38,7 +38,14 @@ namespace google { namespace protobuf { google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_; -__thread Arena::ThreadCache Arena::thread_cache_ = { -1, NULL }; +#ifdef PROTOBUF_USE_DLLS +Arena::ThreadCache& Arena::thread_cache() { + static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL }; + return thread_cache_; +} +#else +GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL }; +#endif void Arena::Init(const ArenaOptions& options) { lifecycle_id_ = lifecycle_id_generator_.GetNext(); @@ -130,18 +137,18 @@ void* Arena::AllocateAligned(size_t n) { // If this thread already owns a block in this arena then try to use that. // This fast path optimizes the case where multiple threads allocate from the // same arena. - if (thread_cache_.last_lifecycle_id_seen == lifecycle_id_ && - thread_cache_.last_block_used_ != NULL) { - if (thread_cache_.last_block_used_->avail() < n) { + if (thread_cache().last_lifecycle_id_seen == lifecycle_id_ && + thread_cache().last_block_used_ != NULL) { + if (thread_cache().last_block_used_->avail() < n) { return SlowAlloc(n); } - return AllocFromBlock(thread_cache_.last_block_used_, n); + return AllocFromBlock(thread_cache().last_block_used_, n); } // Check whether we own the last accessed block on this arena. // This fast path optimizes the case where a single thread uses multiple // arenas. - void* me = &thread_cache_; + void* me = &thread_cache(); Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_)); if (!b || b->owner != me || b->avail() < n) { // If the next block to allocate from is the first block, try to claim it @@ -169,7 +176,7 @@ void* Arena::AllocFromBlock(Block* b, size_t n) { } void* Arena::SlowAlloc(size_t n) { - void* me = &thread_cache_; + void* me = &thread_cache(); Block* b = FindBlock(me); // Find block owned by me. // See if allocation fits in my latest block. if (b != NULL && b->avail() >= n) { diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 519e3569..d0cb163c 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -312,7 +312,12 @@ class LIBPROTOBUF_EXPORT Arena { static const size_t kHeaderSize = sizeof(Block); static google::protobuf::internal::SequenceNumber lifecycle_id_generator_; - static __thread ThreadCache thread_cache_; +#ifdef PROTOBUF_USE_DLLS + static ThreadCache& thread_cache(); +#else + static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif // SFINAE for skipping addition to delete list for a Type. This is mainly to // skip proto2/proto1 message objects with cc_enable_arenas=true from being @@ -434,8 +439,8 @@ class LIBPROTOBUF_EXPORT Arena { void CleanupList(); inline void SetThreadCacheBlock(Block* block) { - thread_cache_.last_block_used_ = block; - thread_cache_.last_lifecycle_id_seen = lifecycle_id_; + thread_cache().last_block_used_ = block; + thread_cache().last_lifecycle_id_seen = lifecycle_id_; } int64 lifecycle_id_; // Unique for each arena. Changes on Reset(). diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 76a4274f..9d3d3e3e 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -128,7 +128,7 @@ TEST(ArenaTest, InitialBlockTooSmall) { // initial block. std::vector<char> arena_block(64); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -137,7 +137,7 @@ TEST(ArenaTest, InitialBlockTooSmall) { // Ensure that the arena allocator did not return memory pointing into the // initial block of memory. - uintptr_t arena_start = reinterpret_cast<uintptr_t>(arena_block.data()); + uintptr_t arena_start = reinterpret_cast<uintptr_t>(&arena_block[0]); uintptr_t arena_end = arena_start + arena_block.size(); EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); @@ -771,7 +771,7 @@ TEST(ArenaTest, RepeatedFieldOnArena) { // Preallocate an initial arena block to avoid mallocs during hooked region. std::vector<char> arena_block(1024 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -898,7 +898,7 @@ TEST(ArenaTest, NoHeapAllocationsTest) { // Allocate a large initial block to avoid mallocs during hooked test. std::vector<char> arena_block(128 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); @@ -918,7 +918,7 @@ TEST(ArenaTest, NoHeapAllocationsTest) { TEST(ArenaTest, MessageLiteOnArena) { std::vector<char> arena_block(128 * 1024); ArenaOptions options; - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); const google::protobuf::MessageLite* prototype = dynamic_cast< @@ -977,7 +977,7 @@ TEST(ArenaTest, SpaceUsed) { // Test with initial block. std::vector<char> arena_block(1024); - options.initial_block = arena_block.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena_2(options); EXPECT_EQ(1024, arena_2.SpaceUsed()); diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 50f13837..d829ed91 100755 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -31,7 +31,6 @@ #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ #define GOOGLE_PROTOBUF_ARENASTRING_H__ -#include <stdint.h> #include <string> #include <google/protobuf/stubs/common.h> @@ -54,7 +53,7 @@ namespace google { namespace protobuf { namespace internal { -struct ArenaStringPtr { +struct LIBPROTOBUF_EXPORT ArenaStringPtr { inline void Set(const ::std::string* default_value, const ::std::string& value, ::google::protobuf::Arena* arena) { if (ptr_ == default_value) { diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 20fcfa62..2a04b293 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -153,6 +153,7 @@ TEST(GeneratedMessageTest, Defaults) { &message.optional_import_message()); } +#ifndef PROTOBUF_USE_DLLS TEST(GeneratedMessageTest, Int32StringConversion) { EXPECT_EQ("971", Int32ToString(971)); EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min)); @@ -165,6 +166,7 @@ TEST(GeneratedMessageTest, Int64StringConversion) { EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min)); EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max)); } +#endif // !PROTOBUF_USE_DLLS TEST(GeneratedMessageTest, FloatingPointDefaults) { const unittest::TestExtremeDefaultValues& extreme_default = diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 9f2127bb..931b8fa3 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -35,7 +35,7 @@ #include <google/protobuf/compiler/python/python_generator.h> #include <google/protobuf/compiler/java/java_generator.h> #include <google/protobuf/compiler/javanano/javanano_generator.h> - +#include <google/protobuf/compiler/ruby/ruby_generator.h> int main(int argc, char* argv[]) { @@ -63,5 +63,10 @@ int main(int argc, char* argv[]) { cli.RegisterGenerator("--javanano_out", &javanano_generator, "Generate Java Nano source file."); + // Ruby + google::protobuf::compiler::ruby::Generator rb_generator; + cli.RegisterGenerator("--ruby_out", &rb_generator, + "Generate Ruby source file."); + return cli.Run(argc, argv); } diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 35a0a899..ad017005 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2006000 +#if GOOGLE_PROTOBUF_VERSION < 3000000 #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 2006002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3000000 < 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. diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc new file mode 100644 index 00000000..82ccd72b --- /dev/null +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -0,0 +1,313 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/ruby/ruby_generator.h> + +using google::protobuf::internal::scoped_ptr; + +namespace google { +namespace protobuf { +namespace compiler { +namespace ruby { + +// Forward decls. +std::string IntToString(uint32_t value); +std::string StripDotProto(const std::string& proto_file); +std::string LabelForField(google::protobuf::FieldDescriptor* field); +std::string TypeName(google::protobuf::FieldDescriptor* field); +void GenerateMessage(const google::protobuf::Descriptor* message, + google::protobuf::io::Printer* printer); +void GenerateEnum(const google::protobuf::EnumDescriptor* en, + google::protobuf::io::Printer* printer); +void GenerateMessageAssignment( + const std::string& prefix, + const google::protobuf::Descriptor* message, + google::protobuf::io::Printer* printer); +void GenerateEnumAssignment( + const std::string& prefix, + const google::protobuf::EnumDescriptor* en, + google::protobuf::io::Printer* printer); + +std::string IntToString(uint32_t value) { + std::ostringstream os; + os << value; + return os.str(); +} + +std::string StripDotProto(const std::string& proto_file) { + int lastindex = proto_file.find_last_of("."); + return proto_file.substr(0, lastindex); +} + +std::string LabelForField(const google::protobuf::FieldDescriptor* field) { + switch (field->label()) { + case FieldDescriptor::LABEL_OPTIONAL: return "optional"; + case FieldDescriptor::LABEL_REQUIRED: return "required"; + case FieldDescriptor::LABEL_REPEATED: return "repeated"; + default: assert(false); return ""; + } +} + +std::string TypeName(const google::protobuf::FieldDescriptor* field) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: return "int32"; + case FieldDescriptor::CPPTYPE_INT64: return "int64"; + case FieldDescriptor::CPPTYPE_UINT32: return "uint32"; + case FieldDescriptor::CPPTYPE_UINT64: return "uint64"; + case FieldDescriptor::CPPTYPE_DOUBLE: return "double"; + case FieldDescriptor::CPPTYPE_FLOAT: return "float"; + case FieldDescriptor::CPPTYPE_BOOL: return "bool"; + case FieldDescriptor::CPPTYPE_ENUM: return "enum"; + case FieldDescriptor::CPPTYPE_STRING: return "string"; + case FieldDescriptor::CPPTYPE_MESSAGE: return "message"; + default: assert(false); return ""; + } +} + +void GenerateMessage(const google::protobuf::Descriptor* message, + google::protobuf::io::Printer* printer) { + printer->Print( + "add_message \"$name$\" do\n", + "name", message->full_name()); + printer->Indent(); + + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + printer->Print( + "$label$ :$name$, ", + "label", LabelForField(field), + "name", field->name()); + printer->Print( + ":$type$, $number$", + "type", TypeName(field), + "number", IntToString(field->number())); + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", field->message_type()->full_name()); + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer->Print( + ", \"$subtype$\"\n", + "subtype", field->enum_type()->full_name()); + } else { + printer->Print("\n"); + } + } + + printer->Outdent(); + printer->Print("end\n"); + + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateMessage(message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateEnum(message->enum_type(i), printer); + } +} + +void GenerateEnum(const google::protobuf::EnumDescriptor* en, + google::protobuf::io::Printer* printer) { + printer->Print( + "add_enum \"$name$\" do\n", + "name", en->full_name()); + printer->Indent(); + + for (int i = 0; i < en->value_count(); i++) { + const EnumValueDescriptor* value = en->value(i); + printer->Print( + "value :$name$, $number$\n", + "name", value->name(), + "number", IntToString(value->number())); + } + + printer->Outdent(); + printer->Print( + "end\n"); +} + +// Module names, class names, and enum value names need to be Ruby constants, +// which must start with a capital letter. +std::string RubifyConstant(const std::string& name) { + std::string ret = name; + if (!ret.empty()) { + if (ret[0] >= 'a' && ret[0] <= 'z') { + // If it starts with a lowercase letter, capitalize it. + ret[0] = ret[0] - 'a' + 'A'; + } else if (ret[0] < 'A' || ret[0] > 'Z') { + // Otherwise (e.g. if it begins with an underscore), we need to come up + // with some prefix that starts with a capital letter. We could be smarter + // here, e.g. try to strip leading underscores, but this may cause other + // problems if the user really intended the name. So let's just prepend a + // well-known suffix. + ret = "PB_" + ret; + } + } + return ret; +} + +void GenerateMessageAssignment( + const std::string& prefix, + const google::protobuf::Descriptor* message, + google::protobuf::io::Printer* printer) { + printer->Print( + "$prefix$$name$ = ", + "prefix", prefix, + "name", RubifyConstant(message->name())); + printer->Print( + "Google::Protobuf::DescriptorPool.generated_pool." + "lookup(\"$full_name$\").msgclass\n", + "full_name", message->full_name()); + + std::string nested_prefix = prefix + message->name() + "::"; + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateMessageAssignment(nested_prefix, message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateEnumAssignment(nested_prefix, message->enum_type(i), printer); + } +} + +void GenerateEnumAssignment( + const std::string& prefix, + const google::protobuf::EnumDescriptor* en, + google::protobuf::io::Printer* printer) { + printer->Print( + "$prefix$$name$ = ", + "prefix", prefix, + "name", RubifyConstant(en->name())); + printer->Print( + "Google::Protobuf::DescriptorPool.generated_pool." + "lookup(\"$full_name$\").enummodule\n", + "full_name", en->full_name()); +} + +int GeneratePackageModules( + std::string package_name, + google::protobuf::io::Printer* printer) { + int levels = 0; + while (!package_name.empty()) { + size_t dot_index = package_name.find("."); + string component; + if (dot_index == string::npos) { + component = package_name; + package_name = ""; + } else { + component = package_name.substr(0, dot_index); + package_name = package_name.substr(dot_index + 1); + } + component = RubifyConstant(component); + printer->Print( + "module $name$\n", + "name", component); + printer->Indent(); + levels++; + } + return levels; +} + +void EndPackageModules( + int levels, + google::protobuf::io::Printer* printer) { + while (levels > 0) { + levels--; + printer->Outdent(); + printer->Print( + "end\n"); + } +} + +void GenerateFile(const google::protobuf::FileDescriptor* file, + google::protobuf::io::Printer* printer) { + printer->Print( + "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "# source: $filename$\n" + "\n", + "filename", file->name()); + + printer->Print( + "require 'protobuf'\n\n"); + + for (int i = 0; i < file->dependency_count(); i++) { + const std::string& name = file->dependency(i)->name(); + printer->Print( + "require '$name$'\n", "name", StripDotProto(name)); + } + + printer->Print( + "Google::Protobuf::DescriptorPool.generated_pool.build do\n"); + printer->Indent(); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateMessage(file->message_type(i), printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateEnum(file->enum_type(i), printer); + } + printer->Outdent(); + printer->Print( + "end\n\n"); + + int levels = GeneratePackageModules(file->package(), printer); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateMessageAssignment("", file->message_type(i), printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateEnumAssignment("", file->enum_type(i), printer); + } + EndPackageModules(levels, printer); +} + +bool Generator::Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const { + std::string filename = + StripDotProto(file->name()) + ".rb"; + scoped_ptr<io::ZeroCopyOutputStream> output(generator_context->Open(filename)); + io::Printer printer(output.get(), '$'); + + GenerateFile(file, &printer); + + return true; +} + +} // namespace ruby +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.h b/src/google/protobuf/compiler/ruby/ruby_generator.h new file mode 100644 index 00000000..48dbefd1 --- /dev/null +++ b/src/google/protobuf/compiler/ruby/ruby_generator.h @@ -0,0 +1,57 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace ruby { + +class Generator : public google::protobuf::compiler::CodeGenerator { + virtual bool Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; +}; + +} // namespace ruby +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ + diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 19d49cab..b8dd198d 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -345,6 +345,10 @@ typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; set<string>* allowed_proto3_extendees_ = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_); +void DeleteAllowedProto3Extendee() { + delete allowed_proto3_extendees_; +} + void InitAllowedProto3Extendee() { allowed_proto3_extendees_ = new set<string>; allowed_proto3_extendees_->insert("google.protobuf.FileOptions"); @@ -354,6 +358,7 @@ void InitAllowedProto3Extendee() { allowed_proto3_extendees_->insert("google.protobuf.EnumValueOptions"); allowed_proto3_extendees_->insert("google.protobuf.ServiceOptions"); allowed_proto3_extendees_->insert("google.protobuf.MethodOptions"); + google::protobuf::internal::OnShutdown(&DeleteAllowedProto3Extendee); } // Checks whether the extendee type is allowed in proto3. diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 6bb5c6a6..cda25982 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2006000 +#if GOOGLE_PROTOBUF_VERSION < 3000000 #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 2006002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3000000 < 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. diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index f6ae3e52..6d8a9d03 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -110,7 +110,7 @@ class Map { ~Map() { clear(); } // Iterators - class LIBPROTOBUF_EXPORT const_iterator + class const_iterator : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t, const value_type*, const value_type&> { typedef typename hash_map<Key, value_type*>::const_iterator InnerIt; @@ -139,7 +139,7 @@ class Map { InnerIt it_; }; - class LIBPROTOBUF_EXPORT iterator : public std::iterator<std::forward_iterator_tag, value_type> { + class iterator : public std::iterator<std::forward_iterator_tag, value_type> { typedef typename hash_map<Key, value_type*>::iterator InnerIt; public: @@ -302,7 +302,7 @@ class Map { template <typename K, typename V, FieldDescriptor::Type KeyProto, FieldDescriptor::Type ValueProto, int default_enum> - friend class LIBPROTOBUF_EXPORT internal::MapField; + friend class internal::MapField; }; } // namespace protobuf diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 6971c763..217b15f6 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -43,6 +43,10 @@ class Arena; namespace protobuf { namespace internal { +// Register all MapEntry default instances so we can delete them in +// ShutdownProtobufLibrary(). +void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance(MessageLite* default_instance); + // This is the common base class for MapEntry. It is used by MapFieldBase in // reflection api, in which the static type of key and value is unknown. class LIBPROTOBUF_EXPORT MapEntryBase : public Message { @@ -80,7 +84,7 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message { // Moreover, default_enum_value is used to initialize enum field in proto2. template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType, FieldDescriptor::Type ValueProtoType, int default_enum_value> -class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { +class MapEntry : public MapEntryBase { // Handlers for key/value's proto field type. Used to infer internal layout // and provide parsing/serialization support. typedef MapProtoTypeHandler<KeyProtoType> KeyProtoHandler; @@ -317,6 +321,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { entry->reflection_ = reflection; entry->default_instance_ = entry; entry->InitAsDefaultInstance(); + RegisterMapEntryDefaultInstance(entry); return entry; } @@ -358,7 +363,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename KeyNested, typename ValueNested, FieldDescriptor::Type KeyProtoNested, FieldDescriptor::Type ValueProtoNested, int default_enum> - class LIBPROTOBUF_EXPORT MapEntryWrapper + class MapEntryWrapper : public MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, default_enum> { typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, @@ -389,7 +394,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename KeyNested, typename ValueNested, FieldDescriptor::Type KeyProtoNested, FieldDescriptor::Type ValueProtoNested, int default_enum> - class LIBPROTOBUF_EXPORT MapEnumEntryWrapper + class MapEnumEntryWrapper : public MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, default_enum> { typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested, @@ -428,7 +433,7 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { template <typename K, typename V, FieldDescriptor::Type KType, FieldDescriptor::Type VType, int default_enum> - friend class LIBPROTOBUF_EXPORT internal::MapField; + friend class internal::MapField; friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 74431628..b535ec28 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -30,10 +30,37 @@ #include <google/protobuf/map_field.h> +#include <vector> + namespace google { namespace protobuf { namespace internal { +ProtobufOnceType map_entry_default_instances_once_; +Mutex* map_entry_default_instances_mutex_; +vector<MessageLite*>* map_entry_default_instances_; + +void DeleteMapEntryDefaultInstances() { + for (int i = 0; i < map_entry_default_instances_->size(); ++i) { + delete map_entry_default_instances_->at(i); + } + delete map_entry_default_instances_mutex_; + delete map_entry_default_instances_; +} + +void InitMapEntryDefaultInstances() { + map_entry_default_instances_mutex_ = new Mutex(); + map_entry_default_instances_ = new vector<MessageLite*>(); + OnShutdown(&DeleteMapEntryDefaultInstances); +} + +void RegisterMapEntryDefaultInstance(MessageLite* default_instance) { + GoogleOnceInit(&map_entry_default_instances_once_, + &InitMapEntryDefaultInstances); + MutexLock lock(map_entry_default_instances_mutex_); + map_entry_default_instances_->push_back(default_instance); +} + MapFieldBase::~MapFieldBase() { if (repeated_field_ != NULL) delete repeated_field_; } diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 0fad1351..8516d74e 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -137,7 +137,7 @@ class LIBPROTOBUF_EXPORT MapFieldBase { template<typename Key, typename T, FieldDescriptor::Type KeyProto, FieldDescriptor::Type ValueProto, int default_enum_value = 0> -class LIBPROTOBUF_EXPORT MapField : public MapFieldBase { +class MapField : public MapFieldBase { // Handlers for key/value's proto field type. typedef MapProtoTypeHandler<KeyProto> KeyProtoHandler; typedef MapProtoTypeHandler<ValueProto> ValueProtoHandler; diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 98551839..045f8f2c 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -430,41 +430,6 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } -class MapFieldBaseStateStub : public MapFieldBaseStub { - public: - MapFieldBaseStateStub(Mutex* mutex, int* clean_counter, - int* completed_counter) - : mutex_(mutex), - clean_counter_(clean_counter), - completed_counter_(completed_counter) {} - ~MapFieldBaseStateStub() {} - - protected: - void SyncRepeatedFieldWithMapNoLock() const { Clean(); } - void SyncMapWithRepeatedFieldNoLock() const { Clean(); } - - private: - void Clean() const { - { - MutexLock lock(mutex_); - ++(*clean_counter_); - } - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = 100000000; // 100ms - nanosleep(&tm, NULL); - { - MutexLock lock(mutex_); - // No other thread should have completed while this one was initializing. - EXPECT_EQ(0, *completed_counter_); - } - } - Mutex* mutex_; - int* clean_counter_; - int* completed_counter_; -}; - - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index c680ccb2..9db67523 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -190,6 +190,7 @@ TEST_F(MapImplTest, MutableAt) { ExpectSingleElement(key, value2); } +#ifdef PROTOBUF_HAS_DEATH_TEST TEST_F(MapImplTest, MutableAtNonExistDeathTest) { EXPECT_DEATH(map_.at(0), ""); } @@ -197,6 +198,7 @@ TEST_F(MapImplTest, MutableAtNonExistDeathTest) { TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { EXPECT_DEATH(const_map_.at(0), ""); } +#endif // PROTOBUF_HAS_DEATH_TEST TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc index b27c8f19..eb7ea511 100644 --- a/src/google/protobuf/map_test_util.cc +++ b/src/google/protobuf/map_test_util.cc @@ -1020,7 +1020,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_int32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_int32_int32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1034,7 +1034,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int64_int64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_int64_int64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1048,7 +1048,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_uint32_uint32_key_); uint32 val = sub_message->GetReflection()->GetUInt32( *sub_message, map_uint32_uint32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1062,7 +1062,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_uint64_uint64_key_); uint64 val = sub_message->GetReflection()->GetUInt64( *sub_message, map_uint64_uint64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1076,7 +1076,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sint32_sint32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_sint32_sint32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1090,7 +1090,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sint64_sint64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_sint64_sint64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1104,7 +1104,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_fixed32_fixed32_key_); uint32 val = sub_message->GetReflection()->GetUInt32( *sub_message, map_fixed32_fixed32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1118,7 +1118,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_fixed64_fixed64_key_); uint64 val = sub_message->GetReflection()->GetUInt64( *sub_message, map_fixed64_fixed64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1132,7 +1132,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sfixed32_sfixed32_key_); int32 val = sub_message->GetReflection()->GetInt32( *sub_message, map_sfixed32_sfixed32_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1146,7 +1146,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_sfixed64_sfixed64_key_); int64 val = sub_message->GetReflection()->GetInt64( *sub_message, map_sfixed64_sfixed64_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1160,7 +1160,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_float_key_); float val = sub_message->GetReflection()->GetFloat( *sub_message, map_int32_float_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1174,7 +1174,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_double_key_); double val = sub_message->GetReflection()->GetDouble( *sub_message, map_int32_double_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1188,7 +1188,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_bool_bool_key_); bool val = sub_message->GetReflection()->GetBool( *sub_message, map_bool_bool_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1202,7 +1202,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_string_string_key_); string val = sub_message->GetReflection()->GetString( *sub_message, map_string_string_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1216,7 +1216,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_bytes_key_); string val = sub_message->GetReflection()->GetString( *sub_message, map_int32_bytes_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1230,7 +1230,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_enum_key_); const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum( *sub_message, map_int32_enum_val_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } { @@ -1246,7 +1246,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection( *sub_message, map_int32_foreign_message_val_); int32 val = foreign_message.GetReflection()->GetInt32( foreign_message, foreign_c_); - EXPECT_EQ(map.at(key), val); + EXPECT_EQ(map[key], val); } } } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 1d8f2499..a200bc92 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -967,6 +967,7 @@ const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \ const Message& message, const FieldDescriptor* field) const; \ \ template<> \ +LIBPROTOBUF_EXPORT \ RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \ Message* message, const FieldDescriptor* field) const; diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc index 33e9ea10..816e52ca 100644 --- a/src/google/protobuf/preserve_unknown_enum_test.cc +++ b/src/google/protobuf/preserve_unknown_enum_test.cc @@ -200,6 +200,7 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { EXPECT_TRUE(enum_value != NULL); r->AddEnum(&message, repeated_field, enum_value); +#ifdef PROTOBUF_HAS_DEATH_TEST // Enum-field integer-based setters GOOGLE_DCHECK-fail on invalid values, in order to // remain consistent with proto2 generated code. EXPECT_DEBUG_DEATH({ @@ -214,6 +215,7 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { r->AddEnumValue(&message, repeated_field, 4242); r->GetRepeatedEnum(message, repeated_field, 1); }, "AddEnumValue accepts only valid integer values"); +#endif // PROTOBUF_HAS_DEATH_TEST } TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index e14dcc62..4798eeda 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -236,10 +236,11 @@ class RepeatedField { Arena* arena; Element elements[1]; }; - // Why not sizeof(Rep) - sizeof(Element)? Because this is not accurate w.r.t. - // trailing padding on the struct -- e.g. if Element is int, this would yield - // 12 on x86-64, not 8 as we want. - static const size_t kRepHeaderSize = sizeof(Arena*); + // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on + // the struct. We can not use sizeof(Arena*) as well because there might be + // a "gap" after the field arena and before the field elements (e.g., when + // Element is double and pointer is 32bit). + static const size_t kRepHeaderSize; // Contains arena ptr and the elements array. We also keep the invariant that // if rep_ is NULL, then arena is NULL. Rep* rep_; @@ -263,6 +264,10 @@ class RepeatedField { } }; +template<typename Element> +const size_t RepeatedField<Element>::kRepHeaderSize = + reinterpret_cast<size_t>(&reinterpret_cast<Rep*>(16)->elements[0]) - 16; + namespace internal { template <typename It> class RepeatedPtrIterator; template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator; diff --git a/src/google/protobuf/repeated_field_reflection.h b/src/google/protobuf/repeated_field_reflection.h index 42f7be20..44d14d5b 100644 --- a/src/google/protobuf/repeated_field_reflection.h +++ b/src/google/protobuf/repeated_field_reflection.h @@ -38,6 +38,8 @@ #include <google/protobuf/stubs/shared_ptr.h> #endif +#include <google/protobuf/generated_enum_reflection.h> + namespace google { namespace protobuf { namespace internal { @@ -273,7 +275,7 @@ struct RefTypeTraits< template<typename T> struct RefTypeTraits< - T, typename internal::enable_if<internal::is_enum<T>::value>::type> { + T, typename internal::enable_if<is_proto_enum<T>::value>::type> { typedef RepeatedFieldRefIterator<T> iterator; typedef RepeatedFieldAccessor AccessorType; // We use int32 for repeated enums in RepeatedFieldAccessor. diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index ae43dfab..8b821806 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -196,8 +196,7 @@ void TestRepeatedFieldRefIterator( int index = 0; for (typename Ref::const_iterator it = handle.begin(); it != handle.end(); ++it) { - ValueType value = static_cast<ValueType>(*it); - EXPECT_EQ((message.*GetFunc)(index), value); + EXPECT_EQ((message.*GetFunc)(index), *it); ++index; } EXPECT_EQ(handle.size(), index); @@ -410,6 +409,7 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { EXPECT_TRUE(rf_message.empty()); EXPECT_TRUE(mrf_message.empty()); +#ifdef PROTOBUF_HAS_DEATH_TEST // Make sure types are checked correctly at runtime. const FieldDescriptor* fd_optional_int32 = desc->FindFieldByName("optional_int32"); @@ -419,6 +419,7 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { message, fd_repeated_int32), ""); EXPECT_DEATH(refl->GetRepeatedFieldRef<TestAllTypes>( message, fd_repeated_foreign_message), ""); +#endif // PROTOBUF_HAS_DEATH_TEST } TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) { diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 9942af50..15c0c93e 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -92,8 +92,8 @@ TEST(RepeatedField, Small) { EXPECT_TRUE(field.empty()); EXPECT_EQ(field.size(), 0); - // Additional 8 bytes are for 'struct Rep' header. - int expected_usage = 4 * sizeof(int) + 8; + // Additional bytes are for 'struct Rep' header. + int expected_usage = 4 * sizeof(int) + sizeof(Arena*); EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage); } diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index c0cfd414..c3f735a2 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -113,24 +113,24 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2006002 +#define GOOGLE_PROTOBUF_VERSION 3000000 // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3000000 // 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 = 2006000; +static const int kMinHeaderVersionForLibrary = 3000000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3000000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2006000; +static const int kMinHeaderVersionForProtoc = 3000000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -314,6 +314,12 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { } #endif +#if defined(_MSC_VER) +#define GOOGLE_THREAD_LOCAL __declspec(thread) +#else +#define GOOGLE_THREAD_LOCAL __thread +#endif + // =================================================================== // from google3/base/basictypes.h diff --git a/src/google/protobuf/stubs/fastmem.h b/src/google/protobuf/stubs/fastmem.h index e553f142..763a6e60 100644 --- a/src/google/protobuf/stubs/fastmem.h +++ b/src/google/protobuf/stubs/fastmem.h @@ -46,7 +46,6 @@ #define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ #include <stddef.h> -#include <stdint.h> #include <stdio.h> #include <string.h> diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h index f5365c38..b58cae3f 100644 --- a/src/google/protobuf/stubs/type_traits.h +++ b/src/google/protobuf/stubs/type_traits.h @@ -103,7 +103,7 @@ template <class T> struct remove_reference; template <class T> struct add_reference; template <class T> struct remove_pointer; template <class T, class U> struct is_same; -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) template <class From, class To> struct is_convertible; #endif @@ -322,7 +322,7 @@ template<typename T, typename U> struct is_same : public false_type { }; template<typename T> struct is_same<T, T> : public true_type { }; // Specified by TR1 [4.6] Relationships between types -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) namespace type_traits_internal { // This class is an implementation detail for is_convertible, and you @@ -339,6 +339,9 @@ struct ConvertHelper { static small_ Test(To); static big_ Test(...); static From Create(); + enum { + value = sizeof(Test(Create())) == sizeof(small_) + }; }; } // namespace type_traits_internal @@ -346,9 +349,7 @@ struct ConvertHelper { template <typename From, typename To> struct is_convertible : integral_constant<bool, - sizeof(type_traits_internal::ConvertHelper<From, To>::Test( - type_traits_internal::ConvertHelper<From, To>::Create())) - == sizeof(small_)> { + type_traits_internal::ConvertHelper<From, To>::value> { }; #endif diff --git a/src/google/protobuf/stubs/type_traits_unittest.cc b/src/google/protobuf/stubs/type_traits_unittest.cc index b42b9e83..49c10ace 100644 --- a/src/google/protobuf/stubs/type_traits_unittest.cc +++ b/src/google/protobuf/stubs/type_traits_unittest.cc @@ -610,7 +610,7 @@ TEST(TypeTraitsTest, TestIsSame) { } TEST(TypeTraitsTest, TestConvertible) { -#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) +#if !(defined(__GNUC__) && __GNUC__ <= 3) EXPECT_TRUE((is_convertible<int, int>::value)); EXPECT_TRUE((is_convertible<int, long>::value)); EXPECT_TRUE((is_convertible<long, int>::value)); diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc index 6bba8fc7..9b02f0b0 100644 --- a/src/google/protobuf/unknown_field_set_unittest.cc +++ b/src/google/protobuf/unknown_field_set_unittest.cc @@ -485,7 +485,7 @@ TEST_F(UnknownFieldSetTest, UnknownEnumValue) { TEST_F(UnknownFieldSetTest, SpaceUsedExcludingSelf) { UnknownFieldSet empty; empty.AddVarint(1, 0); - EXPECT_EQ(/* vector<UnknownField> */ 24 + /* sizeof(UnknownField) */ 16, + EXPECT_EQ(sizeof(vector<UnknownField>) + sizeof(UnknownField), empty.SpaceUsedExcludingSelf()); } |