Index: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc |
diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc |
index 5c4b56f7eda2433385d66b9759a32d37400577b2..f585c31b4bf8ebfb9a2bb5d96968bf63f9c6d470 100644 |
--- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc |
+++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_map_field.cc |
@@ -45,10 +45,10 @@ bool IsProto3Field(const FieldDescriptor* field_descriptor) { |
} |
void SetMessageVariables(const FieldDescriptor* descriptor, |
- std::map<string, string>* variables, |
+ map<string, string>* variables, |
const Options& options) { |
SetCommonFieldVariables(descriptor, variables, options); |
- (*variables)["type"] = ClassName(descriptor->message_type(), false); |
+ (*variables)["type"] = FieldMessageTypeName(descriptor); |
(*variables)["stream_writer"] = |
(*variables)["declared_type"] + |
(HasFastArraySerialization(descriptor->message_type()->file(), options) |
@@ -137,7 +137,7 @@ GenerateAccessorDeclarations(io::Printer* printer) const { |
void MapFieldGenerator:: |
GenerateInlineAccessorDefinitions(io::Printer* printer, |
bool is_inline) const { |
- std::map<string, string> variables(variables_); |
+ map<string, string> variables(variables_); |
variables["inline"] = is_inline ? "inline" : ""; |
printer->Print(variables, |
"$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" |
@@ -154,7 +154,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, |
void MapFieldGenerator:: |
GenerateClearingCode(io::Printer* printer) const { |
- std::map<string, string> variables(variables_); |
+ map<string, string> variables(variables_); |
variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
printer->Print(variables, "$this_message$$name$_.Clear();\n"); |
} |
@@ -173,48 +173,42 @@ void MapFieldGenerator:: |
GenerateConstructorCode(io::Printer* printer) const { |
if (HasDescriptorMethods(descriptor_->file(), options_)) { |
printer->Print(variables_, |
- "$name$_.SetAssignDescriptorCallback(\n" |
- " protobuf_AssignDescriptorsOnce);\n" |
- "$name$_.SetEntryDescriptor(\n" |
- " &$type$_descriptor);\n"); |
+ "$name$_.SetAssignDescriptorCallback(\n" |
+ " protobuf_AssignDescriptorsOnce);\n" |
+ "$name$_.SetEntryDescriptor(\n" |
+ " &$type$_descriptor_);\n"); |
} |
} |
void MapFieldGenerator:: |
-GenerateCopyConstructorCode(io::Printer* printer) const { |
- GenerateConstructorCode(printer); |
- GenerateMergingCode(printer); |
-} |
- |
-void MapFieldGenerator:: |
GenerateMergeFromCodedStream(io::Printer* printer) const { |
- const FieldDescriptor* key_field = |
- descriptor_->message_type()->FindFieldByName("key"); |
const FieldDescriptor* value_field = |
descriptor_->message_type()->FindFieldByName("value"); |
- bool using_entry = false; |
- string key; |
- string 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_, |
- "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n" |
- " $key_cpp$, $val_cpp$,\n" |
- " $key_wire_type$,\n" |
- " $val_wire_type$,\n" |
- " $default_enum_value$ >,\n" |
- " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" |
- " parser(&$name$_);\n" |
"DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" |
- " input, &parser));\n"); |
- key = "parser.key()"; |
- value = "parser.value()"; |
+ " 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 { |
- using_entry = true; |
- key = "entry->key()"; |
- value = "entry->value()"; |
- printer->Print(variables_, |
- "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n"); |
printer->Print(variables_, |
"{\n" |
" ::std::string data;\n" |
@@ -230,183 +224,156 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { |
"->AddLengthDelimited($number$, data);\n"); |
} else { |
printer->Print(variables_, |
- " unknown_fields_stream.WriteVarint32($tag$u);\n" |
+ " unknown_fields_stream.WriteVarint32($tag$);\n" |
" unknown_fields_stream.WriteVarint32(data.size());\n" |
" unknown_fields_stream.WriteString(data);\n"); |
} |
+ |
printer->Print(variables_, |
" }\n" |
"}\n"); |
} |
+ const FieldDescriptor* key_field = |
+ descriptor_->message_type()->FindFieldByName("key"); |
if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
GenerateUtf8CheckCodeForString( |
- key_field, options_, true, variables_, |
- StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); |
+ key_field, options_, true, variables_, |
+ "entry->key().data(), entry->key().length(),\n", printer); |
} |
if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, |
- StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); |
+ "entry->mutable_value()->data(),\n" |
+ "entry->mutable_value()->length(),\n", |
+ printer); |
} |
// If entry is allocated by arena, its desctructor should be avoided. |
- if (using_entry && SupportsArenas(descriptor_)) { |
+ if (SupportsArenas(descriptor_)) { |
printer->Print(variables_, |
"if (entry->GetArena() != NULL) entry.release();\n"); |
} |
} |
-static void GenerateSerializationLoop(io::Printer* printer, |
- const std::map<string, string>& variables, |
- bool supports_arenas, |
- const string& utf8_check, |
- const string& loop_header, |
- const string& ptr, |
- bool loop_via_iterators) { |
- printer->Print(variables, |
- StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n", |
- loop_header, " {\n").c_str()); |
- printer->Indent(); |
- |
- printer->Print(variables, StrCat( |
- "entry.reset($name$_.New$wrapper$(\n" |
- " ", ptr, "->first, ", ptr, "->second));\n" |
- "$write_entry$;\n").c_str()); |
+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 = this->$name$().begin();\n" |
+ " it != this->$name$().end(); ++it) {\n"); |
// If entry is allocated by arena, its desctructor should be avoided. |
- if (supports_arenas) { |
- printer->Print( |
- "if (entry->GetArena() != NULL) {\n" |
- " entry.release();\n" |
- "}\n"); |
+ if (SupportsArenas(descriptor_)) { |
+ printer->Print(variables_, |
+ " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
+ " entry.release();\n" |
+ " }\n"); |
} |
- if (!utf8_check.empty()) { |
- // If loop_via_iterators is true then ptr is actually an iterator, and we |
- // create a pointer by prefixing it with "&*". |
- printer->Print( |
- StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n") |
- .c_str()); |
+ printer->Print(variables_, |
+ " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" |
+ " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" |
+ " $number$, *entry, output);\n"); |
+ |
+ printer->Indent(); |
+ printer->Indent(); |
+ |
+ const FieldDescriptor* key_field = |
+ descriptor_->message_type()->FindFieldByName("key"); |
+ const FieldDescriptor* value_field = |
+ descriptor_->message_type()->FindFieldByName("value"); |
+ if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
+ GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, |
+ "it->first.data(), it->first.length(),\n", |
+ printer); |
+ } |
+ if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
+ GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, |
+ "it->second.data(), it->second.length(),\n", |
+ printer); |
} |
printer->Outdent(); |
+ printer->Outdent(); |
+ |
printer->Print( |
- "}\n"); |
-} |
+ " }\n"); |
-void MapFieldGenerator:: |
-GenerateSerializeWithCachedSizes(io::Printer* printer) const { |
- std::map<string, string> variables(variables_); |
- variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" + |
- variables["stream_writer"] + "(\n " + |
- variables["number"] + ", *entry, output)"; |
- variables["deterministic"] = "output->IsSerializationDeterministic()"; |
- GenerateSerializeWithCachedSizes(printer, variables); |
+ // If entry is allocated by arena, its desctructor should be avoided. |
+ if (SupportsArenas(descriptor_)) { |
+ printer->Print(variables_, |
+ " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
+ " entry.release();\n" |
+ " }\n"); |
+ } |
+ |
+ printer->Print("}\n"); |
} |
void MapFieldGenerator:: |
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
- std::map<string, string> variables(variables_); |
- variables["write_entry"] = |
- "target = ::google::protobuf::internal::WireFormatLite::\n" |
- " InternalWrite" + variables["declared_type"] + |
- "NoVirtualToArray(\n " + variables["number"] + |
- ", *entry, deterministic, target);\n"; |
- variables["deterministic"] = "deterministic"; |
- GenerateSerializeWithCachedSizes(printer, variables); |
-} |
+ printer->Print(variables_, |
+ "{\n" |
+ " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
+ " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
+ " it = this->$name$().begin();\n" |
+ " it != this->$name$().end(); ++it) {\n"); |
+ |
+ // If entry is allocated by arena, its desctructor should be avoided. |
+ if (SupportsArenas(descriptor_)) { |
+ printer->Print(variables_, |
+ " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
+ " entry.release();\n" |
+ " }\n"); |
+ } |
+ |
+ printer->Print(variables_, |
+ " 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"); |
-void MapFieldGenerator::GenerateSerializeWithCachedSizes( |
- io::Printer* printer, const std::map<string, string>& variables) const { |
- printer->Print(variables, |
- "if (!this->$name$().empty()) {\n"); |
printer->Indent(); |
+ printer->Indent(); |
+ |
const FieldDescriptor* key_field = |
descriptor_->message_type()->FindFieldByName("key"); |
const FieldDescriptor* value_field = |
descriptor_->message_type()->FindFieldByName("value"); |
- const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; |
- const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; |
- |
- printer->Print(variables, |
- "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n" |
- " ConstPtr;\n"); |
- if (string_key) { |
- printer->Print(variables, |
- "typedef ConstPtr SortItem;\n" |
- "typedef ::google::protobuf::internal::" |
- "CompareByDerefFirst<SortItem> Less;\n"); |
- } else { |
- printer->Print(variables, |
- "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > " |
- "SortItem;\n" |
- "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Less;\n"); |
+ if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
+ GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, |
+ "it->first.data(), it->first.length(),\n", |
+ printer); |
} |
- string utf8_check; |
- if (string_key || string_value) { |
- printer->Print( |
- "struct Utf8Check {\n" |
- " static void Check(ConstPtr p) {\n"); |
- printer->Indent(); |
- printer->Indent(); |
- if (string_key) { |
- GenerateUtf8CheckCodeForString(key_field, options_, false, variables, |
- "p->first.data(), p->first.length(),\n", |
- printer); |
- } |
- if (string_value) { |
- GenerateUtf8CheckCodeForString(value_field, options_, false, variables, |
- "p->second.data(), p->second.length(),\n", |
- printer); |
- } |
- printer->Outdent(); |
- printer->Outdent(); |
- printer->Print( |
- " }\n" |
- "};\n"); |
- utf8_check = "Utf8Check::Check"; |
+ if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
+ GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, |
+ "it->second.data(), it->second.length(),\n", |
+ printer); |
} |
- printer->Print(variables, |
- "\n" |
- "if ($deterministic$ &&\n" |
- " this->$name$().size() > 1) {\n" |
- " ::google::protobuf::scoped_array<SortItem> items(\n" |
- " new SortItem[this->$name$().size()]);\n" |
- " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n" |
- " size_type n = 0;\n" |
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
- " it = this->$name$().begin();\n" |
- " it != this->$name$().end(); ++it, ++n) {\n" |
- " items[n] = SortItem(&*it);\n" |
- " }\n" |
- " ::std::sort(&items[0], &items[n], Less());\n"); |
- printer->Indent(); |
- GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_), |
- utf8_check, "for (size_type i = 0; i < n; i++)", |
- string_key ? "items[i]" : "items[i].second", false); |
- printer->Outdent(); |
- printer->Print( |
- "} else {\n"); |
- printer->Indent(); |
- GenerateSerializationLoop( |
- printer, variables, SupportsArenas(descriptor_), utf8_check, |
- "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
- " it = this->$name$().begin();\n" |
- " it != this->$name$().end(); ++it)", |
- "it", true); |
printer->Outdent(); |
- printer->Print("}\n"); |
printer->Outdent(); |
+ printer->Print( |
+ " }\n"); |
+ |
+ // If entry is allocated by arena, its desctructor should be avoided. |
+ if (SupportsArenas(descriptor_)) { |
+ printer->Print(variables_, |
+ " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
+ " entry.release();\n" |
+ " }\n"); |
+ } |
+ |
printer->Print("}\n"); |
} |
void MapFieldGenerator:: |
GenerateByteSize(io::Printer* printer) const { |
printer->Print(variables_, |
- "total_size += $tag_size$ *\n" |
- " ::google::protobuf::internal::FromIntSize(this->$name$_size());\n" |
+ "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" |