diff options
Diffstat (limited to 'src/google/protobuf/compiler/cpp')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_field.cc | 20 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_field.h | 2 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_file.cc | 26 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_file.h | 8 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_generator.cc | 4 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_helpers.cc | 19 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_helpers.h | 10 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_map_field.cc | 255 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_map_field.h | 75 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_message.cc | 148 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_message.h | 6 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_message_field.cc | 14 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc | 2 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_string_field.cc | 9 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_unittest.cc | 16 |
15 files changed, 553 insertions, 61 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 85838ac3..43df1d88 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -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: - return new RepeatedMessageFieldGenerator(field, options); + 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. diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 088e5063..c37fe0be 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -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); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 6dc88e88..fae4df40 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -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++) { @@ -150,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( @@ -395,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"); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index 13d06f98..0e06547d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -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_; diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index a2fb7162..c999b93f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -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); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 63b0265e..28c4dd54 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -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) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 1cff17c8..e60fa7c2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -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) { diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc new file mode 100644 index 00000000..0154eeb8 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -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 diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h new file mode 100644 index 00000000..0ff032fd --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -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__ diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 54a92ae4..28ee3a9d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -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,9 +909,11 @@ 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); - printer->Print("typedef $nested_full_name$ $nested_name$;\n", - "nested_name", nested_type->name(), - "nested_full_name", ClassName(nested_type, false)); + 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) { @@ -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) { - printer->Print( - "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" - "const ::google::protobuf::internal::GeneratedMessageReflection*\n" - " $name$_reflection_ = NULL;\n", - "name", classname_); + 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"); } - printer->Print( - " ::google::protobuf::DescriptorPool::generated_pool(),\n"); - printer->Print(vars, - " ::google::protobuf::MessageFactory::generated_factory(),\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. - printer->Print( - "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" - " $classname$_descriptor_, &$classname$::default_instance());\n", - "classname", classname_); + 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,14 +3278,14 @@ 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. printer->Print( - "if (has_$name$()) {\n" - " if (!this->$name$_->IsInitialized()) return false;\n" - "}\n", + "if (has_$name$()) {\n" + " if (!this->$name$_->IsInitialized()) return false;\n" + "}\n", "name", FieldName(field)); } else { printer->Print( diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index a781c234..dfbc9af5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -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_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index da1ec60b..b3cd0ba1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -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" diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc index 26cefb2e..d1efbfe6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -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); diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index a2a8c81c..a7f95044 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -306,7 +306,14 @@ GenerateClearingCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "set_$name$(from.$name$());\n"); + 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:: diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 74a277e0..20fcfa62 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -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); |