Merge remote-tracking branch 'upstream/master'

pull/88/head
Tres Seaver 10 years ago
commit 0eb74768d0
  1. 34
      java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
  2. 2
      java/src/main/java/com/google/protobuf/MapEntry.java
  3. 2
      java/src/main/java/com/google/protobuf/MapField.java
  4. 14
      java/src/test/java/com/google/protobuf/MapForProto2Test.java
  5. 5
      java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto
  6. 5
      java/src/test/java/com/google/protobuf/map_for_proto2_test.proto
  7. 2
      python/google/protobuf/internal/generator_test.py
  8. 6
      python/google/protobuf/internal/test_bad_identifiers.proto
  9. 36
      python/google/protobuf/text_format.py
  10. 22
      src/Makefile.am
  11. 2
      src/google/protobuf/arena.cc
  12. 41
      src/google/protobuf/arena_unittest.cc
  13. 10
      src/google/protobuf/arenastring.cc
  14. 2
      src/google/protobuf/arenastring.h
  15. 6
      src/google/protobuf/compiler/command_line_interface.cc
  16. 6
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  17. 4
      src/google/protobuf/compiler/cpp/cpp_enum.cc
  18. 18
      src/google/protobuf/compiler/cpp/cpp_field.cc
  19. 2
      src/google/protobuf/compiler/cpp/cpp_field.h
  20. 27
      src/google/protobuf/compiler/cpp/cpp_file.cc
  21. 8
      src/google/protobuf/compiler/cpp/cpp_file.h
  22. 4
      src/google/protobuf/compiler/cpp/cpp_generator.cc
  23. 19
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  24. 10
      src/google/protobuf/compiler/cpp/cpp_helpers.h
  25. 255
      src/google/protobuf/compiler/cpp/cpp_map_field.cc
  26. 75
      src/google/protobuf/compiler/cpp/cpp_map_field.h
  27. 110
      src/google/protobuf/compiler/cpp/cpp_message.cc
  28. 6
      src/google/protobuf/compiler/cpp/cpp_message.h
  29. 14
      src/google/protobuf/compiler/cpp/cpp_message_field.cc
  30. 2
      src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
  31. 7
      src/google/protobuf/compiler/cpp/cpp_string_field.cc
  32. 16
      src/google/protobuf/compiler/cpp/cpp_unittest.cc
  33. 6
      src/google/protobuf/compiler/importer.cc
  34. 6
      src/google/protobuf/compiler/importer_unittest.cc
  35. 2
      src/google/protobuf/compiler/java/java_context.h
  36. 2
      src/google/protobuf/compiler/java/java_field.cc
  37. 2
      src/google/protobuf/compiler/java/java_field.h
  38. 14
      src/google/protobuf/compiler/java/java_file.cc
  39. 8
      src/google/protobuf/compiler/java/java_file.h
  40. 4
      src/google/protobuf/compiler/java/java_generator.cc
  41. 93
      src/google/protobuf/compiler/java/java_message.cc
  42. 2
      src/google/protobuf/compiler/java/java_plugin_unittest.cc
  43. 4
      src/google/protobuf/compiler/java/java_shared_code_generator.cc
  44. 2
      src/google/protobuf/compiler/java/java_shared_code_generator.h
  45. 6
      src/google/protobuf/compiler/mock_code_generator.cc
  46. 6
      src/google/protobuf/compiler/parser_unittest.cc
  47. 188
      src/google/protobuf/compiler/plugin.pb.cc
  48. 265
      src/google/protobuf/compiler/plugin.pb.h
  49. 49
      src/google/protobuf/compiler/python/python_generator.cc
  50. 2
      src/google/protobuf/compiler/python/python_plugin_unittest.cc
  51. 13
      src/google/protobuf/descriptor.cc
  52. 4
      src/google/protobuf/descriptor.h
  53. 1409
      src/google/protobuf/descriptor.pb.cc
  54. 1796
      src/google/protobuf/descriptor.pb.h
  55. 5
      src/google/protobuf/descriptor.proto
  56. 42
      src/google/protobuf/descriptor_unittest.cc
  57. 2
      src/google/protobuf/drop_unknown_fields_test.cc
  58. 25
      src/google/protobuf/dynamic_message.cc
  59. 2
      src/google/protobuf/dynamic_message.h
  60. 2
      src/google/protobuf/extension_set_unittest.cc
  61. 151
      src/google/protobuf/generated_message_reflection.cc
  62. 26
      src/google/protobuf/generated_message_reflection.h
  63. 1
      src/google/protobuf/generated_message_util.cc
  64. 282
      src/google/protobuf/map.h
  65. 449
      src/google/protobuf/map_entry.h
  66. 113
      src/google/protobuf/map_field.cc
  67. 220
      src/google/protobuf/map_field.h
  68. 269
      src/google/protobuf/map_field_inl.h
  69. 470
      src/google/protobuf/map_field_test.cc
  70. 39
      src/google/protobuf/map_lite_unittest.proto
  71. 68
      src/google/protobuf/map_proto2_unittest.proto
  72. 2143
      src/google/protobuf/map_test.cc
  73. 1479
      src/google/protobuf/map_test_util.cc
  74. 149
      src/google/protobuf/map_test_util.h
  75. 486
      src/google/protobuf/map_type_handler.h
  76. 77
      src/google/protobuf/map_unittest.proto
  77. 4
      src/google/protobuf/message.cc
  78. 2
      src/google/protobuf/preserve_unknown_enum_test.cc
  79. 2
      src/google/protobuf/proto3_arena_unittest.cc
  80. 68
      src/google/protobuf/reflection_internal.h
  81. 7
      src/google/protobuf/repeated_field.h
  82. 2
      src/google/protobuf/repeated_field_reflection.h
  83. 2
      src/google/protobuf/repeated_field_reflection_unittest.cc
  84. 2
      src/google/protobuf/stubs/common.h
  85. 2
      src/google/protobuf/text_format.h
  86. 1
      src/google/protobuf/unittest.proto
  87. 1
      src/google/protobuf/unittest_arena.proto
  88. 1
      src/google/protobuf/unittest_import.proto
  89. 1
      src/google/protobuf/unittest_mset.proto
  90. 1
      src/google/protobuf/unittest_no_arena.proto
  91. 1
      src/google/protobuf/unittest_proto3_arena.proto

@ -81,22 +81,18 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite
return unknownFields.mergeFieldFrom(tag, input);
}
/**
* Used by parsing constructors in generated classes.
*/
protected void makeExtensionsImmutable() {
// Noop for messages without extensions.
}
@SuppressWarnings("unchecked")
public abstract static class Builder<MessageType extends GeneratedMessageLite,
BuilderType extends Builder>
extends AbstractMessageLite.Builder<BuilderType> {
private final MessageType defaultInstance;
private UnknownFieldSetLite unknownFields =
UnknownFieldSetLite.getDefaultInstance();
protected Builder() {}
protected Builder(MessageType defaultInstance) {
this.defaultInstance = defaultInstance;
}
//@Override (Java 1.6 override semantics, but we must support 1.5)
public BuilderType clear() {
@ -115,11 +111,21 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite
/** All subclasses implement this. */
public abstract MessageType buildPartial();
//@Override (Java 1.6 override semantics, but we must support 1.5)
public final MessageType build() {
MessageType result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
/** All subclasses implement this. */
public abstract BuilderType mergeFrom(MessageType message);
// Defined here for return type covariance.
public abstract MessageType getDefaultInstanceForType();
public MessageType getDefaultInstanceForType() {
return defaultInstance;
}
/**
* Called by subclasses to parse an unknown field.
@ -288,8 +294,8 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite
/**
* Used by parsing constructors in generated classes.
*/
@Override
protected void makeExtensionsImmutable() {
protected static void makeExtensionsImmutable(
FieldSet<ExtensionDescriptor> extensions) {
extensions.makeImmutable();
}
@ -361,7 +367,9 @@ public abstract class GeneratedMessageLite extends AbstractMessageLite
BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
extends Builder<MessageType, BuilderType>
implements ExtendableMessageOrBuilder<MessageType> {
protected ExtendableBuilder() {}
protected ExtendableBuilder(MessageType defaultInstance) {
super(defaultInstance);
}
private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
private boolean extensionsIsMutable;

@ -282,7 +282,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public MapEntry<K, V> buildPartial() {
if (dataBuilder != null) {
data = dataBuilder.build();
data = dataBuilder.buildPartial();
dataBuilder = null;
}
return new MapEntry<K, V>(metadata, data);

@ -91,7 +91,7 @@ public class MapField<K, V> {
}
public Message convertKeyAndValueToMessage(K key, V value) {
return defaultEntry.newBuilderForType().setKey(key).setValue(value).build();
return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
}
public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {

@ -33,6 +33,7 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.FieldDescriptor;
import map_test.MapForProto2TestProto.TestMap;
import map_test.MapForProto2TestProto.TestMap.MessageValue;
import map_test.MapForProto2TestProto.TestMap.MessageWithRequiredFields;
import map_test.MapForProto2TestProto.TestUnknownEnumValue;
import junit.framework.TestCase;
@ -485,4 +486,17 @@ public class MapForProto2Test extends TestCase {
assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
}
public void testRequiredMessage() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
builder.getMutableRequiredMessageMap().put(0,
MessageWithRequiredFields.newBuilder().buildPartial());
TestMap message = builder.buildPartial();
assertFalse(message.isInitialized());
builder.getMutableRequiredMessageMap().put(0,
MessageWithRequiredFields.newBuilder().setValue(1).build());
message = builder.build();
assertTrue(message.isInitialized());
}
}

@ -51,6 +51,11 @@ message TestMap {
map<int32, EnumValue> int32_to_enum_field = 4;
map<int32, MessageValue> int32_to_message_field = 5;
map<string, int32> string_to_int32_field = 6;
message MessageWithRequiredFields {
required int32 value = 1;
}
map<int32, MessageWithRequiredFields> required_message_map = 11;
}
message TestUnknownEnumValue {

@ -53,6 +53,11 @@ message TestMap {
map<int32, EnumValue> int32_to_enum_field = 4;
map<int32, MessageValue> int32_to_message_field = 5;
map<string, int32> string_to_int32_field = 6;
message MessageWithRequiredFields {
required int32 value = 1;
}
map<int32, MessageWithRequiredFields> required_message_map = 11;
}
message TestUnknownEnumValue {

@ -281,8 +281,6 @@ class GeneratorTest(basetest.TestCase):
"baz")
self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
"qux")
self.assertEqual(message.Extensions[test_bad_identifiers_pb2.class_],
"Foo")
def testOneof(self):
desc = unittest_pb2.TestAllTypes.DESCRIPTOR

@ -40,15 +40,13 @@ message TestBadIdentifiers {
extensions 100 to max;
}
// Make sure these reasonable extension names don't conflict with internal
// variables.
extend TestBadIdentifiers {
// Make sure these reasonable extension names don't conflict with internal
// variables.
optional string message = 100 [default="foo"];
optional string descriptor = 101 [default="bar"];
optional string reflection = 102 [default="baz"];
optional string service = 103 [default="qux"];
// And Python keywords.
optional string class = 104 [default="Foo"];
}
message AnotherMessage {}

@ -217,24 +217,6 @@ def PrintFieldValue(field, value, out, indent=0, as_utf8=False,
out.write(str(value))
def _ParseOrMerge(lines, message, allow_multiple_scalars):
"""Converts an ASCII representation of a protocol message into a message.
Args:
lines: Lines of a message's ASCII representation.
message: A protocol buffer message to merge into.
allow_multiple_scalars: Determines if repeated values for a non-repeated
field are permitted, e.g., the string "foo: 1 foo: 2" for a
required/optional field named "foo".
Raises:
ParseError: On ASCII parsing problems.
"""
tokenizer = _Tokenizer(lines)
while not tokenizer.AtEnd():
_MergeField(tokenizer, message, allow_multiple_scalars)
def Parse(text, message):
"""Parses an ASCII representation of a protocol message into a message.
@ -305,6 +287,24 @@ def MergeLines(lines, message):
return message
def _ParseOrMerge(lines, message, allow_multiple_scalars):
"""Converts an ASCII representation of a protocol message into a message.
Args:
lines: Lines of a message's ASCII representation.
message: A protocol buffer message to merge into.
allow_multiple_scalars: Determines if repeated values for a non-repeated
field are permitted, e.g., the string "foo: 1 foo: 2" for a
required/optional field named "foo".
Raises:
ParseError: On ASCII parsing problems.
"""
tokenizer = _Tokenizer(lines)
while not tokenizer.AtEnd():
_MergeField(tokenizer, message, allow_multiple_scalars)
def _MergeField(tokenizer, message, allow_multiple_scalars):
"""Merges a single protocol message field into a message.

@ -40,6 +40,7 @@ MAINTAINERCLEANFILES = \
nobase_include_HEADERS = \
google/protobuf/stubs/atomic_sequence_num.h \
google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_aix.h \
google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
@ -71,6 +72,11 @@ nobase_include_HEADERS = \
google/protobuf/generated_enum_reflection.h \
google/protobuf/generated_message_reflection.h \
google/protobuf/generated_message_util.h \
google/protobuf/map_entry.h \
google/protobuf/map_field.h \
google/protobuf/map_field_inl.h \
google/protobuf/map.h \
google/protobuf/map_type_handler.h \
google/protobuf/message.h \
google/protobuf/message_lite.h \
google/protobuf/metadata.h \
@ -120,6 +126,7 @@ 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 \
@ -182,6 +189,8 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/cpp/cpp_generator.cc \
google/protobuf/compiler/cpp/cpp_helpers.cc \
google/protobuf/compiler/cpp/cpp_helpers.h \
google/protobuf/compiler/cpp/cpp_map_field.cc \
google/protobuf/compiler/cpp/cpp_map_field.h \
google/protobuf/compiler/cpp/cpp_message.cc \
google/protobuf/compiler/cpp/cpp_message.h \
google/protobuf/compiler/cpp/cpp_message_field.cc \
@ -239,6 +248,9 @@ protoc_SOURCES = google/protobuf/compiler/main.cc
# Tests ==============================================================
protoc_inputs = \
google/protobuf/map_lite_unittest.proto \
google/protobuf/map_proto2_unittest.proto \
google/protobuf/map_unittest.proto \
google/protobuf/unittest.proto \
google/protobuf/unittest_arena.proto \
google/protobuf/unittest_custom_options.proto \
@ -292,6 +304,12 @@ protoc_lite_outputs = \
protoc_outputs = \
$(protoc_lite_outputs) \
google/protobuf/map_lite_unittest.pb.cc \
google/protobuf/map_lite_unittest.pb.h \
google/protobuf/map_proto2_unittest.pb.cc \
google/protobuf/map_proto2_unittest.pb.h \
google/protobuf/map_unittest.pb.cc \
google/protobuf/map_unittest.pb.h \
google/protobuf/unittest.pb.cc \
google/protobuf/unittest.pb.h \
google/protobuf/unittest_arena.pb.cc \
@ -351,6 +369,8 @@ endif
$(protoc_outputs): unittest_proto_middleman
COMMON_TEST_SOURCES = \
google/protobuf/map_test_util.cc \
google/protobuf/map_test_util.h \
google/protobuf/test_util.cc \
google/protobuf/test_util.h \
google/protobuf/testing/googletest.cc \
@ -385,6 +405,8 @@ protobuf_test_SOURCES = \
google/protobuf/dynamic_message_unittest.cc \
google/protobuf/extension_set_unittest.cc \
google/protobuf/generated_message_reflection_unittest.cc \
google/protobuf/map_field_test.cc \
google/protobuf/map_test.cc \
google/protobuf/message_unittest.cc \
google/protobuf/no_field_presence_test.cc \
google/protobuf/preserve_unknown_enum_test.cc \

@ -138,7 +138,7 @@ void* Arena::AllocateAligned(size_t n) {
// for this thread.
if (!owns_first_block_ && b->next == NULL) {
MutexLock l(&blocks_lock_);
if (b->owner == &b->owner) {
if (b->owner == &b->owner && b->avail() >= n) {
b->owner = me;
SetThreadCacheBlock(b);
return AllocFromBlock(b, n);

@ -30,14 +30,26 @@
#include <google/protobuf/arena.h>
#include <algorithm>
#include <cstring>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_arena.pb.h>
#include <google/protobuf/unittest_no_arena.pb.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/message.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/unknown_field_set.h>
#include <gtest/gtest.h>
@ -110,6 +122,31 @@ TEST(ArenaTest, BasicCreate) {
EXPECT_EQ(2, notifier.GetCount());
}
TEST(ArenaTest, InitialBlockTooSmall) {
// Construct a small (64 byte) initial block of memory to be used by the
// arena allocator; then, allocate an object which will not fit in the
// initial block.
std::vector<char> arena_block(64);
ArenaOptions options;
options.initial_block = arena_block.data();
options.initial_block_size = arena_block.size();
Arena arena(options);
char* p = ::google::protobuf::Arena::CreateArray<char>(&arena, 96);
uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
// 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_end = arena_start + arena_block.size();
EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
// Write to the memory we allocated; this should (but is not guaranteed to)
// trigger a check for heap corruption if the object was allocated from the
// initially-provided block.
memset(p, '\0', 128);
}
TEST(ArenaTest, Parsing) {
TestAllTypes original;
TestUtil::SetAllFields(&original);

@ -38,6 +38,16 @@ namespace protobuf {
namespace internal {
void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
ArenaStringPtr value) {
const ::std::string* me = *UnsafeRawStringPointer();
const ::std::string* other = *value.UnsafeRawStringPointer();
// If the pointers are the same then do nothing.
if (me != other) {
SetNoArena(default_value, value.GetNoArena(default_value));
}
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -214,6 +214,8 @@ struct ArenaStringPtr {
}
}
void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
inline const ::std::string& GetNoArena(const ::std::string* default_value) const {
return *ptr_;
}

@ -300,7 +300,7 @@ class CommandLineInterface::MemoryOutputStream
bool append_mode_;
// StringOutputStream writing to data_.
scoped_ptr<io::StringOutputStream> inner_;
google::protobuf::scoped_ptr<io::StringOutputStream> inner_;
};
// -------------------------------------------------------------------
@ -1321,7 +1321,7 @@ bool CommandLineInterface::GeneratePluginOutput(
// Write the files. We do this even if there was a generator error in order
// to match the behavior of a compiled-in generator.
scoped_ptr<io::ZeroCopyOutputStream> current_output;
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> current_output;
for (int i = 0; i < response.file_size(); i++) {
const CodeGeneratorResponse::File& output_file = response.file(i);
@ -1370,7 +1370,7 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
}
DynamicMessageFactory dynamic_factory(pool);
scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
google::protobuf::scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
if (mode_ == MODE_ENCODE) {
SetFdToTextMode(STDIN_FILENO);

@ -261,7 +261,7 @@ void CommandLineInterfaceTest::SetUp() {
void CommandLineInterfaceTest::TearDown() {
// Delete the temp directory.
if (File::Exists(temp_directory_)) {
if (FileExists(temp_directory_)) {
File::DeleteRecursively(temp_directory_, NULL, NULL);
}
@ -312,7 +312,7 @@ void CommandLineInterfaceTest::Run(const string& command) {
}
}
scoped_array<const char*> argv(new const char* [args.size()]);
google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
@ -1550,7 +1550,7 @@ class EncodeDecodeTest : public testing::Test {
SplitStringUsing(command, " ", &args);
args.push_back("--proto_path=" + TestSourceDir());
scoped_array<const char*> argv(new const char* [args.size()]);
google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]);
for (int i = 0; i < args.size(); i++) {
argv[i] = args[i].c_str();
}

@ -106,8 +106,8 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
// INT32_MIN and INT32_MAX
if (descriptor_->value_count() > 0) printer->Print(",\n");
printer->Print(vars,
"$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = INT32_MIN,\n"
"$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = INT32_MAX");
"$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,\n"
"$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max");
}
printer->Outdent();

@ -42,6 +42,7 @@
#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
#include <google/protobuf/compiler/cpp/cpp_string_field.h>
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
@ -65,6 +66,12 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["classname"] = ClassName(FieldScope(descriptor), false);
(*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
// non_null_ptr_to_name is usable only if has_$name$ is true. It yields a
// pointer that will not be NULL. Subclasses of FieldGenerator may set
// (*variables)["non_null_ptr_to_name"] differently.
(*variables)["non_null_ptr_to_name"] =
StrCat("&this->", FieldName(descriptor), "()");
(*variables)["tag_size"] = SimpleItoa(
WireFormat::TagSize(descriptor->number(), descriptor->type()));
(*variables)["deprecation"] = descriptor->options().deprecated()
@ -89,8 +96,11 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
(*variables)["oneof_prefix"] = descriptor->containing_oneof()->name() + "_.";
const string prefix = descriptor->containing_oneof()->name() + "_.";
(*variables)["oneof_prefix"] = prefix;
(*variables)["oneof_name"] = descriptor->containing_oneof()->name();
(*variables)["non_null_ptr_to_name"] =
StrCat(prefix, (*variables)["name"], "_");
}
FieldGenerator::~FieldGenerator() {}
@ -111,7 +121,7 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
const Options& options)
: descriptor_(descriptor),
field_generators_(
new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
new google::protobuf::scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
@ -123,7 +133,11 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
if (field->is_repeated()) {
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
if (field->is_map()) {
return new MapFieldGenerator(field, options);
} else {
return new RepeatedMessageFieldGenerator(field, options);
}
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // RepeatedStringFieldGenerator handles unknown ctypes.

@ -182,7 +182,7 @@ class FieldGeneratorMap {
private:
const Descriptor* descriptor_;
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGenerator> > field_generators_;
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
const Options& options);

@ -59,13 +59,13 @@ namespace cpp {
FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
: file_(file),
message_generators_(
new scoped_ptr<MessageGenerator>[file->message_type_count()]),
new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
enum_generators_(
new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]),
service_generators_(
new scoped_ptr<ServiceGenerator>[file->service_count()]),
new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
extension_generators_(
new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
options_(options) {
for (int i = 0; i < file->message_type_count(); i++) {
@ -105,7 +105,6 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"#define PROTOBUF_$filename_identifier$__INCLUDED\n"
"\n"
"#include <string>\n"
"#include <stdint.h>\n" // INT32_MIN, INT32_MAX
"\n",
"filename", file_->name(),
"filename_identifier", filename_identifier);
@ -151,6 +150,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
printer->Print(
"#include <google/protobuf/repeated_field.h>\n"
"#include <google/protobuf/extension_set.h>\n");
if (HasMapFields(file_)) {
printer->Print(
"#include <google/protobuf/map.h>\n"
"#include <google/protobuf/map_field_inl.h>\n");
}
if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
printer->Print(
@ -396,6 +400,19 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
// Generate classes.
for (int i = 0; i < file_->message_type_count(); i++) {
if (i == 0 && HasGeneratedMethods(file_)) {
printer->Print(
"\n"
"namespace {\n"
"\n"
"static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n"
"static void MergeFromFail(int line) {\n"
" GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n"
"}\n"
"\n"
"} // namespace\n"
"\n");
}
printer->Print("\n");
printer->Print(kThickSeparator);
printer->Print("\n");

@ -82,10 +82,10 @@ class FileGenerator {
const FileDescriptor* file_;
scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
scoped_array<scoped_ptr<ServiceGenerator> > service_generators_;
scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> > service_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_;
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
vector<string> package_parts_;

@ -105,7 +105,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate header.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
file_generator.GenerateHeader(&printer);
@ -113,7 +113,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate cc file.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".cc"));
io::Printer printer(output.get(), '$');
file_generator.GenerateSource(&printer);

@ -453,6 +453,25 @@ void PrintHandlingOptionalStaticInitializers(
}
static bool HasMapFields(const Descriptor* descriptor) {
for (int i = 0; i < descriptor->field_count(); ++i) {
if (descriptor->field(i)->is_map()) {
return true;
}
}
for (int i = 0; i < descriptor->nested_type_count(); ++i) {
if (HasMapFields(descriptor->nested_type(i))) return true;
}
return false;
}
bool HasMapFields(const FileDescriptor* file) {
for (int i = 0; i < file->message_type_count(); ++i) {
if (HasMapFields(file->message_type(i))) return true;
}
return false;
}
static bool HasEnumDefinitions(const Descriptor* message_type) {
if (message_type->enum_type_count() > 0) return true;
for (int i = 0; i < message_type->nested_type_count(); ++i) {

@ -149,6 +149,10 @@ inline bool UseUnknownFieldSet(const FileDescriptor* file) {
}
// Does the file have any map fields, necessitating the file to include
// map_field_inl.h and map.h.
bool HasMapFields(const FileDescriptor* file);
// Does this file have any enum type definitions?
bool HasEnumDefinitions(const FileDescriptor* file);
@ -200,6 +204,10 @@ void PrintHandlingOptionalStaticInitializers(
const char* without_static_init);
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry();
}
// Returns true if the field's CPPTYPE is string or message.
bool IsStringOrMessage(const FieldDescriptor* field);
@ -216,7 +224,7 @@ inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
}
inline bool SupportsArenas(const FileDescriptor* file) {
return true;
return file->options().cc_enable_arenas();
}
inline bool SupportsArenas(const Descriptor* desc) {

@ -0,0 +1,255 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
bool IsProto3Field(const FieldDescriptor* field_descriptor) {
const FileDescriptor* file_descriptor = field_descriptor->file();
return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
}
void SetMessageVariables(const FieldDescriptor* descriptor,
map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
(*variables)["stream_writer"] = (*variables)["declared_type"] +
(HasFastArraySerialization(descriptor->message_type()->file()) ?
"MaybeToArray" :
"");
(*variables)["full_name"] = descriptor->full_name();
const FieldDescriptor* key =
descriptor->message_type()->FindFieldByName("key");
const FieldDescriptor* val =
descriptor->message_type()->FindFieldByName("value");
(*variables)["key_cpp"] = PrimitiveTypeName(key->cpp_type());
switch (val->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
(*variables)["val_cpp"] = FieldMessageTypeName(val);
(*variables)["wrapper"] = "EntryWrapper";
break;
case FieldDescriptor::CPPTYPE_ENUM:
(*variables)["val_cpp"] = ClassName(val->enum_type(), false);
(*variables)["wrapper"] = "EnumEntryWrapper";
break;
default:
(*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type());
(*variables)["wrapper"] = "EntryWrapper";
}
(*variables)["key_type"] =
"::google::protobuf::FieldDescriptor::TYPE_" +
ToUpper(DeclaredTypeMethodName(key->type()));
(*variables)["val_type"] =
"::google::protobuf::FieldDescriptor::TYPE_" +
ToUpper(DeclaredTypeMethodName(val->type()));
(*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
(*variables)["number"] = Int32ToString(descriptor->number());
if (!IsProto3Field(descriptor) &&
val->type() == FieldDescriptor::TYPE_ENUM) {
const EnumValueDescriptor* default_value = val->default_value_enum();
(*variables)["default_enum_value"] = Int32ToString(default_value->number());
} else {
(*variables)["default_enum_value"] = "0";
}
}
MapFieldGenerator::
MapFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: descriptor_(descriptor) {
SetMessageVariables(descriptor, &variables_, options);
}
MapFieldGenerator::~MapFieldGenerator() {}
void MapFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"typedef ::google::protobuf::internal::MapEntry<\n"
" $key_cpp$, $val_cpp$,\n"
" $key_type$,\n"
" $val_type$, $default_enum_value$>\n"
" $map_classname$;\n"
"::google::protobuf::internal::MapField< $key_cpp$, $val_cpp$,"
"$key_type$, $val_type$, $default_enum_value$ > $name$_;\n");
}
void MapFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
" $name$() const$deprecation$;\n"
"inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
" mutable_$name$()$deprecation$;\n");
}
void MapFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
printer->Print(variables_,
"inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
"$classname$::$name$() const {\n"
" // @@protoc_insertion_point(field_map:$full_name$)\n"
" return $name$_.GetMap();\n"
"}\n"
"inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
"$classname$::mutable_$name$() {\n"
" // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
" return $name$_.MutableMap();\n"
"}\n");
}
void MapFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_.Clear();\n");
}
void MapFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
}
void MapFieldGenerator::
GenerateSwappingCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
}
void MapFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
if (HasDescriptorMethods(descriptor_->file())) {
printer->Print(variables_,
"$name$_.SetAssignDescriptorCallback(\n"
" protobuf_AssignDescriptorsOnce);\n"
"$name$_.SetEntryDescriptor(\n"
" &$type$_descriptor_);\n");
}
}
void MapFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
printer->Print(variables_,
"::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n");
if (IsProto3Field(descriptor_) ||
value_field->type() != FieldDescriptor::TYPE_ENUM) {
printer->Print(variables_,
"DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
" input, entry.get()));\n");
switch (value_field->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
printer->Print(variables_,
"(*mutable_$name$())[entry->key()].Swap("
"entry->mutable_value());\n");
break;
case FieldDescriptor::CPPTYPE_ENUM:
printer->Print(variables_,
"(*mutable_$name$())[entry->key()] =\n"
" static_cast<$val_cpp$>(*entry->mutable_value());\n");
break;
default:
printer->Print(variables_,
"(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n");
break;
}
} else {
printer->Print(variables_,
"{\n"
" ::std::string data;\n"
" DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &data));\n"
" DO_(entry->ParseFromString(data));\n"
" if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
" (*mutable_$name$())[entry->key()] =\n"
" static_cast<$val_cpp$>(*entry->mutable_value());\n"
" } else {\n"
" mutable_unknown_fields()->AddLengthDelimited($number$, data);\n"
" }\n"
"}\n");
}
}
void MapFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
"{\n"
" ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
" for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
" it = $name$().begin(); it != $name$().end(); ++it) {\n"
" entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
" ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
" $number$, *entry, output);\n"
" }\n"
"}\n");
}
void MapFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"{\n"
" ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
" for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
" it = $name$().begin(); it != $name$().end(); ++it) {\n"
" entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
" target = ::google::protobuf::internal::WireFormatLite::\n"
" Write$declared_type$NoVirtualToArray(\n"
" $number$, *entry, target);\n"
" }\n"
"}\n");
}
void MapFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ * this->$name$_size();\n"
"{\n"
" ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
" for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
" it = $name$().begin(); it != $name$().end(); ++it) {\n"
" entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
" total_size += ::google::protobuf::internal::WireFormatLite::\n"
" $declared_type$SizeNoVirtual(*entry);\n"
" }\n"
"}\n");
}
} // namespace cpp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,75 @@
// 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_CPP_MAP_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
#include <map>
#include <string>
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
class MapFieldGenerator : public FieldGenerator {
public:
explicit MapFieldGenerator(const FieldDescriptor* descriptor,
const Options& options);
~MapFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GeneratePrivateMembers(io::Printer* printer) const;
void GenerateAccessorDeclarations(io::Printer* printer) const;
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateClearingCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const;
void GenerateMergeFromCodedStream(io::Printer* printer) const;
void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
void GenerateByteSize(io::Printer* printer) const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
};
} // namespace cpp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__

