Index: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc |
diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc |
index 332c0264fc9d0547ba1b351c1b2cd2929264f456..914496577bbd02a1a4fa6f83992b4ef781dcaca4 100644 |
--- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc |
+++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc |
@@ -45,7 +45,7 @@ namespace cpp { |
namespace { |
void SetMessageVariables(const FieldDescriptor* descriptor, |
- map<string, string>* variables, |
+ std::map<string, string>* variables, |
const Options& options) { |
SetCommonFieldVariables(descriptor, variables, options); |
(*variables)["type"] = FieldMessageTypeName(descriptor); |
@@ -161,8 +161,7 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( |
" if ($name$_ == NULL) {\n" |
" return NULL;\n" |
" } else {\n" |
- " $type$* temp = new $type$;\n" |
- " temp->MergeFrom(*$name$_);\n" |
+ " $type$* temp = new $type$(*$name$_);\n" |
" $name$_ = NULL;\n" |
" return temp;\n" |
" }\n" |
@@ -219,7 +218,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
return; |
} |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
// For the CRTP base class, all mutation methods are dependent, and so |
// they must be in the header. |
variables["dependent_classname"] = |
@@ -346,24 +345,30 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
void MessageFieldGenerator:: |
GenerateInlineAccessorDefinitions(io::Printer* printer, |
bool is_inline) const { |
- map<string, string> variables(variables_); |
- variables["inline"] = is_inline ? "inline " : ""; |
- printer->Print(variables, |
- "$inline$const $type$& $classname$::$name$() const {\n" |
- " // @@protoc_insertion_point(field_get:$full_name$)\n"); |
- |
- PrintHandlingOptionalStaticInitializers( |
- variables, descriptor_->file(), options_, printer, |
- // With static initializers. |
- " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n", |
- // Without. |
- " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n"); |
- printer->Print(variables, "}\n"); |
- |
if (dependent_field_) { |
+ // for dependent fields we cannot access its internal_default_instance, |
+ // because the type is incomplete. |
+ // TODO(gerbens) deprecate dependent base class. |
+ std::map<string, string> variables(variables_); |
+ variables["inline"] = is_inline ? "inline " : ""; |
+ printer->Print(variables, |
+ "$inline$const $type$& $classname$::$name$() const {\n" |
+ " // @@protoc_insertion_point(field_get:$full_name$)\n" |
+ " return $name$_ != NULL ? *$name$_\n" |
+ " : *internal_default_instance()->$name$_;\n" |
+ "}\n"); |
return; |
} |
+ std::map<string, string> variables(variables_); |
+ variables["inline"] = is_inline ? "inline " : ""; |
+ printer->Print(variables, |
+ "$inline$const $type$& $classname$::$name$() const {\n" |
+ " // @@protoc_insertion_point(field_get:$full_name$)\n" |
+ " return $name$_ != NULL ? *$name$_\n" |
+ " : *$type$::internal_default_instance();\n" |
+ "}\n"); |
+ |
if (SupportsArenas(descriptor_)) { |
printer->Print(variables, |
"$inline$" |
@@ -464,7 +469,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, |
void MessageFieldGenerator:: |
GenerateClearingCode(io::Printer* printer) const { |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
if (!HasFieldPresence(descriptor_->file())) { |
// If we don't have has-bits, message presence is indicated only by ptr != |
@@ -481,6 +486,26 @@ GenerateClearingCode(io::Printer* printer) const { |
} |
void MessageFieldGenerator:: |
+GenerateMessageClearingCode(io::Printer* printer) const { |
+ std::map<string, string> variables(variables_); |
+ variables["type"] = FieldMessageTypeName(descriptor_); |
+ |
+ if (!HasFieldPresence(descriptor_->file())) { |
+ // If we don't have has-bits, message presence is indicated only by ptr != |
+ // NULL. Thus on clear, we need to delete the object. |
+ printer->Print(variables_, |
+ "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n" |
+ " delete $name$_;\n" |
+ "}\n" |
+ "$name$_ = NULL;\n"); |
+ } else { |
+ printer->Print(variables_, |
+ "GOOGLE_DCHECK($name$_ != NULL);\n" |
+ "$name$_->$type$::Clear();\n"); |
+ } |
+} |
+ |
+void MessageFieldGenerator:: |
GenerateMergingCode(io::Printer* printer) const { |
printer->Print(variables_, |
"mutable_$name$()->$type$::MergeFrom(from.$name$());\n"); |
@@ -492,11 +517,51 @@ GenerateSwappingCode(io::Printer* printer) const { |
} |
void MessageFieldGenerator:: |
+GenerateDestructorCode(io::Printer* printer) const { |
+ // In google3 a default instance will never get deleted so we don't need to |
+ // worry about that but in opensource protobuf default instances are deleted |
+ // in shutdown process and we need to take special care when handling them. |
+ printer->Print(variables_, |
+ "if (this != internal_default_instance()) {\n" |
+ " delete $name$_;\n" |
+ "}\n"); |
+} |
+ |
+void MessageFieldGenerator:: |
GenerateConstructorCode(io::Printer* printer) const { |
printer->Print(variables_, "$name$_ = NULL;\n"); |
} |
void MessageFieldGenerator:: |
+GenerateCopyConstructorCode(io::Printer* printer) const { |
+ // For non-Arena enabled messages, everything always goes on the heap. |
+ // |
+ // For Arena enabled messages, the logic is a bit more convoluted. |
+ // |
+ // In the copy constructor, we call InternalMetadataWithArena::MergeFrom, |
+ // which does *not* copy the Arena pointer. In the generated MergeFrom |
+ // (see MessageFieldGenerator::GenerateMergingCode), we: |
+ // -> copy the has bits (but this is done in bulk by a memcpy in the copy |
+ // constructor) |
+ // -> check whether the destination field pointer is NULL (it will be, since |
+ // we're initializing it and would have called SharedCtor) and if so: |
+ // -> call _slow_mutable_$name$(), which calls either |
+ // ::google::protobuf::Arena::CreateMessage<>(GetArenaNoVirtual()), or |
+ // ::google::protobuf::Arena::Create<>(GetArenaNoVirtual()) |
+ // |
+ // At this point, GetArenaNoVirtual returns NULL since the Arena pointer |
+ // wasn't copied, so both of these methods allocate the submessage on the |
+ // heap. |
+ |
+ printer->Print(variables_, |
+ "if (from.has_$name$()) {\n" |
+ " $name$_ = new $type$(*from.$name$_);\n" |
+ "} else {\n" |
+ " $name$_ = NULL;\n" |
+ "}\n"); |
+} |
+ |
+void MessageFieldGenerator:: |
GenerateMergeFromCodedStream(io::Printer* printer) const { |
if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { |
printer->Print(variables_, |
@@ -520,8 +585,8 @@ void MessageFieldGenerator:: |
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
printer->Print(variables_, |
"target = ::google::protobuf::internal::WireFormatLite::\n" |
- " Write$declared_type$NoVirtualToArray(\n" |
- " $number$, *$non_null_ptr_to_name$, target);\n"); |
+ " InternalWrite$declared_type$NoVirtualToArray(\n" |
+ " $number$, *$non_null_ptr_to_name$, false, target);\n"); |
} |
void MessageFieldGenerator:: |
@@ -576,7 +641,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
if (!dependent_base_) { |
return; |
} |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["inline"] = "inline "; |
variables["dependent_classname"] = |
DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>"; |
@@ -596,7 +661,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, |
if (dependent_base_) { |
return; |
} |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["inline"] = is_inline ? "inline " : ""; |
variables["dependent_classname"] = variables["classname"]; |
variables["this_message"] = ""; |
@@ -610,16 +675,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, |
void MessageOneofFieldGenerator:: |
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["field_member"] = |
variables["oneof_prefix"] + variables["name"] + "_"; |
//printer->Print(variables, |
} |
-void MessageOneofFieldGenerator:: |
-InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables, |
- io::Printer* printer) const { |
+void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions( |
+ const std::map<string, string>& variables, io::Printer* printer) const { |
printer->Print(variables, |
"$tmpl$" |
"$inline$ " |
@@ -663,8 +727,8 @@ InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables, |
" if ($this_message$GetArenaNoVirtual() != NULL) {\n" |
// N.B.: safe to use the underlying field pointer here because we are sure |
// that it is non-NULL (because has_$name$() returned true). |
- " $dependent_typename$* temp = new $dependent_typename$;\n" |
- " temp->MergeFrom(*$field_member$);\n" |
+ " $dependent_typename$* temp = " |
+ "new $dependent_typename$(*$field_member$);\n" |
" $field_member$ = NULL;\n" |
" return temp;\n" |
" } else {\n" |
@@ -789,7 +853,7 @@ InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables, |
void MessageOneofFieldGenerator:: |
GenerateClearingCode(io::Printer* printer) const { |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
if (SupportsArenas(descriptor_)) { |
printer->Print(variables, |
@@ -803,11 +867,22 @@ GenerateClearingCode(io::Printer* printer) const { |
} |
void MessageOneofFieldGenerator:: |
+GenerateMessageClearingCode(io::Printer* printer) const { |
+ GenerateClearingCode(printer); |
+} |
+ |
+void MessageOneofFieldGenerator:: |
GenerateSwappingCode(io::Printer* printer) const { |
// Don't print any swapping code. Swapping the union will swap this field. |
} |
void MessageOneofFieldGenerator:: |
+GenerateDestructorCode(io::Printer* printer) const { |
+ // We inherit from MessageFieldGenerator, so we need to override the default |
+ // behavior. |
+} |
+ |
+void MessageOneofFieldGenerator:: |
GenerateConstructorCode(io::Printer* printer) const { |
// Don't print any constructor code. The field is in a union. We allocate |
// space only when this field is used. |
@@ -879,7 +954,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
if (!dependent_field_) { |
return; |
} |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
// For the CRTP base class, all mutation methods are dependent, and so |
// they must be in the header. |
variables["dependent_classname"] = |
@@ -910,7 +985,6 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
" return $this_message$$name$_.Add();\n" |
"}\n"); |
- |
if (dependent_getter_) { |
printer->Print(variables, |
"template <class T>\n" |
@@ -934,7 +1008,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { |
void RepeatedMessageFieldGenerator:: |
GenerateInlineAccessorDefinitions(io::Printer* printer, |
bool is_inline) const { |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["inline"] = is_inline ? "inline " : ""; |
if (!dependent_getter_) { |
@@ -984,7 +1058,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, |
void RepeatedMessageFieldGenerator:: |
GenerateClearingCode(io::Printer* printer) const { |
- map<string, string> variables(variables_); |
+ std::map<string, string> variables(variables_); |
variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
printer->Print(variables, "$this_message$$name$_.Clear();\n"); |
} |
@@ -1033,20 +1107,26 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
printer->Print(variables_, |
"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" |
+ " InternalWrite$declared_type$NoVirtualToArray(\n" |
+ " $number$, this->$name$(i), false, target);\n" |
"}\n"); |
} |
void RepeatedMessageFieldGenerator:: |
GenerateByteSize(io::Printer* printer) const { |
printer->Print(variables_, |
- "total_size += $tag_size$ * this->$name$_size();\n" |
- "for (int i = 0; i < this->$name$_size(); i++) {\n" |
+ "{\n" |
+ " unsigned int count = this->$name$_size();\n"); |
+ printer->Indent(); |
+ printer->Print(variables_, |
+ "total_size += $tag_size$UL * count;\n" |
+ "for (unsigned int i = 0; i < count; i++) {\n" |
" total_size +=\n" |
" ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n" |
" this->$name$(i));\n" |
"}\n"); |
+ printer->Outdent(); |
+ printer->Print("}\n"); |
} |
} // namespace cpp |