aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am11
-rw-r--r--src/google/protobuf/arena.cc21
-rw-r--r--src/google/protobuf/arena.h11
-rw-r--r--src/google/protobuf/arena_unittest.cc12
-rwxr-xr-xsrc/google/protobuf/arenastring.h3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc2
-rw-r--r--src/google/protobuf/compiler/main.cc7
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h4
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator.cc313
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator.h57
-rw-r--r--src/google/protobuf/descriptor.cc5
-rw-r--r--src/google/protobuf/descriptor.pb.h4
-rw-r--r--src/google/protobuf/map.h6
-rw-r--r--src/google/protobuf/map_entry.h13
-rw-r--r--src/google/protobuf/map_field.cc27
-rw-r--r--src/google/protobuf/map_field.h2
-rw-r--r--src/google/protobuf/map_field_test.cc35
-rw-r--r--src/google/protobuf/map_test.cc2
-rw-r--r--src/google/protobuf/map_test_util.cc34
-rw-r--r--src/google/protobuf/message.h1
-rw-r--r--src/google/protobuf/preserve_unknown_enum_test.cc2
-rw-r--r--src/google/protobuf/repeated_field.h13
-rw-r--r--src/google/protobuf/repeated_field_reflection.h4
-rw-r--r--src/google/protobuf/repeated_field_reflection_unittest.cc5
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc4
-rw-r--r--src/google/protobuf/stubs/common.h16
-rw-r--r--src/google/protobuf/stubs/fastmem.h1
-rw-r--r--src/google/protobuf/stubs/type_traits.h11
-rw-r--r--src/google/protobuf/stubs/type_traits_unittest.cc2
-rw-r--r--src/google/protobuf/unknown_field_set_unittest.cc2
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());
}