@ -334,6 +334,31 @@ bool HasHasMethod(const FieldDescriptor* field) {
return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
}
// Collects map entry message type information.
void CollectMapInfo(const Descriptor* descriptor,
map<string, string>* variables) {
GOOGLE_CHECK(IsMapEntryMessage(descriptor));
const FieldDescriptor* key = descriptor->FindFieldByName("key");
const FieldDescriptor* val = descriptor->FindFieldByName("value");
(*variables)["key"] = PrimitiveTypeName(key->cpp_type());
switch (val->cpp_type()) {
case FieldDescriptor::CPPTYPE_MESSAGE:
(*variables)["val"] = FieldMessageTypeName(val);
break;
case FieldDescriptor::CPPTYPE_ENUM:
(*variables)["val"] = ClassName(val->enum_type(), false);
break;
default:
(*variables)["val"] = PrimitiveTypeName(val->cpp_type());
}
(*variables)["key_type"] =
"::google::protobuf::FieldDescriptor::TYPE_" +
ToUpper(DeclaredTypeMethodName(key->type()));
(*variables)["val_type"] =
"::google::protobuf::FieldDescriptor::TYPE_" +
ToUpper(DeclaredTypeMethodName(val->type()));
}
// Does the given field have a private (internal helper only) has_$name$()
// method?
bool HasPrivateHasMethod(const FieldDescriptor* field) {
@ -353,11 +378,11 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
classname_(ClassName(descriptor, false)),
options_(options),
field_generators_(descriptor, options),
nested_generators_(new scoped_ptr<
nested_generators_(new google::protobuf::scoped_ptr<
MessageGenerator>[descriptor->nested_type_count()]),
enum_generators_(
new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
extension_generators_(new scoped_ptr<
new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
extension_generators_(new google::protobuf::scoped_ptr<
ExtensionGenerator>[descriptor->extension_count()]) {
for (int i = 0; i < descriptor->nested_type_count(); i++) {
@ -391,6 +416,10 @@ GenerateForwardDeclaration(io::Printer* printer) {
"classname", classname_);
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need forward declaration. Since map entry
// message cannot be a top level class, we just need to avoid calling
// GenerateForwardDeclaration here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateForwardDeclaration(printer);
}
}
@ -622,6 +651,10 @@ static bool CanClearByZeroing(const FieldDescriptor* field) {
void MessageGenerator::
GenerateClassDefinition(io::Printer* printer) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need class definition. Since map entry message
// cannot be a top level class, we just need to avoid calling
// GenerateClassDefinition here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateClassDefinition(printer);
printer->Print("\n");
printer->Print(kThinSeparator);
@ -876,10 +909,12 @@ GenerateClassDefinition(io::Printer* printer) {
// Import all nested message classes into this class's scope with typedefs.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
const Descriptor* nested_type = descriptor_->nested_type(i);
if (!IsMapEntryMessage(nested_type)) {
printer->Print("typedef $nested_full_name$ $nested_name$;\n",
"nested_name", nested_type->name(),
"nested_full_name", ClassName(nested_type, false));
}
}
if (descriptor_->nested_type_count() > 0) {
printer->Print("\n");
@ -1124,6 +1159,10 @@ GenerateClassDefinition(io::Printer* printer) {
void MessageGenerator::
GenerateInlineMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need inline methods. Since map entry message
// cannot be a top level class, we just need to avoid calling
// GenerateInlineMethods here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateInlineMethods(printer);
printer->Print(kThinSeparator);
printer->Print("\n");
@ -1151,11 +1190,17 @@ GenerateInlineMethods(io::Printer* printer) {
void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer* printer) {
if (!IsMapEntryMessage(descriptor_)) {
printer->Print(
"const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
"const ::google::protobuf::internal::GeneratedMessageReflection*\n"
" $name$_reflection_ = NULL;\n",
"name", classname_);
} else {
printer->Print(
"const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
"name", classname_);
}
// Generate oneof default instance for reflection usage.
if (descriptor_->oneof_decl_count() > 0) {
@ -1206,13 +1251,20 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
"$parent$_descriptor_->nested_type($index$);\n");
}
if (IsMapEntryMessage(descriptor_)) return;
// Generate the offsets.
GenerateOffsets(printer);
const bool pass_pool_and_factory = false;
vars["fn"] = pass_pool_and_factory ?
"new ::google::protobuf::internal::GeneratedMessageReflection" :
"::google::protobuf::internal::GeneratedMessageReflection"
"::NewGeneratedMessageReflection";
// Construct the reflection object.
printer->Print(vars,
"$classname$_reflection_ =\n"
" new ::google::protobuf::internal::GeneratedMessageReflection(\n"
" $fn$(\n"
" $classname$_descriptor_,\n"
" $classname$::default_instance_,\n"
" $classname$_offsets_,\n");
@ -1254,10 +1306,12 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
"$classname$, _oneof_case_[0]),\n");
}
if (pass_pool_and_factory) {
printer->Print(
" ::google::protobuf::DescriptorPool::generated_pool(),\n");
printer->Print(vars,
" ::google::protobuf::MessageFactory::generated_factory(),\n");
}
printer->Print(vars,
" sizeof($classname$),\n");
@ -1289,10 +1343,37 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
void MessageGenerator::
GenerateTypeRegistrations(io::Printer* printer) {
// Register this message type with the message factory.
if (!IsMapEntryMessage(descriptor_)) {
printer->Print(
"::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
" $classname$_descriptor_, &$classname$::default_instance());\n",
"classname", classname_);
}
else {
map<string, string> vars;
CollectMapInfo(descriptor_, &vars);
vars["classname"] = classname_;
const FieldDescriptor* val = descriptor_->FindFieldByName("value");
if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
val->type() == FieldDescriptor::TYPE_ENUM) {
const EnumValueDescriptor* default_value = val->default_value_enum();
vars["default_enum_value"] = Int32ToString(default_value->number());
} else {
vars["default_enum_value"] = "0";
}
printer->Print(vars,
"::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
" $classname$_descriptor_,\n"
" ::google::protobuf::internal::MapEntry<\n"
" $key$,\n"
" $val$,\n"
" $key_type$,\n"
" $val_type$,\n"
" $default_enum_value$>::CreateDefaultInstance(\n"
" $classname$_descriptor_));\n");
}
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
@ -1309,6 +1390,8 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) {
.GenerateDefaultInstanceAllocator(printer);
}
if (IsMapEntryMessage(descriptor_)) return;
// Construct the default instance. We can't call InitAsDefaultInstance() yet
// because we need to make sure all default instances that this one might
// depend on are constructed first.
@ -1343,6 +1426,10 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) {
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need to initialize default instance manually.
// Since map entry message cannot be a top level class, we just need to
// avoid calling DefaultInstanceInitializer here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
}
}
@ -1372,6 +1459,7 @@ GenerateShutdownCode(io::Printer* printer) {
// Handle nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateShutdownCode(printer);
}
}
@ -1383,6 +1471,10 @@ GenerateClassMethods(io::Printer* printer) {
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need class methods. Since map entry message
// cannot be a top level class, we just need to avoid calling
// GenerateClassMethods here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
nested_generators_[i]->GenerateClassMethods(printer);
printer->Print("\n");
printer->Print(kThinSeparator);
@ -2195,7 +2287,7 @@ GenerateMergeFrom(io::Printer* printer) {
// base class as a parameter).
printer->Print(
"void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
" GOOGLE_CHECK_NE(&from, this);\n",
" if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
"classname", classname_);
printer->Indent();
@ -2230,7 +2322,7 @@ GenerateMergeFrom(io::Printer* printer) {
// Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
printer->Print(
"void $classname$::MergeFrom(const $classname$& from) {\n"
" GOOGLE_CHECK_NE(&from, this);\n",
" if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
"classname", classname_);
printer->Indent();
@ -2429,7 +2521,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Print("for (;;) {\n");
printer->Indent();
scoped_array<const FieldDescriptor*> ordered_fields(
google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
SortFieldsByNumber(descriptor_));
uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
@ -2788,7 +2880,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
void MessageGenerator::
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
scoped_array<const FieldDescriptor*> ordered_fields(
google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields(
SortFieldsByNumber(descriptor_));
vector<const Descriptor::ExtensionRange*> sorted_extensions;
@ -3186,7 +3278,7 @@ GenerateIsInitialized(io::Printer* printer) {
" return false;\n",
"name", FieldName(field));
} else {
if (field->options().weak()) {
if (field->options().weak() || !field->containing_oneof()) {
// For weak fields, use the data member (::google::protobuf::Message*) instead
// of the getter to avoid a link dependency on the weak message type
// which is only forward declared.

@ -163,9 +163,9 @@ class MessageGenerator {
Options options_;
FieldGeneratorMap field_generators_;
vector< vector<string> > runs_of_fields_; // that might be trivially cleared
scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > nested_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_;
int num_required_fields_;
bool uses_string_;

@ -49,6 +49,10 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
if (descriptor->options().weak() || !descriptor->containing_oneof()) {
(*variables)["non_null_ptr_to_name"] =
StrCat("this->", (*variables)["name"], "_");
}
(*variables)["stream_writer"] = (*variables)["declared_type"] +
(HasFastArraySerialization(descriptor->message_type()->file()) ?
"MaybeToArray" :
@ -293,7 +297,7 @@ void MessageFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
" $number$, this->$name$(), output);\n");
" $number$, *$non_null_ptr_to_name$, output);\n");
}
void MessageFieldGenerator::
@ -301,7 +305,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"target = ::google::protobuf::internal::WireFormatLite::\n"
" Write$declared_type$NoVirtualToArray(\n"
" $number$, this->$name$(), target);\n");
" $number$, *$non_null_ptr_to_name$, target);\n");
}
void MessageFieldGenerator::
@ -309,7 +313,7 @@ GenerateByteSize(io::Printer* printer) const {
printer->Print(variables_,
"total_size += $tag_size$ +\n"
" ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
" this->$name$());\n");
" *$non_null_ptr_to_name$);\n");
}
// ===================================================================
@ -591,7 +595,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
"for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
" ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
" $number$, this->$name$(i), output);\n"
"}\n");
@ -600,7 +604,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n"
"for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
" target = ::google::protobuf::internal::WireFormatLite::\n"
" Write$declared_type$NoVirtualToArray(\n"
" $number$, this->$name$(i), target);\n"

@ -171,7 +171,7 @@ class TestGenerator : public CodeGenerator {
void TryInsert(const string& filename, const string& insertion_point,
GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);

@ -306,7 +306,14 @@ GenerateClearingCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
// TODO(gpike): improve this
printer->Print(variables_, "set_$name$(from.$name$());\n");
} else {
printer->Print(variables_,
"$set_hasbit$\n"
"$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
}
}
void StringFieldGenerator::

@ -251,7 +251,7 @@ TEST(GeneratedMessageTest, ReleaseString) {
message.set_default_string("blah");
EXPECT_TRUE(message.has_default_string());
scoped_ptr<string> str(message.release_default_string());
google::protobuf::scoped_ptr<string> str(message.release_default_string());
EXPECT_FALSE(message.has_default_string());
ASSERT_TRUE(str != NULL);
EXPECT_EQ("blah", *str);
@ -270,7 +270,7 @@ TEST(GeneratedMessageTest, ReleaseMessage) {
EXPECT_FALSE(message.has_optional_nested_message());
message.mutable_optional_nested_message()->set_bb(1);
scoped_ptr<unittest::TestAllTypes::NestedMessage> nest(
google::protobuf::scoped_ptr<unittest::TestAllTypes::NestedMessage> nest(
message.release_optional_nested_message());
EXPECT_FALSE(message.has_optional_nested_message());
ASSERT_TRUE(nest != NULL);
@ -534,7 +534,7 @@ TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
// Construct a new version of the dynamic message via the factory.
DynamicMessageFactory factory;
scoped_ptr<Message> message1;
google::protobuf::scoped_ptr<Message> message1;
message1.reset(factory.GetPrototype(
unittest::TestAllTypes::descriptor())->New());
@ -581,9 +581,9 @@ TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
TEST(GeneratedMessageTest, MergeFromSelf) {
unittest::TestAllTypes message;
EXPECT_DEATH(message.MergeFrom(message), "&from");
EXPECT_DEATH(message.MergeFrom(message), "Check failed:.*pb[.]cc");
EXPECT_DEATH(message.MergeFrom(implicit_cast<const Message&>(message)),
"&from");
"Check failed:.*pb[.]cc");
}
#endif // PROTOBUF_HAS_DEATH_TEST
@ -1221,7 +1221,7 @@ class GeneratedServiceTest : public testing::Test {
unittest::FooResponse foo_response_;
unittest::BarRequest bar_request_;
unittest::BarResponse bar_response_;
scoped_ptr<Closure> done_;
google::protobuf::scoped_ptr<Closure> done_;
};
TEST_F(GeneratedServiceTest, GetDescriptor) {
@ -1519,7 +1519,7 @@ TEST_F(OneofTest, ReleaseString) {
message.set_foo_string("blah");
EXPECT_TRUE(message.has_foo_string());
scoped_ptr<string> str(message.release_foo_string());
google::protobuf::scoped_ptr<string> str(message.release_foo_string());
EXPECT_FALSE(message.has_foo_string());
ASSERT_TRUE(str != NULL);
EXPECT_EQ("blah", *str);
@ -1573,7 +1573,7 @@ TEST_F(OneofTest, ReleaseMessage) {
message.mutable_foo_message()->set_qux_int(1);
EXPECT_TRUE(message.has_foo_message());
scoped_ptr<unittest::TestOneof2_NestedMessage> mes(
google::protobuf::scoped_ptr<unittest::TestOneof2_NestedMessage> mes(
message.release_foo_message());
EXPECT_FALSE(message.has_foo_message());
ASSERT_TRUE(mes != NULL);

@ -125,7 +125,7 @@ SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {}
bool SourceTreeDescriptorDatabase::FindFileByName(
const string& filename, FileDescriptorProto* output) {
scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
if (input == NULL) {
if (error_collector_ != NULL) {
error_collector_->AddError(filename, -1, 0,
@ -403,7 +403,7 @@ DiskSourceTree::DiskFileToVirtualFile(
// Verify that we can open the file. Note that this also has the side-effect
// of verifying that we are not canonicalizing away any non-existent
// directories.
scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file));
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file));
if (stream == NULL) {
return CANNOT_OPEN;
}
@ -413,7 +413,7 @@ DiskSourceTree::DiskFileToVirtualFile(
bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file,
string* disk_file) {
scoped_ptr<io::ZeroCopyInputStream> stream(
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> stream(
OpenVirtualFile(virtual_file, disk_file));
return stream != NULL;
}

@ -242,7 +242,7 @@ class DiskSourceTreeTest : public testing::Test {
virtual void TearDown() {
for (int i = 0; i < dirnames_.size(); i++) {
if (File::Exists(dirnames_[i])) {
if (FileExists(dirnames_[i])) {
File::DeleteRecursively(dirnames_[i], NULL, NULL);
}
}
@ -258,7 +258,7 @@ class DiskSourceTreeTest : public testing::Test {
void ExpectFileContents(const string& filename,
const char* expected_contents) {
scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
ASSERT_FALSE(input == NULL);
@ -275,7 +275,7 @@ class DiskSourceTreeTest : public testing::Test {
void ExpectCannotOpenFile(const string& filename,
const string& error_message) {
scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
EXPECT_TRUE(input == NULL);
EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage());
}

@ -84,7 +84,7 @@ class Context {
void InitializeFieldGeneratorInfoForFields(
const vector<const FieldDescriptor*>& fields);
scoped_ptr<ClassNameResolver> name_resolver_;
google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_;
map<const FieldDescriptor*, FieldGeneratorInfo> field_generator_info_map_;
map<const OneofDescriptor*, OneofGeneratorInfo> oneof_generator_info_map_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context);

@ -159,7 +159,7 @@ template <>
FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
const Descriptor* descriptor, Context* context)
: descriptor_(descriptor),
field_generators_(new scoped_ptr<
field_generators_(new google::protobuf::scoped_ptr<
ImmutableFieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators and assign them bit indices for their

@ -108,7 +108,7 @@ class FieldGeneratorMap {
const Descriptor* descriptor_;
Context* context_;
ClassNameResolver* name_resolver_;
scoped_array<scoped_ptr<FieldGeneratorType> > field_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGeneratorType> > field_generators_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};

@ -121,7 +121,7 @@ void CollectExtensions(const FileDescriptorProto& file_proto,
"descriptor.proto is not in the transitive dependencies. "
"This normally should not happen. Please report a bug.";
DynamicMessageFactory factory;
scoped_ptr<Message> dynamic_file_proto(
google::protobuf::scoped_ptr<Message> dynamic_file_proto(
factory.GetPrototype(file_proto_desc)->New());
GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
@ -146,9 +146,9 @@ FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
: file_(file),
java_package_(FileJavaPackage(file, immutable_api)),
message_generators_(
new scoped_ptr<MessageGenerator>[file->message_type_count()]),
new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
extension_generators_(
new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
context_(new Context(file)),
name_resolver_(context_->GetNameResolver()),
immutable_api_(immutable_api) {
@ -240,7 +240,7 @@ void FileGenerator::Generate(io::Printer* printer) {
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
scoped_ptr<ServiceGenerator> generator(
google::protobuf::scoped_ptr<ServiceGenerator> generator(
generator_factory_->NewServiceGenerator(file_->service(i)));
generator->Generate(printer);
}
@ -340,7 +340,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
"com.google.protobuf.ExtensionRegistry registry =\n"
" com.google.protobuf.ExtensionRegistry.newInstance();\n");
for (int i = 0; i < extensions.size(); i++) {
scoped_ptr<ExtensionGenerator> generator(
google::protobuf::scoped_ptr<ExtensionGenerator> generator(
generator_factory_->NewExtensionGenerator(extensions[i]));
generator->GenerateRegistrationCode(printer);
}
@ -444,7 +444,7 @@ static void GenerateSibling(const string& package_dir,
string filename = package_dir + descriptor->name() + name_suffix + ".java";
file_list->push_back(filename);
scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
io::Printer printer(output.get(), '$');
printer.Print(
@ -492,7 +492,7 @@ void FileGenerator::GenerateSiblings(const string& package_dir,
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
scoped_ptr<ServiceGenerator> generator(
google::protobuf::scoped_ptr<ServiceGenerator> generator(
generator_factory_->NewServiceGenerator(file_->service(i)));
GenerateSibling<ServiceGenerator>(package_dir, java_package_,
file_->service(i),

@ -99,10 +99,10 @@ class FileGenerator {
string java_package_;
string classname_;
scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
scoped_ptr<GeneratorFactory> generator_factory_;
scoped_ptr<Context> context_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_;
google::protobuf::scoped_ptr<GeneratorFactory> generator_factory_;
google::protobuf::scoped_ptr<Context> context_;
ClassNameResolver* name_resolver_;
bool immutable_api_;

@ -130,7 +130,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
all_files.push_back(java_filename);
// Generate main java file.
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->Open(java_filename));
io::Printer printer(output.get(), '$');
file_generator->Generate(&printer);
@ -148,7 +148,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
if (!output_list_file.empty()) {
// Generate output list. This is just a simple text file placed in a
// deterministic location which lists the .java files being generated.
scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
context->Open(output_list_file));
io::Printer srclist_printer(srclist_raw_output.get(), '$');
for (int i = 0; i < all_files.size(); i++) {

@ -70,6 +70,13 @@ bool GenerateHasBits(const Descriptor* descriptor) {
return SupportFieldPresence(descriptor->file()) ||
HasRepeatedFields(descriptor);
}
string MapValueImmutableClassdName(const Descriptor* descriptor,
ClassNameResolver* name_resolver) {
const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
return name_resolver->GetImmutableClassName(value_field->message_type());
}
} // namespace
// ===================================================================
@ -323,18 +330,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n"
"\n"
"private static final $classname$ defaultInstance;\n"
"public static $classname$ getDefaultInstance() {\n"
" return defaultInstance;\n"
"}\n"
"\n"
"public $classname$ getDefaultInstanceForType() {\n"
" return defaultInstance;\n"
"}\n"
"\n",
"classname", descriptor_->name(),
"lite", variables["lite"]);
"\n");
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
@ -479,18 +475,25 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
GenerateParseFromMethods(printer);
GenerateBuilder(printer);
// Carefully initialize the default instance in such a way that it doesn't
// conflict with other initialization.
printer->Print(
"\n"
"static {\n"
" defaultInstance = new $classname$();\n"
"}\n"
"\n"
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
"classname", descriptor_->name(),
"full_name", descriptor_->full_name());
// Carefully initialize the default instance in such a way that it doesn't
// conflict with other initialization.
printer->Print("private static final $classname$ defaultInstance =\n"
" new $classname$();\n"
"public static $classname$ getDefaultInstance() {\n"
" return defaultInstance;\n"
"}\n"
"\n"
"public $classname$ getDefaultInstanceForType() {\n"
" return defaultInstance;\n"
"}\n"
"\n",
"classname", descriptor_->name());
// Extensions must be declared after the defaultInstance is initialized
// because the defaultInstance is used by the extension to lazily retrieve
// the outer class's FileDescriptor.
@ -508,7 +511,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
void ImmutableMessageGenerator::
GenerateMessageSerializationMethods(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
SortFieldsByNumber(descriptor_));
vector<const Descriptor::ExtensionRange*> sorted_extensions;
@ -913,6 +916,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
void ImmutableMessageGenerator::
GenerateCommonBuilderMethods(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"// Construct using $classname$.newBuilder()\n"
"private Builder() {\n"
@ -921,7 +925,6 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"private Builder(\n"
" com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
@ -929,6 +932,17 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
" maybeForceBuilderInitialization();\n"
"}\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
} else {
// LITE runtime passes along the default instance to implement
// getDefaultInstanceForType() at the GneratedMessageLite level.
printer->Print(
"// Construct using $classname$.newBuilder()\n"
"private Builder() {\n"
" super(defaultInstance);\n"
" maybeForceBuilderInitialization();\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
}
@ -994,16 +1008,20 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"\n",
"fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
"identifier", UniqueFileScopeIdentifier(descriptor_));
}
// LITE runtime implements this in GeneratedMessageLite.
printer->Print(
"public $classname$ getDefaultInstanceForType() {\n"
" return $classname$.getDefaultInstance();\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
}
// -----------------------------------------------------------------
if (HasDescriptorMethods(descriptor_)) {
// LITE implements build in GeneratedMessageLite to save methods.
printer->Print(
"public $classname$ build() {\n"
" $classname$ result = buildPartial();\n"
@ -1012,7 +1030,11 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
" }\n"
" return result;\n"
"}\n"
"\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
}
printer->Print(
"public $classname$ buildPartial() {\n"
" $classname$ result = new $classname$(this);\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
@ -1255,6 +1277,19 @@ void ImmutableMessageGenerator::GenerateIsInitialized(
"memoize", memoization ? "memoizedIsInitialized = 0;" : "");
break;
case FieldDescriptor::LABEL_REPEATED:
if (IsMapEntry(field->message_type())) {
printer->Print(
"for ($type$ item : get$name$().values()) {\n"
" if (!item.isInitialized()) {\n"
" $memoize$\n"
" return false;\n"
" }\n"
"}\n",
"type", MapValueImmutableClassdName(field->message_type(),
name_resolver_),
"name", info->capitalized_name,
"memoize", memoization ? "memoizedIsInitialized = 0;" : "");
} else {
printer->Print(
"for (int i = 0; i < get$name$Count(); i++) {\n"
" if (!get$name$(i).isInitialized()) {\n"
@ -1266,6 +1301,7 @@ void ImmutableMessageGenerator::GenerateIsInitialized(
field->message_type()),
"name", info->capitalized_name,
"memoize", memoization ? "memoizedIsInitialized = 0;" : "");
}
break;
}
}
@ -1440,7 +1476,7 @@ GenerateExtensionRegistrationCode(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::
GenerateParsingConstructor(io::Printer* printer) {
scoped_array<const FieldDescriptor*> sorted_fields(
google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
SortFieldsByNumber(descriptor_));
printer->Print(
@ -1596,9 +1632,18 @@ GenerateParsingConstructor(io::Printer* printer) {
printer->Print("this.unknownFields = unknownFields.build();\n");
}
if (!HasDescriptorMethods(descriptor_)) {
// LITE runtime uses a static method to reduce method count.
if (descriptor_->extension_range_count() > 0) {
// Make extensions immutable.
printer->Print(
"makeExtensionsImmutable(extensions);\n");
}
} else {
// Make extensions immutable.
printer->Print(
"makeExtensionsImmutable();\n");
}
printer->Outdent();
printer->Outdent();

@ -75,7 +75,7 @@ class TestGenerator : public CodeGenerator {
void TryInsert(const string& filename, const string& insertion_point,
GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);

@ -68,8 +68,8 @@ void SharedCodeGenerator::Generate(GeneratorContext* context,
string classname = name_resolver_->GetDescriptorClassName(file_);
string filename = package_dir + classname + ".java";
file_list->push_back(filename);
scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
scoped_ptr<io::Printer> printer(new io::Printer(output.get(), '$'));
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
google::protobuf::scoped_ptr<io::Printer> printer(new io::Printer(output.get(), '$'));
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"

@ -80,7 +80,7 @@ class SharedCodeGenerator {
// improve compatibility with version 1 of protocol buffers.
bool ShouldIncludeDependency(const FileDescriptor* descriptor);
scoped_ptr<ClassNameResolver> name_resolver_;
google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_;
const FileDescriptor* file_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator);
};

@ -160,7 +160,7 @@ bool MockCodeGenerator::Generate(
for (int i = 0; i < insert_into.size(); i++) {
{
scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
GetOutputFileName(insert_into[i], file), kFirstInsertionPointName));
io::Printer printer(output.get(), '$');
printer.PrintRaw(GetOutputFileContent(name_, "first_insert",
@ -172,7 +172,7 @@ bool MockCodeGenerator::Generate(
}
{
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->OpenForInsert(GetOutputFileName(insert_into[i], file),
kSecondInsertionPointName));
io::Printer printer(output.get(), '$');
@ -185,7 +185,7 @@ bool MockCodeGenerator::Generate(
}
}
} else {
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->Open(GetOutputFileName(name_, file)));
io::Printer printer(output.get(), '$');

@ -178,9 +178,9 @@ class ParserTest : public testing::Test {
MockErrorCollector error_collector_;
DescriptorPool pool_;
scoped_ptr<io::ZeroCopyInputStream> raw_input_;
scoped_ptr<io::Tokenizer> input_;
scoped_ptr<Parser> parser_;
google::protobuf::scoped_ptr<io::ZeroCopyInputStream> raw_input_;
google::protobuf::scoped_ptr<io::Tokenizer> input_;
google::protobuf::scoped_ptr<Parser> parser_;
bool require_syntax_identifier_;
};

@ -48,15 +48,13 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_),
};
CodeGeneratorRequest_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
CodeGeneratorRequest_descriptor_,
CodeGeneratorRequest::default_instance_,
CodeGeneratorRequest_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_[0]),
-1,
-1,
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(CodeGeneratorRequest),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_));
CodeGeneratorResponse_descriptor_ = file->message_type(1);
@ -65,15 +63,13 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_),
};
CodeGeneratorResponse_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
CodeGeneratorResponse_descriptor_,
CodeGeneratorResponse::default_instance_,
CodeGeneratorResponse_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_[0]),
-1,
-1,
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(CodeGeneratorResponse),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_));
CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0);
@ -83,15 +79,13 @@ void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_),
};
CodeGeneratorResponse_File_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
CodeGeneratorResponse_File_descriptor_,
CodeGeneratorResponse_File::default_instance_,
CodeGeneratorResponse_File_offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_[0]),
-1,
-1,
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(CodeGeneratorResponse_File),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_));
}
@ -163,6 +157,16 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
namespace {
static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
static void MergeFromFail(int line) {
GOOGLE_CHECK(false) << __FILE__ << ":" << line;
}
} // namespace
// ===================================================================
#ifndef _MSC_VER
@ -177,16 +181,6 @@ CodeGeneratorRequest::CodeGeneratorRequest()
// @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
CodeGeneratorRequest::CodeGeneratorRequest(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(),
_internal_metadata_(arena),
file_to_generate_(arena),
proto_file_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
void CodeGeneratorRequest::InitAsDefaultInstance() {
}
@ -211,21 +205,11 @@ CodeGeneratorRequest::~CodeGeneratorRequest() {
}
void CodeGeneratorRequest::SharedDtor() {
if (GetArenaNoVirtual() != NULL) {
return;
}
parameter_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
parameter_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
}
}
void CodeGeneratorRequest::ArenaDtor(void* object) {
CodeGeneratorRequest* _this = reinterpret_cast< CodeGeneratorRequest* >(object);
(void)_this;
}
void CodeGeneratorRequest::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void CodeGeneratorRequest::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@ -244,12 +228,16 @@ const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL;
CodeGeneratorRequest* CodeGeneratorRequest::New(::google::protobuf::Arena* arena) const {
return ::google::protobuf::Arena::CreateMessage<CodeGeneratorRequest>(arena);
CodeGeneratorRequest* n = new CodeGeneratorRequest;
if (arena != NULL) {
arena->Own(n);
}
return n;
}
void CodeGeneratorRequest::Clear() {
if (has_parameter()) {
parameter_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
file_to_generate_.Clear();
proto_file_.Clear();
@ -365,7 +353,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
for (int i = 0; i < this->proto_file_size(); i++) {
for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
15, this->proto_file(i), output);
}
@ -402,7 +390,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
for (int i = 0; i < this->proto_file_size(); i++) {
for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
15, this->proto_file(i), target);
@ -453,7 +441,7 @@ int CodeGeneratorRequest::ByteSize() const {
}
void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
const CodeGeneratorRequest* source =
::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorRequest*>(
&from);
@ -465,12 +453,13 @@ void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
}
void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_parameter()) {
set_parameter(from.parameter());
set_has_parameter();
parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
}
}
if (from._internal_metadata_.have_unknown_fields()) {
@ -498,18 +487,6 @@ bool CodeGeneratorRequest::IsInitialized() const {
void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
CodeGeneratorRequest temp;
temp.MergeFrom(*this);
CopyFrom(*other);
other->CopyFrom(temp);
}
}
void CodeGeneratorRequest::UnsafeArenaSwap(CodeGeneratorRequest* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
@ -544,14 +521,6 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File()
// @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
CodeGeneratorResponse_File::CodeGeneratorResponse_File(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(),
_internal_metadata_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
void CodeGeneratorResponse_File::InitAsDefaultInstance() {
}
@ -578,23 +547,13 @@ CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
}
void CodeGeneratorResponse_File::SharedDtor() {
if (GetArenaNoVirtual() != NULL) {
return;
}
name_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
insertion_point_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
content_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
insertion_point_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
content_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
}
}
void CodeGeneratorResponse_File::ArenaDtor(void* object) {
CodeGeneratorResponse_File* _this = reinterpret_cast< CodeGeneratorResponse_File* >(object);
(void)_this;
}
void CodeGeneratorResponse_File::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void CodeGeneratorResponse_File::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@ -613,19 +572,23 @@ const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance()
CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL;
CodeGeneratorResponse_File* CodeGeneratorResponse_File::New(::google::protobuf::Arena* arena) const {
return ::google::protobuf::Arena::CreateMessage<CodeGeneratorResponse_File>(arena);
CodeGeneratorResponse_File* n = new CodeGeneratorResponse_File;
if (arena != NULL) {
arena->Own(n);
}
return n;
}
void CodeGeneratorResponse_File::Clear() {
if (_has_bits_[0 / 32] & 7) {
if (has_name()) {
name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
if (has_insertion_point()) {
insertion_point_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
if (has_content()) {
content_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
@ -838,7 +801,7 @@ int CodeGeneratorResponse_File::ByteSize() const {
}
void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
const CodeGeneratorResponse_File* source =
::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse_File*>(
&from);
@ -850,16 +813,19 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr
}
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_name(from.name());
set_has_name();
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
}
if (from.has_insertion_point()) {
set_insertion_point(from.insertion_point());
set_has_insertion_point();
insertion_point_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.insertion_point_);
}
if (from.has_content()) {
set_content(from.content());
set_has_content();
content_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.content_);
}
}
if (from._internal_metadata_.have_unknown_fields()) {
@ -886,18 +852,6 @@ bool CodeGeneratorResponse_File::IsInitialized() const {
void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
CodeGeneratorResponse_File temp;
temp.MergeFrom(*this);
CopyFrom(*other);
other->CopyFrom(temp);
}
}
void CodeGeneratorResponse_File::UnsafeArenaSwap(CodeGeneratorResponse_File* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) {
@ -931,15 +885,6 @@ CodeGeneratorResponse::CodeGeneratorResponse()
// @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
CodeGeneratorResponse::CodeGeneratorResponse(::google::protobuf::Arena* arena)
: ::google::protobuf::Message(),
_internal_metadata_(arena),
file_(arena) {
SharedCtor();
RegisterArenaDtor(arena);
// @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
void CodeGeneratorResponse::InitAsDefaultInstance() {
}
@ -964,21 +909,11 @@ CodeGeneratorResponse::~CodeGeneratorResponse() {
}
void CodeGeneratorResponse::SharedDtor() {
if (GetArenaNoVirtual() != NULL) {
return;
}
error_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
error_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
}
}
void CodeGeneratorResponse::ArenaDtor(void* object) {
CodeGeneratorResponse* _this = reinterpret_cast< CodeGeneratorResponse* >(object);
(void)_this;
}
void CodeGeneratorResponse::RegisterArenaDtor(::google::protobuf::Arena* arena) {
}
void CodeGeneratorResponse::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@ -997,12 +932,16 @@ const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL;
CodeGeneratorResponse* CodeGeneratorResponse::New(::google::protobuf::Arena* arena) const {
return ::google::protobuf::Arena::CreateMessage<CodeGeneratorResponse>(arena);
CodeGeneratorResponse* n = new CodeGeneratorResponse;
if (arena != NULL) {
arena->Own(n);
}
return n;
}
void CodeGeneratorResponse::Clear() {
if (has_error()) {
error_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
file_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
@ -1087,7 +1026,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
for (int i = 0; i < this->file_size(); i++) {
for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
15, this->file(i), output);
}
@ -1114,7 +1053,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
for (int i = 0; i < this->file_size(); i++) {
for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
15, this->file(i), target);
@ -1158,7 +1097,7 @@ int CodeGeneratorResponse::ByteSize() const {
}
void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
const CodeGeneratorResponse* source =
::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse*>(
&from);
@ -1170,11 +1109,12 @@ void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
}
void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
GOOGLE_CHECK_NE(&from, this);
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_error()) {
set_error(from.error());
set_has_error();
error_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_);
}
}
if (from._internal_metadata_.have_unknown_fields()) {
@ -1201,18 +1141,6 @@ bool CodeGeneratorResponse::IsInitialized() const {
void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) {
if (other == this) return;
if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
InternalSwap(other);
} else {
CodeGeneratorResponse temp;
temp.MergeFrom(*this);
CopyFrom(*other);
other->CopyFrom(temp);
}
}
void CodeGeneratorResponse::UnsafeArenaSwap(CodeGeneratorResponse* other) {
if (other == this) return;
GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {

@ -5,7 +5,6 @@
#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
#include <string>
#include <stdint.h>
#include <google/protobuf/stubs/common.h>
@ -66,14 +65,9 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
return _internal_metadata_.mutable_unknown_fields();
}
inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
inline void* GetMaybeArenaPointer() const {
return MaybeArenaPtr();
}
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorRequest& default_instance();
void UnsafeArenaSwap(CodeGeneratorRequest* other);
void Swap(CodeGeneratorRequest* other);
// implements Message ----------------------------------------------
@ -100,11 +94,6 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(CodeGeneratorRequest* other);
protected:
explicit CodeGeneratorRequest(::google::protobuf::Arena* arena);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@ -147,9 +136,6 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline ::std::string* mutable_parameter();
inline ::std::string* release_parameter();
inline void set_allocated_parameter(::std::string* parameter);
inline ::std::string* unsafe_arena_release_parameter();
inline void unsafe_arena_set_allocated_parameter(
::std::string* parameter);
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int proto_file_size() const;
@ -169,9 +155,6 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline void clear_has_parameter();
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
friend class ::google::protobuf::Arena;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
@ -206,14 +189,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
return _internal_metadata_.mutable_unknown_fields();
}
inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
inline void* GetMaybeArenaPointer() const {
return MaybeArenaPtr();
}
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorResponse_File& default_instance();
void UnsafeArenaSwap(CodeGeneratorResponse_File* other);
void Swap(CodeGeneratorResponse_File* other);
// implements Message ----------------------------------------------
@ -240,11 +218,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(CodeGeneratorResponse_File* other);
protected:
explicit CodeGeneratorResponse_File(::google::protobuf::Arena* arena);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@ -271,9 +244,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline ::std::string* mutable_name();
inline ::std::string* release_name();
inline void set_allocated_name(::std::string* name);
inline ::std::string* unsafe_arena_release_name();
inline void unsafe_arena_set_allocated_name(
::std::string* name);
// optional string insertion_point = 2;
inline bool has_insertion_point() const;
@ -286,9 +256,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline ::std::string* mutable_insertion_point();
inline ::std::string* release_insertion_point();
inline void set_allocated_insertion_point(::std::string* insertion_point);
inline ::std::string* unsafe_arena_release_insertion_point();
inline void unsafe_arena_set_allocated_insertion_point(
::std::string* insertion_point);
// optional string content = 15;
inline bool has_content() const;
@ -301,9 +268,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline ::std::string* mutable_content();
inline ::std::string* release_content();
inline void set_allocated_content(::std::string* content);
inline ::std::string* unsafe_arena_release_content();
inline void unsafe_arena_set_allocated_content(
::std::string* content);
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
private:
@ -315,9 +279,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void clear_has_content();
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
friend class ::google::protobuf::Arena;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::internal::ArenaStringPtr name_;
@ -352,14 +313,9 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
return _internal_metadata_.mutable_unknown_fields();
}
inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
inline void* GetMaybeArenaPointer() const {
return MaybeArenaPtr();
}
static const ::google::protobuf::Descriptor* descriptor();
static const CodeGeneratorResponse& default_instance();
void UnsafeArenaSwap(CodeGeneratorResponse* other);
void Swap(CodeGeneratorResponse* other);
// implements Message ----------------------------------------------
@ -386,11 +342,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(CodeGeneratorResponse* other);
protected:
explicit CodeGeneratorResponse(::google::protobuf::Arena* arena);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@ -419,9 +370,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
inline ::std::string* mutable_error();
inline ::std::string* release_error();
inline void set_allocated_error(::std::string* error);
inline ::std::string* unsafe_arena_release_error();
inline void unsafe_arena_set_allocated_error(
::std::string* error);
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int file_size() const;
@ -441,9 +389,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
inline void clear_has_error();
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
friend class ::google::protobuf::Arena;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::internal::ArenaStringPtr error_;
@ -527,45 +472,37 @@ inline void CodeGeneratorRequest::clear_has_parameter() {
_has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorRequest::clear_parameter() {
parameter_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_parameter();
}
inline const ::std::string& CodeGeneratorRequest::parameter() const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
return parameter_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return parameter_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
set_has_parameter();
parameter_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline void CodeGeneratorRequest::set_parameter(const char* value) {
set_has_parameter();
parameter_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
GetArenaNoVirtual());
parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline void CodeGeneratorRequest::set_parameter(const char* value,
size_t size) {
inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
set_has_parameter();
parameter_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
set_has_parameter();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
return parameter_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorRequest::release_parameter() {
clear_has_parameter();
return parameter_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* CodeGeneratorRequest::unsafe_arena_release_parameter() {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
clear_has_parameter();
return parameter_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
GetArenaNoVirtual());
return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
if (parameter != NULL) {
@ -573,21 +510,7 @@ inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* paramet
} else {
clear_has_parameter();
}
parameter_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter,
GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline void CodeGeneratorRequest::unsafe_arena_set_allocated_parameter(
::std::string* parameter) {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
if (parameter != NULL) {
set_has_parameter();
} else {
clear_has_parameter();
}
set_has_parameter();
parameter_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
parameter, GetArenaNoVirtual());
parameter_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
@ -636,45 +559,37 @@ inline void CodeGeneratorResponse_File::clear_has_name() {
_has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse_File::clear_name() {
name_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_name();
}
inline const ::std::string& CodeGeneratorResponse_File::name() const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
return name_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
set_has_name();
name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline void CodeGeneratorResponse_File::set_name(const char* value) {
set_has_name();
name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
GetArenaNoVirtual());
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline void CodeGeneratorResponse_File::set_name(const char* value,
size_t size) {
inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
set_has_name();
name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
set_has_name();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
return name_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_name() {
clear_has_name();
return name_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* CodeGeneratorResponse_File::unsafe_arena_release_name() {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
clear_has_name();
return name_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
GetArenaNoVirtual());
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
if (name != NULL) {
@ -682,21 +597,7 @@ inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name)
} else {
clear_has_name();
}
name_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name,
GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_name(
::std::string* name) {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
if (name != NULL) {
set_has_name();
} else {
clear_has_name();
}
set_has_name();
name_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
name, GetArenaNoVirtual());
name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
@ -711,45 +612,37 @@ inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
_has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorResponse_File::clear_insertion_point() {
insertion_point_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_insertion_point();
}
inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
return insertion_point_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return insertion_point_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
set_has_insertion_point();
insertion_point_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
set_has_insertion_point();
insertion_point_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
GetArenaNoVirtual());
insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value,
size_t size) {
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
set_has_insertion_point();
insertion_point_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
set_has_insertion_point();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
return insertion_point_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
clear_has_insertion_point();
return insertion_point_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* CodeGeneratorResponse_File::unsafe_arena_release_insertion_point() {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
clear_has_insertion_point();
return insertion_point_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
GetArenaNoVirtual());
return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
if (insertion_point != NULL) {
@ -757,21 +650,7 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::str
} else {
clear_has_insertion_point();
}
insertion_point_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point,
GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_insertion_point(
::std::string* insertion_point) {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
if (insertion_point != NULL) {
set_has_insertion_point();
} else {
clear_has_insertion_point();
}
set_has_insertion_point();
insertion_point_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
insertion_point, GetArenaNoVirtual());
insertion_point_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
@ -786,45 +665,37 @@ inline void CodeGeneratorResponse_File::clear_has_content() {
_has_bits_[0] &= ~0x00000004u;
}
inline void CodeGeneratorResponse_File::clear_content() {
content_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_content();
}
inline const ::std::string& CodeGeneratorResponse_File::content() const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
return content_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return content_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
set_has_content();
content_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline void CodeGeneratorResponse_File::set_content(const char* value) {
set_has_content();
content_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
GetArenaNoVirtual());
content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline void CodeGeneratorResponse_File::set_content(const char* value,
size_t size) {
inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
set_has_content();
content_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
set_has_content();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
return content_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_content() {
clear_has_content();
return content_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* CodeGeneratorResponse_File::unsafe_arena_release_content() {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
clear_has_content();
return content_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
GetArenaNoVirtual());
return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
if (content != NULL) {
@ -832,21 +703,7 @@ inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* con
} else {
clear_has_content();
}
content_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content,
GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_content(
::std::string* content) {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
if (content != NULL) {
set_has_content();
} else {
clear_has_content();
}
set_has_content();
content_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
content, GetArenaNoVirtual());
content_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
@ -865,45 +722,37 @@ inline void CodeGeneratorResponse::clear_has_error() {
_has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse::clear_error() {
error_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_error();
}
inline const ::std::string& CodeGeneratorResponse::error() const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
return error_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
return error_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
set_has_error();
error_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline void CodeGeneratorResponse::set_error(const char* value) {
set_has_error();
error_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
GetArenaNoVirtual());
error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline void CodeGeneratorResponse::set_error(const char* value,
size_t size) {
inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
set_has_error();
error_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline ::std::string* CodeGeneratorResponse::mutable_error() {
set_has_error();
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
return error_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse::release_error() {
clear_has_error();
return error_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* CodeGeneratorResponse::unsafe_arena_release_error() {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
clear_has_error();
return error_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
GetArenaNoVirtual());
return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
if (error != NULL) {
@ -911,21 +760,7 @@ inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
} else {
clear_has_error();
}
error_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error,
GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline void CodeGeneratorResponse::unsafe_arena_set_allocated_error(
::std::string* error) {
GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
if (error != NULL) {
set_has_error();
} else {
clear_has_error();
}
set_has_error();
error_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
error, GetArenaNoVirtual());
error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
}

@ -73,41 +73,6 @@ namespace python {
namespace {
const char* const kKeywordList[] = {
"and", "as", "break", "class", "continue", "def", "elif", "else", "except",
"False", "for", "from", "if", "import", "not", "or", "raise", "return",
"True", "try", "with", "while", "yield"
};
hash_set<string> MakeKeywordsMap() {
hash_set<string> result;
for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); ++i) {
result.insert(kKeywordList[i]);
}
return result;
}
hash_set<string>* keywords_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(keywords_once_);
void InitKeywords() {
keywords_ = new hash_set<string>();
*keywords_ = MakeKeywordsMap();
}
hash_set<string>& GetKeywords() {
::google::protobuf::GoogleOnceInit(&keywords_once_, &InitKeywords);
return *keywords_;
}
string FieldName(const FieldDescriptor& field) {
string result = field.name();
if (GetKeywords().count(result) > 0) {
result.append("_");
}
return result;
}
// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
// suffix stripped.
// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
@ -343,7 +308,7 @@ bool Generator::Generate(const FileDescriptor* file,
fdp.SerializeToString(&file_descriptor_serialized_);
scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
GOOGLE_CHECK(output.get());
io::Printer printer(output.get(), '$');
printer_ = &printer;
@ -531,7 +496,7 @@ void Generator::PrintTopLevelExtensions() const {
printer_->Print("$constant_name$ = $number$\n",
"constant_name", constant_name,
"number", SimpleItoa(extension_field.number()));
printer_->Print("$name$ = ", "name", FieldName(extension_field));
printer_->Print("$name$ = ", "name", extension_field.name());
PrintFieldDescriptor(extension_field, is_extension);
printer_->Print("\n");
}
@ -878,7 +843,7 @@ void Generator::AddExtensionToFileDescriptor(
const FieldDescriptor& descriptor) const {
map<string, string> m;
m["descriptor_name"] = kDescriptorKey;
m["field_name"] = FieldName(descriptor);
m["field_name"] = descriptor.name();
const char file_descriptor_template[] =
"$descriptor_name$.extensions_by_name['$field_name$'] = "
"$field_name$\n";
@ -931,12 +896,12 @@ string Generator::FieldReferencingExpression(
GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
<< file_->name();
if (!containing_type) {
return FieldName(field);
return field.name();
}
return strings::Substitute(
"$0.$1['$2']",
ModuleLevelDescriptorName(*containing_type),
python_dict_name, FieldName(field));
python_dict_name, field.name());
}
// Prints containing_type for nested descriptors or enum descriptors.
@ -1065,7 +1030,7 @@ void Generator::PrintFieldDescriptor(
string options_string;
field.options().SerializeToString(&options_string);
map<string, string> m;
m["name"] = FieldName(field);
m["name"] = field.name();
m["full_name"] = field.full_name();
m["index"] = SimpleItoa(field.index());
m["number"] = SimpleItoa(field.number());
@ -1285,7 +1250,7 @@ void Generator::FixOptionsForField(
if (field.is_extension()) {
if (field.extension_scope() == NULL) {
// Top level extensions.
field_name = FieldName(field);
field_name = field.name();
} else {
field_name = FieldReferencingExpression(
field.extension_scope(), field, "extensions_by_name");

@ -72,7 +72,7 @@ class TestGenerator : public CodeGenerator {
void TryInsert(const string& filename, const string& insertion_point,
GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);

@ -1617,6 +1617,10 @@ bool DescriptorPool::TryFindExtensionInFallbackDatabase(
// ===================================================================
bool FieldDescriptor::is_map() const {
return type() == TYPE_MESSAGE && message_type()->options().map_entry();
}
string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
GOOGLE_CHECK(has_default_value()) << "No default value";
switch (cpp_type()) {
@ -2184,9 +2188,7 @@ void FieldDescriptor::DebugString(int depth,
string field_type;
// Special case map fields.
bool is_map = false;
if (type() == TYPE_MESSAGE && message_type()->options().map_entry()) {
is_map = true;
if (is_map()) {
strings::SubstituteAndAppend(
&field_type, "map<$0, $1>",
message_type()->field(0)->FieldTypeNameDebugString(),
@ -2196,7 +2198,7 @@ void FieldDescriptor::DebugString(int depth,
}
string label;
if (print_label_flag == PRINT_LABEL && !is_map) {
if (print_label_flag == PRINT_LABEL && !is_map()) {
label = kLabelToName[this->label()];
label.push_back(' ');
}
@ -4964,8 +4966,7 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
}
// Validate map types.
if (field->type() == FieldDescriptor::TYPE_MESSAGE &&
field->message_type()->options().map_entry()) {
if (field->is_map()) {
if (!ValidateMapEntry(field, proto)) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::OTHER,

@ -117,8 +117,6 @@ struct SourceLocation {
int end_column;
// Doc comments found at the source location.
// TODO(kenton): Maybe this struct should have been named SourceInfo or
// something instead. Oh well.
string leading_comments;
string trailing_comments;
};
@ -477,6 +475,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
// IsTypePackable(type())
bool is_packed() const; // shorthand for is_packable() &&
// options().packed()
bool is_map() const; // shorthand for type() == TYPE_MESSAGE &&
// message_type()->options().map_entry()
// Index of this field within the message's field array, or the file or
// extension scope's extensions array.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -340,6 +340,11 @@ message FileOptions {
optional bool deprecated = 23 [default=false];
// Enables the use of arenas for the proto messages in this file. This applies
// only to generated classes for C++.
optional bool cc_enable_arenas = 31 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;

@ -415,6 +415,11 @@ class DescriptorTest : public testing::Test {
// required string quux = 6;
// }
//
// // in "map.proto"
// message TestMessage3 {
// map<int32, int32> map_int32_int32 = 1;
// }
//
// We cheat and use TestForeign as the type for qux rather than create
// an actual nested type.
//
@ -462,6 +467,24 @@ class DescriptorTest : public testing::Test {
FieldDescriptorProto::LABEL_REQUIRED,
FieldDescriptorProto::TYPE_STRING);
FileDescriptorProto map_file;
map_file.set_name("map.proto");
DescriptorProto* message3 = AddMessage(&map_file, "TestMessage3");
DescriptorProto* entry = AddNestedMessage(message3, "MapInt32Int32Entry");
AddField(entry, "key", 1,
FieldDescriptorProto::LABEL_OPTIONAL,
FieldDescriptorProto::TYPE_INT32);
AddField(entry, "value", 2,
FieldDescriptorProto::LABEL_OPTIONAL,
FieldDescriptorProto::TYPE_INT32);
entry->mutable_options()->set_map_entry(true);
AddField(message3, "map_int32_int32", 1,
FieldDescriptorProto::LABEL_REPEATED,
FieldDescriptorProto::TYPE_MESSAGE)
->set_type_name("MapInt32Int32Entry");
// Build the descriptors and get the pointers.
foo_file_ = pool_.BuildFile(foo_file);
ASSERT_TRUE(foo_file_ != NULL);
@ -469,6 +492,9 @@ class DescriptorTest : public testing::Test {
bar_file_ = pool_.BuildFile(bar_file);
ASSERT_TRUE(bar_file_ != NULL);
map_file_ = pool_.BuildFile(map_file);
ASSERT_TRUE(map_file_ != NULL);
ASSERT_EQ(1, foo_file_->enum_type_count());
enum_ = foo_file_->enum_type(0);
@ -489,15 +515,23 @@ class DescriptorTest : public testing::Test {
foo2_ = message2_->field(0);
bar2_ = message2_->field(1);
quux2_ = message2_->field(2);
ASSERT_EQ(1, map_file_->message_type_count());
message3_ = map_file_->message_type(0);
ASSERT_EQ(1, message3_->field_count());
map_ = message3_->field(0);
}
DescriptorPool pool_;
const FileDescriptor* foo_file_;
const FileDescriptor* bar_file_;
const FileDescriptor* map_file_;
const Descriptor* message_;
const Descriptor* message2_;
const Descriptor* message3_;
const Descriptor* foreign_;
const EnumDescriptor* enum_;
@ -509,6 +543,8 @@ class DescriptorTest : public testing::Test {
const FieldDescriptor* foo2_;
const FieldDescriptor* bar2_;
const FieldDescriptor* quux2_;
const FieldDescriptor* map_;
};
TEST_F(DescriptorTest, Name) {
@ -638,6 +674,12 @@ TEST_F(DescriptorTest, FieldLabel) {
EXPECT_TRUE (baz_->is_repeated());
}
TEST_F(DescriptorTest, IsMap) {
EXPECT_TRUE(map_->is_map());
EXPECT_FALSE(baz_->is_map());
EXPECT_TRUE(map_->message_type()->options().map_entry());
}
TEST_F(DescriptorTest, FieldHasDefault) {
EXPECT_FALSE(foo_->has_default_value());
EXPECT_FALSE(bar_->has_default_value());

@ -72,7 +72,7 @@ TEST(DropUnknownFieldsTest, DynamicMessage) {
foo_with_extra_fields.set_extra_int32_value(2);
google::protobuf::DynamicMessageFactory factory;
scoped_ptr<google::protobuf::Message> foo(
google::protobuf::scoped_ptr<google::protobuf::Message> foo(
factory.GetPrototype(Foo::descriptor())->New());
ASSERT_TRUE(foo->ParseFromString(foo_with_extra_fields.SerializeAsString()));
EXPECT_TRUE(foo->GetReflection()->GetUnknownFields(*foo).empty());

@ -73,8 +73,10 @@
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/map_field_inl.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format.h>
@ -84,6 +86,8 @@ namespace protobuf {
using internal::WireFormat;
using internal::ExtensionSet;
using internal::GeneratedMessageReflection;
using internal::MapField;
using internal::MapFieldBase;
using internal::ArenaStringPtr;
@ -93,6 +97,10 @@ using internal::ArenaStringPtr;
namespace {
bool IsMapFieldInApi(const FieldDescriptor* field) {
return field->is_map();
}
// Compute the byte size of the in-memory representation of the field.
int FieldSpaceUsed(const FieldDescriptor* field) {
typedef FieldDescriptor FD; // avoid line wrapping
@ -106,7 +114,12 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField<float >);
case FD::CPPTYPE_BOOL : return sizeof(RepeatedField<bool >);
case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >);
case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>);
case FD::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
return sizeof(MapFieldBase);
} else {
return sizeof(RepeatedPtrField<Message>);
}
case FD::CPPTYPE_STRING:
switch (field->options().ctype()) {
@ -369,7 +382,11 @@ void DynamicMessage::SharedCtor() {
if (!field->is_repeated()) {
new(field_ptr) Message*(NULL);
} else {
new(field_ptr) RepeatedPtrField<Message>();
if (IsMapFieldInApi(field)) {
new (field_ptr) MapFieldBase();
} else {
new (field_ptr) RepeatedPtrField<Message>();
}
}
break;
}
@ -456,8 +473,12 @@ DynamicMessage::~DynamicMessage() {
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
reinterpret_cast<MapFieldBase*>(field_ptr)->~MapFieldBase();
} else {
reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
->~RepeatedPtrField<Message>();
}
break;
}

@ -126,7 +126,7 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
// public header (for good reason), but dynamic_message.h is, and public
// headers may only #include other public headers.
struct PrototypeMap;
scoped_ptr<PrototypeMap> prototypes_;
google::protobuf::scoped_ptr<PrototypeMap> prototypes_;
mutable Mutex prototypes_mutex_;
friend class DynamicMessage;

@ -375,7 +375,7 @@ TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
::google::protobuf::Arena arena1;
scoped_ptr<google::protobuf::Arena> arena2(new ::google::protobuf::Arena());
google::protobuf::scoped_ptr<google::protobuf::Arena> arena2(new ::google::protobuf::Arena());
unittest::TestAllExtensions* message1 =
Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);

@ -34,13 +34,16 @@
#include <algorithm>
#include <set>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/map_field.h>
#include <google/protobuf/repeated_field.h>
#define GOOGLE_PROTOBUF_HAS_ONEOF
@ -48,6 +51,12 @@ namespace google {
namespace protobuf {
namespace internal {
namespace {
bool IsMapFieldInApi(const FieldDescriptor* field) {
return field->is_map();
}
} // anonymous namespace
int StringSpaceUsedExcludingSelf(const string& str) {
const void* start = &str;
const void* end = &str + 1;
@ -76,14 +85,7 @@ const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
namespace {
inline bool SupportsArenas(const Descriptor* descriptor) {
// In open-source release we enable arena support by default but as we also
// down-integrate descriptor.pb.(h|cc) from our internal code base which
// hasn't enabled arena support yet, here we need to be able to handle both
// cases for descriptor protos.
if (!Arena::is_arena_constructable<FileDescriptorProto>::type::value) {
return descriptor->name() != "google/protobuf/descriptor.proto";
}
return true;
return descriptor->file()->options().cc_enable_arenas();
}
} // anonymous namespace
@ -318,11 +320,17 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
total_size +=
GetRaw<MapFieldBase>(message, field).SpaceUsedExcludingSelf();
} else {
// We don't know which subclass of RepeatedPtrFieldBase the type is,
// so we use RepeatedPtrFieldBase directly.
total_size +=
GetRaw<RepeatedPtrFieldBase>(message, field)
.SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
}
break;
}
} else {
@ -406,9 +414,17 @@ void GeneratedMessageReflection::SwapField(
case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message1, field)->
MutableRepeatedField()->
Swap<GenericTypeHandler<google::protobuf::Message> >(
MutableRaw<MapFieldBase>(message2, field)->
MutableRepeatedField());
} else {
MutableRaw<RepeatedPtrFieldBase>(message1, field)->
Swap<GenericTypeHandler<google::protobuf::Message> >(
MutableRaw<RepeatedPtrFieldBase>(message2, field));
}
break;
default:
@ -728,8 +744,12 @@ int GeneratedMessageReflection::FieldSize(const Message& message,
case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
return GetRaw<MapFieldBase>(message, field).GetRepeatedField().size();
} else {
return GetRaw<RepeatedPtrFieldBase>(message, field).size();
}
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return 0;
@ -820,10 +840,16 @@ void GeneratedMessageReflection::ClearField(
}
case FieldDescriptor::CPPTYPE_MESSAGE: {
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message, field)
->MutableRepeatedField()
->Clear<GenericTypeHandler<Message> >();
} else {
// We don't know which subclass of RepeatedPtrFieldBase the type is,
// so we use RepeatedPtrFieldBase directly.
MutableRaw<RepeatedPtrFieldBase>(message, field)
->Clear<GenericTypeHandler<Message> >();
}
break;
}
}
@ -865,8 +891,14 @@ void GeneratedMessageReflection::RemoveLast(
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message, field)
->MutableRepeatedField()
->RemoveLast<GenericTypeHandler<Message> >();
} else {
MutableRaw<RepeatedPtrFieldBase>(message, field)
->RemoveLast<GenericTypeHandler<Message> >();
}
break;
}
}
@ -880,10 +912,16 @@ Message* GeneratedMessageReflection::ReleaseLast(
if (field->is_extension()) {
return static_cast<Message*>(
MutableExtensionSet(message)->ReleaseLast(field->number()));
} else {
if (IsMapFieldInApi(field)) {
return MutableRaw<MapFieldBase>(message, field)
->MutableRepeatedField()
->ReleaseLast<GenericTypeHandler<Message> >();
} else {
return MutableRaw<RepeatedPtrFieldBase>(message, field)
->ReleaseLast<GenericTypeHandler<Message> >();
}
}
}
void GeneratedMessageReflection::SwapElements(
@ -916,8 +954,14 @@ void GeneratedMessageReflection::SwapElements(
case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message, field)
->MutableRepeatedField()
->SwapElements(index1, index2);
} else {
MutableRaw<RepeatedPtrFieldBase>(message, field)
->SwapElements(index1, index2);
}
break;
}
}
@ -1518,10 +1562,16 @@ const Message& GeneratedMessageReflection::GetRepeatedMessage(
if (field->is_extension()) {
return static_cast<const Message&>(
GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
} else {
if (IsMapFieldInApi(field)) {
return GetRaw<MapFieldBase>(message, field)
.GetRepeatedField()
.Get<GenericTypeHandler<Message> >(index);
} else {
return GetRaw<RepeatedPtrFieldBase>(message, field)
.Get<GenericTypeHandler<Message> >(index);
}
}
}
Message* GeneratedMessageReflection::MutableRepeatedMessage(
@ -1532,10 +1582,16 @@ Message* GeneratedMessageReflection::MutableRepeatedMessage(
return static_cast<Message*>(
MutableExtensionSet(message)->MutableRepeatedMessage(
field->number(), index));
} else {
if (IsMapFieldInApi(field)) {
return MutableRaw<MapFieldBase>(message, field)
->MutableRepeatedField()
->Mutable<GenericTypeHandler<Message> >(index);
} else {
return MutableRaw<RepeatedPtrFieldBase>(message, field)
->Mutable<GenericTypeHandler<Message> >(index);
}
}
}
Message* GeneratedMessageReflection::AddMessage(
@ -1549,11 +1605,18 @@ Message* GeneratedMessageReflection::AddMessage(
return static_cast<Message*>(
MutableExtensionSet(message)->AddMessage(field, factory));
} else {
Message* result = NULL;
// We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
// know how to allocate one.
RepeatedPtrFieldBase* repeated =
MutableRaw<RepeatedPtrFieldBase>(message, field);
Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
RepeatedPtrFieldBase* repeated = NULL;
if (IsMapFieldInApi(field)) {
repeated =
MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
} else {
repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
}
result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
if (result == NULL) {
// We must allocate a new object.
const Message* prototype;
@ -1568,6 +1631,7 @@ Message* GeneratedMessageReflection::AddMessage(
// of AddAllocated.
repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
}
return result;
}
}
@ -1584,11 +1648,18 @@ void* GeneratedMessageReflection::MutableRawRepeatedField(
GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
if (desc != NULL)
GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
if (field->is_extension())
if (field->is_extension()) {
return MutableExtensionSet(message)->MutableRawRepeatedField(
field->number(), field->type(), field->is_packed(), field);
else
} else {
// Trigger transform for MapField
if (IsMapFieldInApi(field)) {
return reinterpret_cast<MapFieldBase*>(reinterpret_cast<uint8*>(message) +
offsets_[field->index()])
->MutableRepeatedField();
}
return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
}
}
const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
@ -2000,6 +2071,54 @@ void* GeneratedMessageReflection::RepeatedFieldData(
}
}
GeneratedMessageReflection*
GeneratedMessageReflection::NewGeneratedMessageReflection(
const Descriptor* descriptor,
const Message* default_instance,
const int offsets[],
int has_bits_offset,
int unknown_fields_offset,
int extensions_offset,
const void* default_oneof_instance,
int oneof_case_offset,
int object_size,
int arena_offset) {
return new GeneratedMessageReflection(descriptor,
default_instance,
offsets,
has_bits_offset,
unknown_fields_offset,
extensions_offset,
default_oneof_instance,
oneof_case_offset,
DescriptorPool::generated_pool(),
MessageFactory::generated_factory(),
object_size,
arena_offset);
}
GeneratedMessageReflection*
GeneratedMessageReflection::NewGeneratedMessageReflection(
const Descriptor* descriptor,
const Message* default_instance,
const int offsets[],
int has_bits_offset,
int unknown_fields_offset,
int extensions_offset,
int object_size,
int arena_offset) {
return new GeneratedMessageReflection(descriptor,
default_instance,
offsets,
has_bits_offset,
unknown_fields_offset,
extensions_offset,
DescriptorPool::generated_pool(),
MessageFactory::generated_factory(),
object_size,
arena_offset);
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -176,6 +176,32 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
int arena_offset);
~GeneratedMessageReflection();
// Shorter-to-call helpers for the above two constructions that work if the
// pool and factory are the usual, namely, DescriptorPool::generated_pool()
// and MessageFactory::generated_factory().
static GeneratedMessageReflection* NewGeneratedMessageReflection(
const Descriptor* descriptor,
const Message* default_instance,
const int offsets[],
int has_bits_offset,
int unknown_fields_offset,
int extensions_offset,
const void* default_oneof_instance,
int oneof_case_offset,
int object_size,
int arena_offset);
static GeneratedMessageReflection* NewGeneratedMessageReflection(
const Descriptor* descriptor,
const Message* default_instance,
const int offsets[],
int has_bits_offset,
int unknown_fields_offset,
int extensions_offset,
int object_size,
int arena_offset);
// implements Reflection -------------------------------------------
const UnknownFieldSet& GetUnknownFields(const Message& message) const;

@ -36,6 +36,7 @@
#include <limits>
namespace google {
namespace protobuf {
namespace internal {

@ -0,0 +1,282 @@
// 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_MAP_H__
#define GOOGLE_PROTOBUF_MAP_H__
#include <vector>
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/stubs/hash.h>
namespace google {
namespace protobuf {
template <typename Key, typename T>
class Map;
template <typename Enum> struct is_proto_enum;
namespace internal {
template <typename K, typename V, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
class MapField;
}
// This is the class for google::protobuf::Map's internal value_type. Instead of using
// std::pair as value_type, we use this class which provides us more control of
// its process of construction and destruction.
template <typename Key, typename T>
class MapPair {
public:
typedef Key first_type;
typedef T second_type;
MapPair(const Key& other_first, const T& other_second)
: first(other_first), second(other_second) {}
MapPair(const Key& other_first) : first(other_first), second() {}
MapPair(const MapPair& other)
: first(other.first), second(other.second) {}
MapPair& operator=(const MapPair& other) {
first = other.first;
second = other.second;
return *this;
}
~MapPair() {}
const Key first;
T second;
private:
friend class Map<Key, T>;
};
// STL-like iterator implementation for google::protobuf::Map. Users should not refer to
// this class directly; use google::protobuf::Map<Key, T>::iterator instead.
template <typename Key, typename T>
class MapIterator {
public:
typedef MapPair<Key, T> value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef MapIterator iterator;
// constructor
MapIterator(const typename hash_map<Key, value_type*>::iterator& it)
: it_(it) {}
MapIterator(const MapIterator& other) : it_(other.it_) {}
MapIterator& operator=(const MapIterator& other) {
it_ = other.it_;
return *this;
}
// deferenceable
reference operator*() const { return *it_->second; }
pointer operator->() const { return it_->second; }
// incrementable
iterator& operator++() {
++it_;
return *this;
}
iterator operator++(int) { return iterator(it_++); }
// equality_comparable
bool operator==(const iterator& x) const { return it_ == x.it_; }
bool operator!=(const iterator& x) const { return it_ != x.it_; }
private:
typename hash_map<Key, value_type*>::iterator it_;
friend Map<Key, T>;
};
// google::protobuf::Map is an associative container type used to store protobuf map
// fields. Its interface is similar to std::unordered_map. Users should use this
// interface directly to visit or change map fields.
template <typename Key, typename T>
class Map {
typedef internal::MapCppTypeHandler<T> ValueTypeHandler;
public:
typedef Key key_type;
typedef T mapped_type;
typedef MapPair<Key, T> value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef MapIterator<Key, T> iterator;
typedef MapIterator<Key, T> const_iterator;
typedef size_t size_type;
typedef hash<Key> hasher;
Map() : default_enum_value_(0) {}
Map(const Map& other) {
insert(other.begin(), other.end());
}
~Map() { clear(); }
// Iterators
iterator begin() { return iterator(elements_.begin()); }
iterator end() { return iterator(elements_.end()); }
const_iterator begin() const {
return const_iterator(
const_cast<hash_map<Key, value_type*>&>(elements_).begin());
}
const_iterator end() const {
return const_iterator(
const_cast<hash_map<Key, value_type*>&>(elements_).end());
}
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
// Capacity
size_type size() const { return elements_.size(); }
bool empty() const { return elements_.empty(); }
// Element access
T& operator[](const key_type& key) {
value_type** value = &elements_[key];
if (*value == NULL) {
*value = new value_type(key);
internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
T>::Initialize((*value)->second,
default_enum_value_);
}
return (*value)->second;
}
const T& at(const key_type& key) const {
const_iterator it = find(key);
GOOGLE_CHECK(it != end());
return it->second;
}
T& at(const key_type& key) {
iterator it = find(key);
GOOGLE_CHECK(it != end());
return it->second;
}
// Lookup
size_type count(const key_type& key) const {
return elements_.count(key);
}
const_iterator find(const key_type& key) const {
// When elements_ is a const instance, find(key) returns a const iterator.
// However, to reduce code complexity, we use MapIterator for Map's both
// const and non-const iterator, which only takes non-const iterator to
// construct.
return const_iterator(
const_cast<hash_map<Key, value_type*>&>(elements_).find(key));
}
iterator find(const key_type& key) {
return iterator(elements_.find(key));
}
// insert
std::pair<iterator, bool> insert(const value_type& value) {
iterator it = find(value.first);
if (it != end()) {
return std::pair<iterator, bool>(it, false);
} else {
return elements_.insert(
std::pair<Key, value_type*>(value.first, new value_type(value)));
}
}
template <class InputIt>
void insert(InputIt first, InputIt last) {
for (InputIt it = first; it != last; ++it) {
iterator exist_it = find(it->first);
if (exist_it == end()) {
operator[](it->first) = it->second;
}
}
}
// Erase
size_type erase(const key_type& key) {
typename hash_map<Key, value_type*>::iterator it = elements_.find(key);
if (it == elements_.end()) {
return 0;
} else {
delete it->second;
elements_.erase(it);
return 1;
}
}
void erase(iterator pos) {
delete pos.it_->second;
elements_.erase(pos.it_);
}
void erase(iterator first, iterator last) {
for (iterator it = first; it != last;) {
delete it.it_->second;
elements_.erase((it++).it_);
}
}
void clear() {
for (iterator it = begin(); it != end(); ++it) {
delete it.it_->second;
}
elements_.clear();
}
// Assign
Map& operator=(const Map& other) {
insert(other.begin(), other.end());
return *this;
}
private:
// Set default enum value only for proto2 map field whose value is enum type.
void SetDefaultEnumValue(int default_enum_value) {
default_enum_value_ = default_enum_value;
}
hash_map<Key, value_type*> elements_;
int default_enum_value_;
template <typename K, typename V, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum>
friend class LIBPROTOBUF_EXPORT internal::MapField;
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MAP_H__

@ -0,0 +1,449 @@
// 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_MAP_ENTRY_H__
#define GOOGLE_PROTOBUF_MAP_ENTRY_H__
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
namespace protobuf {
class Arena;
}
namespace protobuf {
namespace internal {
// 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 {
public:
::google::protobuf::Metadata GetMetadata() const {
::google::protobuf::Metadata metadata;
metadata.descriptor = descriptor_;
metadata.reflection = reflection_;
return metadata;
}
protected:
MapEntryBase() : descriptor_(NULL), reflection_(NULL) { }
virtual ~MapEntryBase() {}
const Descriptor* descriptor_;
const Reflection* reflection_;
};
// MapEntry is the returned google::protobuf::Message when calling AddMessage of
// google::protobuf::Reflection. In order to let it work with generated message
// reflection, its internal layout is the same as generated message with the
// same fields. However, in order to decide the internal layout of key/value, we
// need to know both their cpp type in generated api and proto type.
//
// cpp type | proto type | internal layout
// int32 TYPE_INT32 int32
// int32 TYPE_FIXED32 int32
// FooEnum TYPE_ENUM int
// FooMessage TYPE_MESSAGE FooMessage*
//
// The internal layouts of primitive types can be inferred from its proto type,
// while we need to explicitly tell cpp type if proto type is TYPE_MESSAGE to
// get internal layout.
// 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 {
// Handlers for key/value's proto field type. Used to infer internal layout
// and provide parsing/serialization support.
typedef MapProtoTypeHandler<KeyProtoType> KeyProtoHandler;
typedef MapProtoTypeHandler<ValueProtoType> ValueProtoHandler;
// Define key/value's internal stored type. Message is the only one whose
// internal stored type cannot be inferred from its proto type.
typedef typename KeyProtoHandler::CppType KeyProtoHandlerCppType;
typedef typename ValueProtoHandler::CppType ValueProtoHandlerCppType;
static const bool kIsKeyMessage = KeyProtoHandler::kIsMessage;
static const bool kIsValueMessage = ValueProtoHandler::kIsMessage;
typedef typename MapIf<kIsKeyMessage, Key, KeyProtoHandlerCppType>::type
KeyCppType;
typedef typename MapIf<kIsValueMessage, Value, ValueProtoHandlerCppType>::type
ValCppType;
// Handlers for key/value's internal stored type. Provide utilities to
// manipulate internal stored type. We need it because some types are stored
// as values and others are stored as pointers (Message and string), but we
// need to keep the code in MapEntry unified instead of providing different
// codes for each type.
typedef MapCppTypeHandler<KeyCppType> KeyCppHandler;
typedef MapCppTypeHandler<ValCppType> ValueCppHandler;
// Define internal memory layout. Strings and messages are stored as
// pointers, while other types are stored as values.
static const bool kKeyIsStringOrMessage = KeyCppHandler::kIsStringOrMessage;
static const bool kValIsStringOrMessage = ValueCppHandler::kIsStringOrMessage;
typedef typename MapIf<kKeyIsStringOrMessage, KeyCppType*, KeyCppType>::type
KeyBase;
typedef typename MapIf<kValIsStringOrMessage, ValCppType*, ValCppType>::type
ValueBase;
// Abbreviation for MapEntry
typedef typename google::protobuf::internal::MapEntry<
Key, Value, KeyProtoType, ValueProtoType, default_enum_value> EntryType;
// Constants for field number.
static const int kKeyFieldNumber = 1;
static const int kValueFieldNumber = 2;
// Constants for field tag.
static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
kKeyFieldNumber, KeyProtoHandler::kWireType);
static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
kValueFieldNumber, ValueProtoHandler::kWireType);
static const int kTagSize = 1;
public:
~MapEntry() {
if (this == default_instance_) {
delete reflection_;
} else {
KeyCppHandler::Delete(key_);
ValueCppHandler::Delete(value_);
}
}
// accessors ======================================================
inline void set_key(const KeyCppType& key) {
KeyCppHandler::EnsureMutable(&key_);
KeyCppHandler::Merge(key, &key_);
set_has_key();
}
virtual inline const KeyCppType& key() const {
return KeyCppHandler::Reference(key_);
}
inline KeyCppType* mutable_key() {
set_has_key();
KeyCppHandler::EnsureMutable(&key_);
return KeyCppHandler::Pointer(key_);
}
inline void set_value(const ValCppType& value) {
ValueCppHandler::EnsureMutable(&value_);
ValueCppHandler::Merge(value, &value_);
set_has_value();
}
virtual inline const ValCppType& value() const {
GOOGLE_CHECK(default_instance_ != NULL);
return ValueCppHandler::DefaultIfNotInitialized(value_,
default_instance_->value_);
}
inline ValCppType* mutable_value() {
set_has_value();
ValueCppHandler::EnsureMutable(&value_);
return ValueCppHandler::Pointer(value_);
}
// implements Message =============================================
bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
uint32 tag;
for (;;) {
// 1) corrupted data: return false;
// 2) unknown field: skip without putting into unknown field set;
// 3) unknown enum value: keep it in parsing. In proto2, caller should
// check the value and put this entry into containing message's unknown
// field set if the value is an unknown enum. In proto3, caller doesn't
// need to care whether the value is unknown enum;
// 4) missing key/value: missed key/value will have default value. caller
// should take this entry as if key/value is set to default value.
tag = input->ReadTag();
switch (tag) {
case kKeyTag:
if (!KeyProtoHandler::Read(input, mutable_key())) return false;
set_has_key();
if (!input->ExpectTag(kValueTag)) break;
GOOGLE_FALLTHROUGH_INTENDED;
case kValueTag:
if (!ValueProtoHandler::Read(input, mutable_value())) return false;
set_has_value();
if (input->ExpectAtEnd()) return true;
break;
default:
if (tag == 0 ||
WireFormatLite::GetTagWireType(tag) ==
WireFormatLite::WIRETYPE_END_GROUP) {
return true;
}
if (!WireFormatLite::SkipField(input, tag)) return false;
break;
}
}
}
int ByteSize() const {
int size = 0;
size += has_key() ? kTagSize + KeyProtoHandler::ByteSize(key()) : 0;
size += has_value() ? kTagSize + ValueProtoHandler::ByteSize(value()) : 0;
return size;
}
void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
KeyProtoHandler::Write(kKeyFieldNumber, key(), output);
ValueProtoHandler::Write(kValueFieldNumber, value(), output);
}
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
output = KeyProtoHandler::WriteToArray(kKeyFieldNumber, key(), output);
output =
ValueProtoHandler::WriteToArray(kValueFieldNumber, value(), output);
return output;
}
int GetCachedSize() const {
int size = 0;
size += has_key() ? kTagSize + KeyProtoHandler::GetCachedSize(key()) : 0;
size +=
has_value() ? kTagSize + ValueProtoHandler::GetCachedSize(value()) : 0;
return size;
}
bool IsInitialized() const { return ValueCppHandler::IsInitialized(value_); }
Message* New() const {
MapEntry* entry = new MapEntry;
entry->descriptor_ = descriptor_;
entry->reflection_ = reflection_;
entry->default_instance_ = default_instance_;
return entry;
}
int SpaceUsed() const {
int size = sizeof(MapEntry);
size += KeyCppHandler::SpaceUsedInMapEntry(key_);
size += ValueCppHandler::SpaceUsedInMapEntry(value_);
return size;
}
void CopyFrom(const ::google::protobuf::Message& from) {
Clear();
MergeFrom(from);
}
void MergeFrom(const ::google::protobuf::Message& from) {
GOOGLE_CHECK_NE(&from, this);
const MapEntry* source = dynamic_cast_if_available<const MapEntry*>(&from);
if (source == NULL) {
ReflectionOps::Merge(from, this);
} else {
MergeFrom(*source);
}
}
void CopyFrom(const MapEntry& from) {
Clear();
MergeFrom(from);
}
void MergeFrom(const MapEntry& from) {
if (from._has_bits_[0]) {
if (from.has_key()) {
KeyCppHandler::EnsureMutable(&key_);
KeyCppHandler::Merge(from.key(), &key_);
set_has_key();
}
if (from.has_value()) {
ValueCppHandler::EnsureMutable(&value_);
ValueCppHandler::Merge(from.value(), &value_);
set_has_value();
}
}
}
void Clear() {
KeyCppHandler::Clear(&key_);
ValueCppHandler::ClearMaybeByDefaultEnum(&value_, default_enum_value);
clear_has_key();
clear_has_value();
}
void InitAsDefaultInstance() {
KeyCppHandler::AssignDefaultValue(&key_);
ValueCppHandler::AssignDefaultValue(&value_);
}
// Create default MapEntry instance for given descriptor. Descriptor has to be
// given when creating default MapEntry instance because different map field
// may have the same type and MapEntry class. The given descriptor is needed
// to distinguish instances of the same MapEntry class.
static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) {
MapEntry* entry = new MapEntry();
const Reflection* reflection = new GeneratedMessageReflection(
descriptor, entry, offsets_,
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _has_bits_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(), sizeof(MapEntry), -1);
entry->descriptor_ = descriptor;
entry->reflection_ = reflection;
entry->default_instance_ = entry;
entry->InitAsDefaultInstance();
return entry;
}
// Create a MapEntry for given key and value from google::protobuf::Map in
// serialization. This function is only called when value is enum. Enum is
// treated differently because its type in MapEntry is int and its type in
// google::protobuf::Map is enum. We cannot create a reference to int from an enum.
static MapEntry* EnumWrap(const Key& key, const Value value) {
return new MapEnumEntryWrapper<Key, Value, KeyProtoType, ValueProtoType,
default_enum_value>(key, value);
}
// Like above, but for all the other types. This avoids value copy to create
// MapEntry from google::protobuf::Map in serialization.
static MapEntry* Wrap(const Key& key, const Value& value) {
return new MapEntryWrapper<Key, Value, KeyProtoType, ValueProtoType,
default_enum_value>(key, value);
}
protected:
void set_has_key() { _has_bits_[0] |= 0x00000001u; }
bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
void clear_has_key() { _has_bits_[0] &= ~0x00000001u; }
void set_has_value() { _has_bits_[0] |= 0x00000002u; }
bool has_value() const { return (_has_bits_[0] & 0x00000002u) != 0; }
void clear_has_value() { _has_bits_[0] &= ~0x00000002u; }
private:
// Serializing a generated message containing map field involves serializing
// key-value pairs from google::protobuf::Map. The wire format of each key-value pair
// after serialization should be the same as that of a MapEntry message
// containing the same key and value inside it. However, google::protobuf::Map doesn't
// store key and value as MapEntry message, which disables us to use existing
// code to serialize message. In order to use existing code to serialize
// message, we need to construct a MapEntry from key-value pair. But it
// involves copy of key and value to construct a MapEntry. In order to avoid
// this copy in constructing a MapEntry, we need the following class which
// only takes references of given key and value.
template <typename KeyNested, typename ValueNested,
FieldDescriptor::Type KeyProtoNested,
FieldDescriptor::Type ValueProtoNested, int default_enum>
class LIBPROTOBUF_EXPORT MapEntryWrapper
: public MapEntry<KeyNested, ValueNested, KeyProtoNested,
ValueProtoNested, default_enum> {
typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
default_enum_value> Base;
typedef typename Base::KeyCppType KeyCppType;
typedef typename Base::ValCppType ValCppType;
public:
MapEntryWrapper(const KeyNested& key, const ValueNested& value)
: key_(key), value_(value) {
Base::set_has_key();
Base::set_has_value();
}
inline const KeyCppType& key() const { return key_; }
inline const ValCppType& value() const { return value_; }
private:
const Key& key_;
const Value& value_;
};
// Like above, but for enum value only, which stores value instead of
// reference of value field inside. This is needed because the type of value
// field in constructor is an enum, while we need to store it as an int. If we
// initialize a reference to int with a reference to enum, compiler will
// generate a temporary int from enum and initialize the reference to int with
// the temporary.
template <typename KeyNested, typename ValueNested,
FieldDescriptor::Type KeyProtoNested,
FieldDescriptor::Type ValueProtoNested, int default_enum>
class LIBPROTOBUF_EXPORT MapEnumEntryWrapper
: public MapEntry<KeyNested, ValueNested, KeyProtoNested,
ValueProtoNested, default_enum> {
typedef MapEntry<KeyNested, ValueNested, KeyProtoNested, ValueProtoNested,
default_enum> Base;
typedef typename Base::KeyCppType KeyCppType;
typedef typename Base::ValCppType ValCppType;
public:
MapEnumEntryWrapper(const KeyNested& key, const ValueNested& value)
: key_(key), value_(value) {
Base::set_has_key();
Base::set_has_value();
}
inline const KeyCppType& key() const { return key_; }
inline const ValCppType& value() const { return value_; }
private:
const KeyCppType& key_;
const ValCppType value_;
};
MapEntry() : default_instance_(NULL) {
KeyCppHandler::Initialize(&key_);
ValueCppHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value);
_has_bits_[0] = 0;
}
KeyBase key_;
ValueBase value_;
static int offsets_[2];
UnknownFieldSet _unknown_fields_;
uint32 _has_bits_[1];
MapEntry* default_instance_;
friend class ::google::protobuf::Arena;
template <typename K, typename V,
FieldDescriptor::Type KType,
FieldDescriptor::Type VType, int default_enum>
friend class LIBPROTOBUF_EXPORT internal::MapField;
friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
};
template <typename Key, typename Value, FieldDescriptor::Type KeyProtoType,
FieldDescriptor::Type ValueProtoType, int default_enum_value>
int MapEntry<Key, Value, KeyProtoType, ValueProtoType,
default_enum_value>::offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, key_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, value_),
};
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MAP_ENTRY_H__

@ -0,0 +1,113 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/map_field.h>
namespace google {
namespace protobuf {
namespace internal {
MapFieldBase::~MapFieldBase() {
if (repeated_field_ != NULL) delete repeated_field_;
}
const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
SyncRepeatedFieldWithMap();
return *repeated_field_;
}
RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
SyncRepeatedFieldWithMap();
SetRepeatedDirty();
return repeated_field_;
}
int MapFieldBase::SpaceUsedExcludingSelf() const {
mutex_.Lock();
int size = SpaceUsedExcludingSelfNoLock();
mutex_.Unlock();
return size;
}
int MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
if (repeated_field_ != NULL) {
return repeated_field_->SpaceUsedExcludingSelf();
} else {
return 0;
}
}
void MapFieldBase::InitMetadataOnce() const {
GOOGLE_CHECK(entry_descriptor_ != NULL);
GOOGLE_CHECK(assign_descriptor_callback_ != NULL);
(*assign_descriptor_callback_)();
}
void MapFieldBase::SetMapDirty() { state_ = STATE_MODIFIED_MAP; }
void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; }
void* MapFieldBase::MutableRepeatedPtrField() const { return repeated_field_; }
void MapFieldBase::SyncRepeatedFieldWithMap() const {
Atomic32 state = google::protobuf::internal::NoBarrier_Load(&state_);
if (state == STATE_MODIFIED_MAP) {
mutex_.Lock();
// Double check state, because another thread may have seen the same state
// and done the synchronization before the current thread.
if (state_ == STATE_MODIFIED_MAP) {
SyncRepeatedFieldWithMapNoLock();
google::protobuf::internal::NoBarrier_Store(&state_, CLEAN);
}
mutex_.Unlock();
}
}
void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
if (repeated_field_ == NULL) repeated_field_ = new RepeatedPtrField<Message>;
}
void MapFieldBase::SyncMapWithRepeatedField() const {
Atomic32 state = google::protobuf::internal::NoBarrier_Load(&state_);
if (state == STATE_MODIFIED_REPEATED) {
mutex_.Lock();
// Double check state, because another thread may have seen the same state
// and done the synchronization before the current thread.
if (state_ == STATE_MODIFIED_REPEATED) {
SyncMapWithRepeatedFieldNoLock();
google::protobuf::internal::NoBarrier_Store(&state_, CLEAN);
}
mutex_.Unlock();
}
}
} // namespace internal
} // namespace protobuf
} // namespace google

@ -0,0 +1,220 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_MAP_FIELD_H__
#define GOOGLE_PROTOBUF_MAP_FIELD_H__
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/map.h>
#include <google/protobuf/map_entry.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/unknown_field_set.h>
namespace google {
namespace protobuf {
namespace internal {
class ContendedMapCleanTest;
class GeneratedMessageReflection;
class MapFieldAccessor;
// This class provides accesss to map field using reflection, which is the same
// as those provided for RepeatedPtrField<Message>. It is used for internal
// reflection implentation only. Users should never use this directly.
class LIBPROTOBUF_EXPORT MapFieldBase {
public:
MapFieldBase()
: base_map_(NULL),
repeated_field_(NULL),
entry_descriptor_(NULL),
assign_descriptor_callback_(NULL),
state_(STATE_MODIFIED_MAP) {}
virtual ~MapFieldBase();
// Returns reference to internal repeated field. Data written using
// google::protobuf::Map's api prior to calling this function is guarantted to be
// included in repeated field.
const RepeatedPtrFieldBase& GetRepeatedField() const;
// Like above. Returns mutable pointer to the internal repeated field.
RepeatedPtrFieldBase* MutableRepeatedField();
// Returns the number of bytes used by the repeated field, excluding
// sizeof(*this)
int SpaceUsedExcludingSelf() const;
protected:
// Gets the size of space used by map field.
virtual int SpaceUsedExcludingSelfNoLock() const;
// Synchronizes the content in Map to RepeatedPtrField if there is any change
// to Map after last synchronization.
void SyncRepeatedFieldWithMap() const;
virtual void SyncRepeatedFieldWithMapNoLock() const;
// Synchronizes the content in RepeatedPtrField to Map if there is any change
// to RepeatedPtrField after last synchronization.
void SyncMapWithRepeatedField() const;
virtual void SyncMapWithRepeatedFieldNoLock() const {}
// Tells MapFieldBase that there is new change to Map.
void SetMapDirty();
// Tells MapFieldBase that there is new change to RepeatedPTrField.
void SetRepeatedDirty();
// Provides derived class the access to repeated field.
void* MutableRepeatedPtrField() const;
// Creates descriptor for only one time.
void InitMetadataOnce() const;
enum State {
STATE_MODIFIED_MAP = 0, // map has newly added data that has not been
// synchronized to repeated field
STATE_MODIFIED_REPEATED = 1, // repeated field has newly added data that
// has not been synchronized to map
CLEAN = 2, // data in map and repeated field are same
};
mutable void* base_map_;
mutable RepeatedPtrField<Message>* repeated_field_;
// MapEntry can only be created from MapField. To create MapEntry, MapField
// needs to know its descriptor, because MapEntry is not generated class which
// cannot initialize its own descriptor by calling generated
// descriptor-assign-function. Thus, we need to register a callback to
// initialize MapEntry's descriptor.
const Descriptor** entry_descriptor_;
void (*assign_descriptor_callback_)();
mutable Mutex mutex_; // The thread to synchronize map and repeated field
// needs to get lock first;
mutable volatile Atomic32 state_; // 0: STATE_MODIFIED_MAP
// 1: STATE_MODIFIED_REPEATED
// 2: CLEAN
private:
friend class ContendedMapCleanTest;
friend class GeneratedMessageReflection;
friend class MapFieldAccessor;
};
// This class provides accesss to map field using generated api. It is used for
// internal generated message implentation only. Users should never use this
// directly.
template<typename Key, typename T,
FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value = 0>
class LIBPROTOBUF_EXPORT MapField : public MapFieldBase {
// Handlers for key/value's proto field type.
typedef MapProtoTypeHandler<KeyProto> KeyProtoHandler;
typedef MapProtoTypeHandler<ValueProto> ValueProtoHandler;
// Define key/value's internal stored type.
typedef typename KeyProtoHandler::CppType KeyHandlerCpp;
typedef typename ValueProtoHandler::CppType ValHandlerCpp;
static const bool kIsKeyMessage = KeyProtoHandler::kIsMessage;
static const bool kIsValMessage = ValueProtoHandler::kIsMessage;
typedef typename MapIf<kIsKeyMessage, Key, KeyHandlerCpp>::type KeyCpp;
typedef typename MapIf<kIsValMessage, T , ValHandlerCpp>::type ValCpp;
// Handlers for key/value's internal stored type.
typedef MapCppTypeHandler<KeyCpp> KeyHandler;
typedef MapCppTypeHandler<ValCpp> ValHandler;
// Define message type for internal repeated field.
typedef MapEntry<Key, T, KeyProto, ValueProto, default_enum_value> EntryType;
// Enum needs to be handled differently from other types because it has
// different exposed type in google::protobuf::Map's api and repeated field's api. For
// details see the comment in the implementation of
// SyncMapWithRepeatedFieldNoLocki.
static const bool kIsValueEnum = ValueProtoHandler::kIsEnum;
typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
public:
MapField();
// MapField doesn't own the default_entry, which means default_entry must
// outlive the lifetime of MapField.
MapField(const Message* default_entry);
~MapField();
// Accessors
const Map<Key, T>& GetMap() const;
Map<Key, T>* MutableMap();
// Convenient methods for generated message implementation.
int size() const;
void Clear();
void MergeFrom(const MapField& other);
void Swap(MapField* other);
// Allocates metadata only if this MapField is part of a generated message.
void SetEntryDescriptor(const Descriptor** descriptor);
void SetAssignDescriptorCallback(void (*callback)());
// Set default enum value only for proto2 map field whose value is enum type.
void SetDefaultEnumValue();
// Used in the implementation of parsing. Caller should take the ownership.
EntryType* NewEntry() const;
// Used in the implementation of serializing enum value type. Caller should
// take the ownership.
EntryType* NewEnumEntryWrapper(const Key& key, const T t) const;
// Used in the implementation of serializing other value types. Caller should
// take the ownership.
EntryType* NewEntryWrapper(const Key& key, const T& t) const;
private:
// MapField needs MapEntry's default instance to create new MapEntry.
void InitDefaultEntryOnce() const;
// Convenient methods to get internal google::protobuf::Map
const Map<Key, T>& GetInternalMap() const;
Map<Key, T>* MutableInternalMap();
// Implements MapFieldBase
void SyncRepeatedFieldWithMapNoLock() const;
void SyncMapWithRepeatedFieldNoLock() const;
int SpaceUsedExcludingSelfNoLock() const;
mutable const EntryType* default_entry_;
};
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MAP_FIELD_H__

@ -0,0 +1,269 @@
// 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_MAP_FIELD_INL_H__
#define GOOGLE_PROTOBUF_MAP_FIELD_INL_H__
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <google/protobuf/map_field.h>
#include <google/protobuf/map_type_handler.h>
namespace google {
namespace protobuf {
namespace internal {
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MapField()
: default_entry_(NULL) {
MapFieldBase::base_map_ = new Map<Key, T>;
SetDefaultEnumValue();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MapField(
const Message* default_entry)
: default_entry_(down_cast<const EntryType*>(default_entry)) {
MapFieldBase::base_map_ = new Map<Key, T>;
SetDefaultEnumValue();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::~MapField() {
delete reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
int MapField<Key, T, KeyProto, ValueProto, default_enum_value>::size() const {
SyncMapWithRepeatedField();
return GetInternalMap().size();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::Clear() {
SyncMapWithRepeatedField();
MutableInternalMap()->clear();
SetMapDirty();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
const Map<Key, T>&
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::GetMap() const {
SyncMapWithRepeatedField();
return GetInternalMap();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
Map<Key, T>*
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MutableMap() {
SyncMapWithRepeatedField();
Map<Key, T>* result = MutableInternalMap();
SetMapDirty();
return result;
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::MergeFrom(
const MapField& other) {
SyncMapWithRepeatedField();
other.SyncMapWithRepeatedField();
Map<Key, T>* map = MutableInternalMap();
const Map<Key, T>& other_map = other.GetInternalMap();
for (typename Map<Key, T>::const_iterator it = other_map.begin();
it != other_map.end(); ++it) {
(*map)[it->first] = it->second;
}
SetMapDirty();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto, default_enum_value>::Swap(
MapField* other) {
std::swap(repeated_field_, other->repeated_field_);
std::swap(base_map_, other->base_map_);
std::swap(state_, other->state_);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::SetEntryDescriptor(
const Descriptor** descriptor) {
entry_descriptor_ = descriptor;
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void
MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) {
assign_descriptor_callback_ = callback;
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::SetDefaultEnumValue() {
MutableInternalMap()->SetDefaultEnumValue(default_enum_value);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEntry() const {
// The MapEntry instance created here is only used in generated code for
// parsing. It doesn't have default instance, descriptor or reflection,
// because these are not needed in parsing and will prevent us from using it
// for parsing MessageLite.
return new EntryType();
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEntryWrapper(
const Key& key, const T& t) const {
return EntryType::Wrap(key, t);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
MapEntry<Key, T, KeyProto, ValueProto, default_enum_value>*
MapField<Key, T, KeyProto, ValueProto, default_enum_value>::NewEnumEntryWrapper(
const Key& key, const T t) const {
return EntryType::EnumWrap(key, t);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
const Map<Key, T>& MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::GetInternalMap() const {
return *reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
Map<Key, T>* MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::MutableInternalMap() {
return reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
if (repeated_field_ == NULL) {
repeated_field_ = new RepeatedPtrField<Message>();
}
const Map<Key, T>& map =
*static_cast<const Map<Key, T>*>(MapFieldBase::base_map_);
RepeatedPtrField<EntryType>* repeated_field =
reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
repeated_field->Clear();
for (typename Map<Key, T>::const_iterator it = map.begin();
it != map.end(); ++it) {
InitDefaultEntryOnce();
GOOGLE_CHECK(default_entry_ != NULL);
EntryType* new_entry = down_cast<EntryType*>(default_entry_->New());
repeated_field->AddAllocated(new_entry);
new_entry->set_key(it->first);
new_entry->set_value(it->second);
}
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
Map<Key, T>* map = reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
RepeatedPtrField<EntryType>* repeated_field =
reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
map->clear();
for (typename RepeatedPtrField<EntryType>::iterator it =
repeated_field->begin(); it != repeated_field->end(); ++it) {
// Cast is needed because Map's api and internal storage is different when
// value is enum. For enum, we cannot cast an int to enum. Thus, we have to
// copy value. For other types, they have same exposed api type and internal
// stored type. We should not introduce value copy for them. We achieve this
// by casting to value for enum while casting to reference for other types.
(*map)[it->key()] = static_cast<CastValueType>(it->value());
}
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
int MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
int size = 0;
if (repeated_field_ != NULL) {
size += repeated_field_->SpaceUsedExcludingSelf();
}
Map<Key, T>* map = reinterpret_cast<Map<Key, T>*>(MapFieldBase::base_map_);
size += sizeof(*map);
for (typename Map<Key, T>::iterator it = map->begin();
it != map->end(); ++it) {
size += KeyHandler::SpaceUsedInMap(it->first);
size += ValHandler::SpaceUsedInMap(it->second);
}
return size;
}
template <typename Key, typename T, FieldDescriptor::Type KeyProto,
FieldDescriptor::Type ValueProto, int default_enum_value>
void MapField<Key, T, KeyProto, ValueProto,
default_enum_value>::InitDefaultEntryOnce() const {
if (default_entry_ == NULL) {
InitMetadataOnce();
GOOGLE_CHECK(*entry_descriptor_ != NULL);
default_entry_ = down_cast<const EntryType*>(
MessageFactory::generated_factory()->GetPrototype(*entry_descriptor_));
}
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MAP_FIELD_INL_H__

@ -0,0 +1,470 @@
// 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 <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/map.h>
#include <google/protobuf/map_unittest.pb.h>
#include <google/protobuf/map_test_util.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/map_field_inl.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace internal {
using unittest::TestAllTypes;
class MapFieldBaseStub : public MapFieldBase {
public:
void SyncRepeatedFieldWithMap() const {
MapFieldBase::SyncRepeatedFieldWithMap();
}
void SyncMapWithRepeatedField() const {
MapFieldBase::SyncMapWithRepeatedField();
}
// Get underlined repeated field without synchronizing map.
RepeatedPtrField<Message>* InternalRepeatedField() {
return repeated_field_;
}
// Get underlined map without synchronizing repeated field.
template <typename MapType>
const MapType& GetMap() {
return *reinterpret_cast<MapType*>(base_map_);
}
// Get underlined map without synchronizing repeated field.
template <typename MapType>
MapType* MutableMap() {
return reinterpret_cast<MapType*>(base_map_);
}
bool IsMapClean() { return state_ != 0; }
bool IsRepeatedClean() { return state_ != 1; }
void SetMapDirty() { state_ = 0; }
void SetRepeatedDirty() { state_ = 1; }
};
class MapFieldBasePrimitiveTest : public ::testing::Test {
protected:
typedef MapField<int32, int32, FieldDescriptor::TYPE_INT32,
FieldDescriptor::TYPE_INT32> MapFieldType;
MapFieldBasePrimitiveTest() {
// Get descriptors
map_descriptor_ = unittest::TestMap::descriptor()
->FindFieldByName("map_int32_int32")
->message_type();
key_descriptor_ = map_descriptor_->FindFieldByName("key");
value_descriptor_ = map_descriptor_->FindFieldByName("value");
// Build map field
default_entry_ =
MessageFactory::generated_factory()->GetPrototype(map_descriptor_);
map_field_.reset(new MapFieldType(default_entry_));
map_field_base_ = map_field_.get();
map_ = map_field_->MutableMap();
initial_value_map_[0] = 100;
initial_value_map_[1] = 101;
map_->insert(initial_value_map_.begin(), initial_value_map_.end());
EXPECT_EQ(2, map_->size());
}
google::protobuf::scoped_ptr<MapFieldType> map_field_;
MapFieldBase* map_field_base_;
Map<int32, int32>* map_;
const Descriptor* map_descriptor_;
const FieldDescriptor* key_descriptor_;
const FieldDescriptor* value_descriptor_;
const Message* default_entry_;
std::map<int32, int32> initial_value_map_; // copy of initial values inserted
};
TEST_F(MapFieldBasePrimitiveTest, SpaceUsedExcludingSelf) {
EXPECT_LT(0, map_field_base_->SpaceUsedExcludingSelf());
}
TEST_F(MapFieldBasePrimitiveTest, GetRepeatedField) {
const RepeatedPtrField<Message>& repeated =
reinterpret_cast<const RepeatedPtrField<Message>&>(
map_field_base_->GetRepeatedField());
EXPECT_EQ(2, repeated.size());
for (int i = 0; i < repeated.size(); i++) {
const Message& message = repeated.Get(i);
int key = message.GetReflection()->GetInt32(message, key_descriptor_);
int value = message.GetReflection()->GetInt32(message, value_descriptor_);
EXPECT_EQ(value, initial_value_map_[key]);
}
}
TEST_F(MapFieldBasePrimitiveTest, MutableRepeatedField) {
RepeatedPtrField<Message>* repeated =
reinterpret_cast<RepeatedPtrField<Message>*>(
map_field_base_->MutableRepeatedField());
EXPECT_EQ(2, repeated->size());
for (int i = 0; i < repeated->size(); i++) {
const Message& message = repeated->Get(i);
int key = message.GetReflection()->GetInt32(message, key_descriptor_);
int value = message.GetReflection()->GetInt32(message, value_descriptor_);
EXPECT_EQ(value, initial_value_map_[key]);
}
}
namespace {
enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
} // anonymous namespace
class MapFieldStateTest
: public testing::TestWithParam<State> {
public:
protected:
typedef MapField<int32, int32, FieldDescriptor::TYPE_INT32,
FieldDescriptor::TYPE_INT32> MapFieldType;
MapFieldStateTest() : state_(GetParam()) {
// Build map field
const Descriptor* map_descriptor =
unittest::TestMap::descriptor()
->FindFieldByName("map_int32_int32")
->message_type();
default_entry_ =
MessageFactory::generated_factory()->GetPrototype(map_descriptor);
map_field_.reset(new MapFieldType(default_entry_));
map_field_base_ = map_field_.get();
Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
switch (state_) {
case CLEAN:
AddOneStillClean(map_field_.get());
break;
case MAP_DIRTY:
MakeMapDirty(map_field_.get());
break;
case REPEATED_DIRTY:
MakeRepeatedDirty(map_field_.get());
break;
default:
break;
}
}
void AddOneStillClean(MapFieldType* map_field) {
MapFieldBase* map_field_base = map_field;
Map<int32, int32>* map = map_field->MutableMap();
(*map)[0] = 0;
map_field_base->GetRepeatedField();
Expect(map_field, CLEAN, 1, 1, false);
}
void MakeMapDirty(MapFieldType* map_field) {
Map<int32, int32>* map = map_field->MutableMap();
(*map)[0] = 0;
Expect(map_field, MAP_DIRTY, 1, 0, true);
}
void MakeRepeatedDirty(MapFieldType* map_field) {
MakeMapDirty(map_field);
MapFieldBase* map_field_base = map_field;
map_field_base->MutableRepeatedField();
MapFieldBaseStub* stub =
reinterpret_cast<MapFieldBaseStub*>(map_field_base);
Map<int32, int32>* map = stub->MutableMap<Map<int32, int32> >();
map->clear();
Expect(map_field, REPEATED_DIRTY, 0, 1, false);
}
void Expect(MapFieldType* map_field, State state, int map_size,
int repeated_size, bool is_repeated_null) {
MapFieldBase* map_field_base = map_field;
MapFieldBaseStub* stub =
reinterpret_cast<MapFieldBaseStub*>(map_field_base);
Map<int32, int32>* map = stub->MutableMap<Map<int32, int32> >();
RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
switch (state) {
case MAP_DIRTY:
EXPECT_FALSE(stub->IsMapClean());
EXPECT_TRUE(stub->IsRepeatedClean());
break;
case REPEATED_DIRTY:
EXPECT_TRUE(stub->IsMapClean());
EXPECT_FALSE(stub->IsRepeatedClean());
break;
case CLEAN:
EXPECT_TRUE(stub->IsMapClean());
EXPECT_TRUE(stub->IsRepeatedClean());
break;
default:
FAIL();
}
EXPECT_EQ(map_size, map->size());
if (is_repeated_null) {
EXPECT_TRUE(repeated_field == NULL);
} else {
EXPECT_EQ(repeated_size, repeated_field->size());
}
}
google::protobuf::scoped_ptr<MapFieldType> map_field_;
MapFieldBase* map_field_base_;
State state_;
const Message* default_entry_;
};
INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
TEST_P(MapFieldStateTest, GetMap) {
map_field_->GetMap();
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), CLEAN, 1, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
}
}
TEST_P(MapFieldStateTest, MutableMap) {
map_field_->MutableMap();
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
}
}
TEST_P(MapFieldStateTest, MergeFromClean) {
MapFieldType other(default_entry_);
AddOneStillClean(&other);
map_field_->MergeFrom(other);
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
}
Expect(&other, CLEAN, 1, 1, false);
}
TEST_P(MapFieldStateTest, MergeFromMapDirty) {
MapFieldType other(default_entry_);
MakeMapDirty(&other);
map_field_->MergeFrom(other);
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
}
Expect(&other, MAP_DIRTY, 1, 0, true);
}
TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
MapFieldType other(default_entry_);
MakeRepeatedDirty(&other);
map_field_->MergeFrom(other);
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
}
Expect(&other, CLEAN, 1, 1, false);
}
TEST_P(MapFieldStateTest, SwapClean) {
MapFieldType other(default_entry_);
AddOneStillClean(&other);
map_field_->Swap(&other);
Expect(map_field_.get(), CLEAN, 1, 1, false);
switch (state_) {
case CLEAN:
Expect(&other, CLEAN, 1, 1, false);
break;
case MAP_DIRTY:
Expect(&other, MAP_DIRTY, 1, 0, true);
break;
case REPEATED_DIRTY:
Expect(&other, REPEATED_DIRTY, 0, 1, false);
break;
default:
break;
}
}
TEST_P(MapFieldStateTest, SwapMapDirty) {
MapFieldType other(default_entry_);
MakeMapDirty(&other);
map_field_->Swap(&other);
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
switch (state_) {
case CLEAN:
Expect(&other, CLEAN, 1, 1, false);
break;
case MAP_DIRTY:
Expect(&other, MAP_DIRTY, 1, 0, true);
break;
case REPEATED_DIRTY:
Expect(&other, REPEATED_DIRTY, 0, 1, false);
break;
default:
break;
}
}
TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
MapFieldType other(default_entry_);
MakeRepeatedDirty(&other);
map_field_->Swap(&other);
Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
switch (state_) {
case CLEAN:
Expect(&other, CLEAN, 1, 1, false);
break;
case MAP_DIRTY:
Expect(&other, MAP_DIRTY, 1, 0, true);
break;
case REPEATED_DIRTY:
Expect(&other, REPEATED_DIRTY, 0, 1, false);
break;
default:
break;
}
}
TEST_P(MapFieldStateTest, Clear) {
map_field_->Clear();
if (state_ != MAP_DIRTY) {
Expect(map_field_.get(), MAP_DIRTY, 0, 1, false);
} else {
Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
}
}
TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
map_field_base_->SpaceUsedExcludingSelf();
switch (state_) {
case CLEAN:
Expect(map_field_.get(), CLEAN, 1, 1, false);
break;
case MAP_DIRTY:
Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
break;
case REPEATED_DIRTY:
Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
break;
default:
break;
}
}
TEST_P(MapFieldStateTest, GetMapField) {
map_field_base_->GetRepeatedField();
if (state_ != REPEATED_DIRTY) {
Expect(map_field_.get(), CLEAN, 1, 1, false);
} else {
Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
}
}
TEST_P(MapFieldStateTest, MutableMapField) {
map_field_base_->MutableRepeatedField();
if (state_ != REPEATED_DIRTY) {
Expect(map_field_.get(), REPEATED_DIRTY, 1, 1, false);
} else {
Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
}
}
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

@ -0,0 +1,39 @@
// 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.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package protobuf_unittest;
message MapLite {
map<int32, int32> map_field = 1;
}

@ -0,0 +1,68 @@
// 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.
syntax = "proto2";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
package protobuf_unittest;
enum Proto2MapEnum {
PROTO2_MAP_ENUM_FOO = 0;
PROTO2_MAP_ENUM_BAR = 1;
PROTO2_MAP_ENUM_BAZ = 2;
}
enum Proto2MapEnumPlusExtra {
E_PROTO2_MAP_ENUM_FOO = 0;
E_PROTO2_MAP_ENUM_BAR = 1;
E_PROTO2_MAP_ENUM_BAZ = 2;
E_PROTO2_MAP_ENUM_EXTRA = 3;
}
enum Proto2MapEnumStartWithNonZero {
PROTO2_NON_ZERO_MAP_ENUM_FOO = 1;
}
message TestEnumMap {
map<int32, Proto2MapEnum> known_map_field = 101;
map<int32, Proto2MapEnum> unknown_map_field = 102;
}
message TestEnumMapPlusExtra {
map<int32, Proto2MapEnumPlusExtra> known_map_field = 101;
map<int32, Proto2MapEnumPlusExtra> unknown_map_field = 102;
}
message TestEnumStartWithNonZeroMap {
map<int32, Proto2MapEnumStartWithNonZero> map_field = 101;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,149 @@
// 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_MAP_TEST_UTIL_H__
#define GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__
#include <google/protobuf/map_unittest.pb.h>
namespace google {
namespace protobuf {
namespace unittest = ::protobuf_unittest;
class MapTestUtil {
public:
// Set every field in the message to a unique value.
static void SetMapFields(unittest::TestMap* message);
// Set every field in the message to a default value.
static void SetMapFieldsInitialized(unittest::TestMap* message);
// Modify all the map fields of the messsage (which should already have been
// initialized with SetMapFields()).
static void ModifyMapFields(unittest::TestMap* message);
// Check that all fields have the values that they should have after
// SetMapFields() is called.
static void ExpectMapFieldsSet(const unittest::TestMap& message);
// Check that all fields have the values that they should have after
// SetMapFieldsInitialized() is called.
static void ExpectMapFieldsSetInitialized(
const unittest::TestMap& message);
// Expect that the message is modified as would be expected from
// ModifyMapFields().
static void ExpectMapFieldsModified(const unittest::TestMap& message);
// Check that all fields are empty.
static void ExpectClear(const unittest::TestMap& message);
// Check that all map fields have the given size.
static void ExpectMapsSize(const unittest::TestMap& message, int size);
// Get pointers of map entries at given index.
static std::vector<const Message*> GetMapEntries(
const unittest::TestMap& message, int index);
// Get pointers of map entries from release.
static std::vector<const Message*> GetMapEntriesFromRelease(
unittest::TestMap* message);
// Like above, but use the reflection interface.
class MapReflectionTester {
public:
// base_descriptor must be a descriptor for TestMap, which is used for
// MapReflectionTester to fetch the FieldDescriptors needed to use the
// reflection interface.
explicit MapReflectionTester(const Descriptor* base_descriptor);
void SetMapFieldsViaReflection(Message* message);
void ClearMapFieldsViaReflection(Message* message);
void ModifyMapFieldsViaReflection(Message* message);
void RemoveLastMapsViaReflection(Message* message);
void ReleaseLastMapsViaReflection(Message* message);
void SwapMapsViaReflection(Message* message);
void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message);
void ExpectMapFieldsSetViaReflection(const Message& message);
void ExpectClearViaReflection(const Message& message);
void ExpectMapEntryClearViaReflection(Message* message);
private:
const FieldDescriptor* F(const string& name);
const Descriptor* base_descriptor_;
const EnumValueDescriptor* map_enum_bar_;
const EnumValueDescriptor* map_enum_baz_;
const EnumValueDescriptor* map_enum_foo_;
const FieldDescriptor* foreign_c_;
const FieldDescriptor* map_int32_int32_key_;
const FieldDescriptor* map_int32_int32_val_;
const FieldDescriptor* map_int64_int64_key_;
const FieldDescriptor* map_int64_int64_val_;
const FieldDescriptor* map_uint32_uint32_key_;
const FieldDescriptor* map_uint32_uint32_val_;
const FieldDescriptor* map_uint64_uint64_key_;
const FieldDescriptor* map_uint64_uint64_val_;
const FieldDescriptor* map_sint32_sint32_key_;
const FieldDescriptor* map_sint32_sint32_val_;
const FieldDescriptor* map_sint64_sint64_key_;
const FieldDescriptor* map_sint64_sint64_val_;
const FieldDescriptor* map_fixed32_fixed32_key_;
const FieldDescriptor* map_fixed32_fixed32_val_;
const FieldDescriptor* map_fixed64_fixed64_key_;
const FieldDescriptor* map_fixed64_fixed64_val_;
const FieldDescriptor* map_sfixed32_sfixed32_key_;
const FieldDescriptor* map_sfixed32_sfixed32_val_;
const FieldDescriptor* map_sfixed64_sfixed64_key_;
const FieldDescriptor* map_sfixed64_sfixed64_val_;
const FieldDescriptor* map_int32_float_key_;
const FieldDescriptor* map_int32_float_val_;
const FieldDescriptor* map_int32_double_key_;
const FieldDescriptor* map_int32_double_val_;
const FieldDescriptor* map_bool_bool_key_;
const FieldDescriptor* map_bool_bool_val_;
const FieldDescriptor* map_string_string_key_;
const FieldDescriptor* map_string_string_val_;
const FieldDescriptor* map_int32_bytes_key_;
const FieldDescriptor* map_int32_bytes_val_;
const FieldDescriptor* map_int32_enum_key_;
const FieldDescriptor* map_int32_enum_val_;
const FieldDescriptor* map_int32_foreign_message_key_;
const FieldDescriptor* map_int32_foreign_message_val_;
};
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MAP_TEST_UTIL_H__

@ -0,0 +1,486 @@
// 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_TYPE_HANDLER_H__
#define GOOGLE_PROTOBUF_TYPE_HANDLER_H__
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/wire_format_lite_inl.h>
namespace google {
namespace protobuf {
namespace internal {
// Used for compile time type selection. MapIf::type will be TrueType if Flag is
// true and FalseType otherwise.
template<bool Flag, typename TrueType, typename FalseType>
struct MapIf;
template<typename TrueType, typename FalseType>
struct MapIf<true, TrueType, FalseType> {
typedef TrueType type;
};
template<typename TrueType, typename FalseType>
struct MapIf<false, TrueType, FalseType> {
typedef FalseType type;
};
// In MapField, string and message are stored as pointer while others are stored
// as object. However, google::protobuf::Map has unified api. Functions in this class
// convert key/value to type wanted in api regardless how it's stored
// internally.
template <typename Type>
class MapCommonTypeHandler {
public:
static inline Type& Reference(Type* x) { return *x; }
static inline Type& Reference(Type& x) { return x; }
static inline const Type& Reference(const Type& x) { return x; }
static inline Type* Pointer(Type* x) { return x; }
static inline Type* Pointer(Type& x) { return &x; }
static inline const Type* Pointer(const Type* x) { return x; }
static inline const Type* Pointer(const Type& x) { return &x; }
};
// In proto2 Map, enum needs to be initialized to given default value, while
// other types' default value can be inferred from the type.
template <bool IsEnum, typename Type>
class MapValueInitializer {
public:
static inline void Initialize(Type& type, int default_enum_value);
};
template <typename Type>
class MapValueInitializer<true, Type> {
public:
static inline void Initialize(Type& value, int default_enum_value) {
value = static_cast<Type>(default_enum_value);
}
};
template <typename Type>
class MapValueInitializer<false, Type> {
public:
static inline void Initialize(Type& value, int default_enum_value) {}
};
// Handlers for key/value stored type in MapField. ==================
// Handler for message
template <typename Type>
class MapCppTypeHandler : public MapCommonTypeHandler<Type> {
public:
static const bool kIsStringOrMessage = true;
// SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
// those already calculate in sizeof(MapField).
static int SpaceUsedInMapEntry(const Type* value) {
return value->SpaceUsed();
}
// Return bytes used by value in Map.
static int SpaceUsedInMap(const Type& value) { return value.SpaceUsed(); }
static inline void Clear(Type** value) {
if (*value != NULL) (*value)->Type::Clear();
}
static inline void ClearMaybeByDefaultEnum(Type** value,
int default_enum_value) {
if (*value != NULL) (*value)->Type::Clear();
}
static inline void Merge(const Type& from, Type** to) {
(*to)->MergeFrom(from);
}
static void Delete(const Type* ptr) { delete ptr; }
// Assign default value to given instance.
static inline void AssignDefaultValue(Type** value) {
*value = const_cast<Type*>(&Type::default_instance());
}
// Initialize value when constructing MapEntry
static inline void Initialize(Type** x) { *x = NULL; }
// Same as above, but use default_enum_value to initialize enum type value.
static inline void InitializeMaybeByDefaultEnum(
Type** x, int default_enum_value) {
*x = NULL;
}
// Initialize value for the first time mutable accessor is called.
static inline void EnsureMutable(Type** value) {
if (*value == NULL) *value = new Type;
}
// Return default instance if value is not initialized when calling const
// reference accessor.
static inline const Type& DefaultIfNotInitialized(Type* value,
Type* default_value) {
return value != NULL ? *value : *default_value;
}
// Check if all required fields have values set.
static inline bool IsInitialized(Type* value) {
return value->IsInitialized();
}
};
// Handler for string.
template <>
class MapCppTypeHandler<string> : public MapCommonTypeHandler<string> {
public:
static const bool kIsStringOrMessage = true;
static inline void Merge(const string& from, string** to) { **to = from; }
static inline void Clear(string** value) { (*value)->clear(); }
static inline void ClearMaybeByDefaultEnum(string** value, int default_enum) {
(*value)->clear();
}
static inline int SpaceUsedInMapEntry(const string* value) {
return sizeof(*value) + StringSpaceUsedExcludingSelf(*value);
}
static inline int SpaceUsedInMap(const string& value) {
return sizeof(value) + StringSpaceUsedExcludingSelf(value);
}
static void Delete(const string* ptr) {
if (ptr != &::google::protobuf::internal::GetEmptyString()) delete ptr;
}
static inline void AssignDefaultValue(string** value) {}
static inline void Initialize(string** value) {
*value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
}
static inline void InitializeMaybeByDefaultEnum(
string** value, int default_enum_value) {
*value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
}
static inline void EnsureMutable(string** value) {
if (*value == &::google::protobuf::internal::GetEmptyString()) *value = new string;
}
static inline const string& DefaultIfNotInitialized(string* value,
string* default_value) {
return value != default_value ? *value : *default_value;
}
static inline bool IsInitialized(string* value) { return true; }
};
// Base class for primitive type handlers.
template <typename Type>
class MapPrimitiveTypeHandler : public MapCommonTypeHandler<Type> {
public:
static const bool kIsStringOrMessage = false;
static inline void Delete(const Type& x) {}
static inline void Merge(const Type& from, Type* to) { *to = from; }
static inline int SpaceUsedInMapEntry(const Type& value) { return 0; }
static inline int SpaceUsedInMap(const Type& value) { return sizeof(Type); }
static inline void AssignDefaultValue(Type* value) {}
static inline const Type& DefaultIfNotInitialized(
const Type& value, const Type& default_value) {
return value;
}
static inline bool IsInitialized(const Type& value) { return true; }
};
// Handlers for primitive types.
#define PRIMITIVE_HANDLER(CType) \
template <> \
class MapCppTypeHandler<CType> : public MapPrimitiveTypeHandler<CType> { \
public: \
static inline void Clear(CType* value) { *value = 0; } \
static inline void ClearMaybeByDefaultEnum(CType* value, \
int default_enum_value) { \
*value = static_cast<CType>(default_enum_value); \
} \
static inline void Initialize(CType* value) { *value = 0; } \
static inline void InitializeMaybeByDefaultEnum(CType* value, \
int default_enum_value) { \
*value = static_cast<CType>(default_enum_value); \
} \
static inline void EnsureMutable(CType* value) {} \
};
PRIMITIVE_HANDLER(int32 )
PRIMITIVE_HANDLER(int64 )
PRIMITIVE_HANDLER(uint32)
PRIMITIVE_HANDLER(uint64)
PRIMITIVE_HANDLER(double)
PRIMITIVE_HANDLER(float )
PRIMITIVE_HANDLER(bool )
#undef PRIMITIVE_HANDLER
// Define constants for given proto field type
template <FieldDescriptor::Type Type>
class MapFieldTypeTraits {};
#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \
template <> \
class MapFieldTypeTraits<FieldDescriptor::TYPE_##FieldType> { \
public: \
typedef CType CppType; \
static const bool kIsMessage = IsMessage; \
static const bool kIsEnum = IsEnum; \
static const WireFormatLite::WireType kWireType = \
WireFormatLite::WIRETYPE_##WireFormatType; \
};
TYPE_TRAITS(MESSAGE , Message, LENGTH_DELIMITED, true, false)
TYPE_TRAITS(STRING , string , LENGTH_DELIMITED, false, false)
TYPE_TRAITS(BYTES , string , LENGTH_DELIMITED, false, false)
TYPE_TRAITS(INT64 , int64 , VARINT , false, false)
TYPE_TRAITS(UINT64 , uint64 , VARINT , false, false)
TYPE_TRAITS(INT32 , int32 , VARINT , false, false)
TYPE_TRAITS(UINT32 , uint32 , VARINT , false, false)
TYPE_TRAITS(SINT64 , int64 , VARINT , false, false)
TYPE_TRAITS(SINT32 , int32 , VARINT , false, false)
TYPE_TRAITS(ENUM , int , VARINT , false, true )
TYPE_TRAITS(DOUBLE , double , FIXED64, false, false)
TYPE_TRAITS(FLOAT , float , FIXED32, false, false)
TYPE_TRAITS(FIXED64 , uint64 , FIXED64, false, false)
TYPE_TRAITS(FIXED32 , uint32 , FIXED32, false, false)
TYPE_TRAITS(SFIXED64, int64 , FIXED64, false, false)
TYPE_TRAITS(SFIXED32, int32 , FIXED32, false, false)
TYPE_TRAITS(BOOL , bool , VARINT , false, false)
#undef TYPE_TRAITS
// Handler for proto field type. Define types and constants used in compile
// time. Also define functions used in parsing and serializing.
template <FieldDescriptor::Type Type>
class MapProtoTypeHandler {
public:
// Internal stored type in MapEntry for given proto field type.
typedef typename MapFieldTypeTraits<Type>::CppType CppType;
// Whether given type is a message.
static const bool kIsMessage = MapFieldTypeTraits<Type>::kIsMessage;
// Whether given type is an enum.
static const bool kIsEnum = MapFieldTypeTraits<Type>::kIsEnum;
// The wire type of given proto field type.
static const WireFormatLite::WireType kWireType =
MapFieldTypeTraits<Type>::kWireType;
// Functions used in parsing and serialization. ===================
template <typename ValueType>
static inline int ByteSize(const ValueType& value);
template <typename ValueType>
static inline int GetCachedSize(const ValueType& value);
static inline void Write(int field, const CppType& value,
io::CodedOutputStream* output);
static inline uint8* WriteToArray(int field, const CppType& value,
uint8* output);
template <typename ValueType>
static inline bool Read(io::CodedInputStream* input, ValueType* value);
};
template <>
template <typename ValueType>
inline int MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::ByteSize(
const ValueType& value) {
return WireFormatLite::MessageSizeNoVirtual(value);
}
#define BYTE_SIZE(FieldType, DeclaredType) \
template <> \
template <typename ValueType> \
inline int MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::ByteSize( \
const ValueType& value) { \
return WireFormatLite::DeclaredType##Size(value); \
}
BYTE_SIZE(STRING, String)
BYTE_SIZE(BYTES , Bytes)
BYTE_SIZE(INT64 , Int64)
BYTE_SIZE(UINT64, UInt64)
BYTE_SIZE(INT32 , Int32)
BYTE_SIZE(UINT32, UInt32)
BYTE_SIZE(SINT64, SInt64)
BYTE_SIZE(SINT32, SInt32)
BYTE_SIZE(ENUM , Enum)
#undef BYTE_SIZE
#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \
template <> \
template <typename ValueType> \
inline int MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::ByteSize( \
const ValueType& value) { \
return WireFormatLite::k##DeclaredType##Size; \
}
FIXED_BYTE_SIZE(DOUBLE , Double)
FIXED_BYTE_SIZE(FLOAT , Float)
FIXED_BYTE_SIZE(FIXED64 , Fixed64)
FIXED_BYTE_SIZE(FIXED32 , Fixed32)
FIXED_BYTE_SIZE(SFIXED64, SFixed64)
FIXED_BYTE_SIZE(SFIXED32, SFixed32)
FIXED_BYTE_SIZE(BOOL , Bool)
#undef FIXED_BYTE_SIZE
template <>
template <typename ValueType>
inline int MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::GetCachedSize(
const ValueType& value) {
return WireFormatLite::LengthDelimitedSize(value.GetCachedSize());
}
#define GET_CACHED_SIZE(FieldType, DeclaredType) \
template <> \
template <typename ValueType> \
inline int \
MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::GetCachedSize( \
const ValueType& value) { \
return WireFormatLite::DeclaredType##Size(value); \
}
GET_CACHED_SIZE(STRING, String)
GET_CACHED_SIZE(BYTES , Bytes)
GET_CACHED_SIZE(INT64 , Int64)
GET_CACHED_SIZE(UINT64, UInt64)
GET_CACHED_SIZE(INT32 , Int32)
GET_CACHED_SIZE(UINT32, UInt32)
GET_CACHED_SIZE(SINT64, SInt64)
GET_CACHED_SIZE(SINT32, SInt32)
GET_CACHED_SIZE(ENUM , Enum)
#undef GET_CACHED_SIZE
#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \
template <> \
template <typename ValueType> \
inline int \
MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::GetCachedSize( \
const ValueType& value) { \
return WireFormatLite::k##DeclaredType##Size; \
}
GET_FIXED_CACHED_SIZE(DOUBLE , Double)
GET_FIXED_CACHED_SIZE(FLOAT , Float)
GET_FIXED_CACHED_SIZE(FIXED64 , Fixed64)
GET_FIXED_CACHED_SIZE(FIXED32 , Fixed32)
GET_FIXED_CACHED_SIZE(SFIXED64, SFixed64)
GET_FIXED_CACHED_SIZE(SFIXED32, SFixed32)
GET_FIXED_CACHED_SIZE(BOOL , Bool)
#undef GET_FIXED_CACHED_SIZE
template <>
inline void MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::Write(
int field, const Message& value, io::CodedOutputStream* output) {
WireFormatLite::WriteMessageMaybeToArray(field, value, output);
}
template <>
inline uint8* MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::WriteToArray(
int field, const Message& value, uint8* output) {
return WireFormatLite::WriteMessageToArray(field, value, output);
}
#define WRITE_METHOD(FieldType, DeclaredType) \
template <> \
inline void MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::Write( \
int field, const CppType& value, io::CodedOutputStream* output) { \
return WireFormatLite::Write##DeclaredType(field, value, output); \
} \
template <> \
inline uint8* \
MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::WriteToArray( \
int field, const CppType& value, uint8* output) { \
return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
}
WRITE_METHOD(STRING , String)
WRITE_METHOD(BYTES , Bytes)
WRITE_METHOD(INT64 , Int64)
WRITE_METHOD(UINT64 , UInt64)
WRITE_METHOD(INT32 , Int32)
WRITE_METHOD(UINT32 , UInt32)
WRITE_METHOD(SINT64 , SInt64)
WRITE_METHOD(SINT32 , SInt32)
WRITE_METHOD(ENUM , Enum)
WRITE_METHOD(DOUBLE , Double)
WRITE_METHOD(FLOAT , Float)
WRITE_METHOD(FIXED64 , Fixed64)
WRITE_METHOD(FIXED32 , Fixed32)
WRITE_METHOD(SFIXED64, SFixed64)
WRITE_METHOD(SFIXED32, SFixed32)
WRITE_METHOD(BOOL , Bool)
#undef WRITE_METHOD
template <>
template <typename ValueType>
inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_MESSAGE>::Read(
io::CodedInputStream* input, ValueType* value) {
return WireFormatLite::ReadMessageNoVirtual(input, value);
}
template <>
template <typename ValueType>
inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_STRING>::Read(
io::CodedInputStream* input, ValueType* value) {
return WireFormatLite::ReadString(input, value);
}
template <>
template <typename ValueType>
inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_BYTES>::Read(
io::CodedInputStream* input, ValueType* value) {
return WireFormatLite::ReadBytes(input, value);
}
#define READ_METHOD(FieldType) \
template <> \
template <typename ValueType> \
inline bool MapProtoTypeHandler<FieldDescriptor::TYPE_##FieldType>::Read( \
io::CodedInputStream* input, ValueType* value) { \
return WireFormatLite::ReadPrimitive<CppType, \
WireFormatLite::TYPE_##FieldType>( \
input, value); \
}
READ_METHOD(INT64)
READ_METHOD(UINT64)
READ_METHOD(INT32)
READ_METHOD(UINT32)
READ_METHOD(SINT64)
READ_METHOD(SINT32)
READ_METHOD(ENUM)
READ_METHOD(DOUBLE)
READ_METHOD(FLOAT)
READ_METHOD(FIXED64)
READ_METHOD(FIXED32)
READ_METHOD(SFIXED64)
READ_METHOD(SFIXED32)
READ_METHOD(BOOL)
#undef READ_METHOD
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_TYPE_HANDLER_H__

@ -0,0 +1,77 @@
// 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.
syntax = "proto3";
import "google/protobuf/unittest.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
// In map_test_util.h we do "using namespace unittest = protobuf_unittest".
package protobuf_unittest;
// Tests maps.
message TestMap {
map<int32 , int32 > map_int32_int32 = 1;
map<int64 , int64 > map_int64_int64 = 2;
map<uint32 , uint32 > map_uint32_uint32 = 3;
map<uint64 , uint64 > map_uint64_uint64 = 4;
map<sint32 , sint32 > map_sint32_sint32 = 5;
map<sint64 , sint64 > map_sint64_sint64 = 6;
map<fixed32 , fixed32 > map_fixed32_fixed32 = 7;
map<fixed64 , fixed64 > map_fixed64_fixed64 = 8;
map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 9;
map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 10;
map<int32 , float > map_int32_float = 11;
map<int32 , double > map_int32_double = 12;
map<bool , bool > map_bool_bool = 13;
map<string , string > map_string_string = 14;
map<int32 , bytes > map_int32_bytes = 15;
map<int32 , MapEnum > map_int32_enum = 16;
map<int32 , ForeignMessage> map_int32_foreign_message = 17;
}
message TestMessageMap {
map<int32, TestAllTypes> map_int32_message = 1;
}
// Two map fields share the same entry default instance.
message TestSameTypeMap {
map<int32, int32> map1 = 1;
map<int32, int32> map2 = 2;
}
enum MapEnum {
MAP_ENUM_FOO = 0;
MAP_ENUM_BAR = 1;
MAP_ENUM_BAZ = 2;
}

@ -430,8 +430,12 @@ const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor(
}
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (field->is_map()) {
return internal::Singleton<internal::MapFieldAccessor>::get();
} else {
return internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::get();
}
}
GOOGLE_LOG(FATAL) << "Should not reach here.";
return NULL;
}

@ -110,7 +110,7 @@ TEST(PreserveUnknownEnumTest, PreserveParseAndSerializeDynamicMessage) {
string serialized = orig_message.SerializeAsString();
google::protobuf::DynamicMessageFactory factory;
scoped_ptr<google::protobuf::Message> message(factory.GetPrototype(
google::protobuf::scoped_ptr<google::protobuf::Message> message(factory.GetPrototype(
proto2_preserve_unknown_enum_unittest::MyMessage::descriptor())->New());
EXPECT_EQ(true, message->ParseFromString(serialized));
message->DiscardUnknownFields();

@ -175,7 +175,7 @@ TEST(ArenaTest, ReleaseMessage) {
Arena arena;
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
arena_message->mutable_optional_nested_message()->set_bb(118);
scoped_ptr<TestAllTypes::NestedMessage> nested(
google::protobuf::scoped_ptr<TestAllTypes::NestedMessage> nested(
arena_message->release_optional_nested_message());
EXPECT_EQ(118, nested->bb());
}

@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
#define GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
#include <google/protobuf/map_field.h>
#include <google/protobuf/reflection.h>
#include <google/protobuf/repeated_field.h>
@ -199,6 +200,73 @@ class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor {
Value* scratch_space) const = 0;
};
// An implementation of RandomAccessRepeatedFieldAccessor that manipulates
// MapFieldBase.
class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor {
public:
MapFieldAccessor() {}
virtual ~MapFieldAccessor() {}
virtual bool IsEmpty(const Field* data) const {
return GetRepeatedField(data)->empty();
}
virtual int Size(const Field* data) const {
return GetRepeatedField(data)->size();
}
virtual const Value* Get(const Field* data, int index,
Value* scratch_space) const {
return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space);
}
virtual void Clear(Field* data) const {
MutableRepeatedField(data)->Clear();
}
virtual void Set(Field* data, int index, const Value* value) const {
ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index));
}
virtual void Add(Field* data, const Value* value) const {
Message* allocated = New(value);
ConvertToEntry(value, allocated);
MutableRepeatedField(data)->AddAllocated(allocated);
}
virtual void RemoveLast(Field* data) const {
MutableRepeatedField(data)->RemoveLast();
}
virtual void SwapElements(Field* data, int index1, int index2) const {
MutableRepeatedField(data)->SwapElements(index1, index2);
}
virtual void Swap(
Field* data,
const internal::RepeatedFieldAccessor* other_mutator,
Field* other_data) const {
GOOGLE_CHECK(this == other_mutator);
MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
}
protected:
typedef RepeatedPtrField<Message> RepeatedFieldType;
static const RepeatedFieldType* GetRepeatedField(const Field* data) {
return reinterpret_cast<const RepeatedFieldType*>(
(&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField()));
}
static RepeatedFieldType* MutableRepeatedField(Field* data) {
return reinterpret_cast<RepeatedFieldType*>(
reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField());
}
virtual Message* New(const Value* value) const {
return static_cast<const Message*>(value)->New();
}
// Convert an object received by this accessor to an MapEntry message to be
// stored in the underlying MapFieldBase.
virtual void ConvertToEntry(const Value* value, Message* result) const {
result->CopyFrom(*static_cast<const Message*>(value));
}
// Convert a MapEntry message stored in the underlying MapFieldBase to an
// object that will be returned by this accessor.
virtual const Value* ConvertFromEntry(const Message& value,
Value* scratch_space) const {
return static_cast<const Value*>(&value);
}
};
// Default implementations of RepeatedFieldAccessor for primitive types.
template<typename T>
class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> {

@ -86,7 +86,7 @@ inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
template <typename Iter>
inline int CalculateReserve(Iter /*begin*/, Iter /*end*/,
std::input_iterator_tag) {
std::input_iterator_tag /*unused*/) {
return -1;
}
@ -349,6 +349,11 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
// use of AddFromCleared(), which is not part of the public interface.
friend class ExtensionSet;
// The MapFieldBase implementation needs to call protected methods directly,
// reinterpreting pointers as being to Message instead of a specific Message
// subclass.
friend class MapFieldBase;
// To parse directly into a proto2 generated class, the upb class GMR_Handlers
// needs to be able to modify a RepeatedPtrFieldBase directly.
friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;

@ -231,7 +231,7 @@ class RepeatedFieldRefIterator
const void* data_;
const RepeatedFieldAccessor* accessor_;
void* iterator_;
scoped_ptr<AccessorValueType> scratch_space_;
google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
};
// TypeTraits that maps the type parameter T of RepeatedFieldRef or

@ -686,7 +686,7 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefDynamicMessage) {
desc->FindFieldByName("repeated_int32");
DynamicMessageFactory factory;
scoped_ptr<Message> dynamic_message(factory.GetPrototype(desc)->New());
google::protobuf::scoped_ptr<Message> dynamic_message(factory.GetPrototype(desc)->New());
const Reflection* refl = dynamic_message->GetReflection();
MutableRepeatedFieldRef<int32> rf_int32 =

@ -267,6 +267,8 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#endif
#define GOOGLE_GUARDED_BY(x)
#define GOOGLE_FALLTHROUGH_INTENDED
#define GOOGLE_ATTRIBUTE_COLD
// x86 and x86-64 can perform unaligned loads/stores directly.
#if defined(_M_X64) || defined(__x86_64__) || \

@ -271,7 +271,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
bool print_message_fields_in_index_order_;
scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
google::protobuf::scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
typedef map<const FieldDescriptor*,
const FieldValuePrinter*> CustomPrinterMap;
CustomPrinterMap custom_printers_;

@ -41,6 +41,7 @@ syntax = "proto2";
option cc_generic_services = true; // auto-added
option java_generic_services = true; // auto-added
option py_generic_services = true; // auto-added
option cc_enable_arenas = true;
import "google/protobuf/unittest_import.proto";

@ -34,6 +34,7 @@ import "google/protobuf/unittest_no_arena_import.proto";
package proto2_arena_unittest;
option cc_enable_arenas = true;
message NestedMessage {
optional int32 d = 1;

@ -43,6 +43,7 @@ syntax = "proto2";
package protobuf_unittest_import;
option optimize_for = SPEED;
option cc_enable_arenas = true;
// Exercise the java_package option.
option java_package = "com.google.protobuf.test";

@ -37,6 +37,7 @@
syntax = "proto2";
package protobuf_unittest;
option cc_enable_arenas = true;
option optimize_for = SPEED;
// A message with message_set_wire_format.

@ -43,6 +43,7 @@ syntax = "proto2";
option cc_generic_services = true; // auto-added
option java_generic_services = true; // auto-added
option py_generic_services = true; // auto-added
option cc_enable_arenas = false;
import "google/protobuf/unittest_import.proto";
import "google/protobuf/unittest_arena.proto";

@ -30,6 +30,7 @@
syntax = "proto3";
option cc_enable_arenas = true;
import "google/protobuf/unittest_import.proto";

Loading…
Cancel
Save