aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/cpp/cpp_message_field.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_message_field.cc')
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc336
1 files changed, 273 insertions, 63 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index da4c3950..5888f51a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -45,13 +45,42 @@ namespace cpp {
namespace {
+// When we are generating code for implicit weak fields, we need to insert some
+// additional casts. These functions return the casted expression if
+// implicit_weak_field is true but otherwise return the original expression.
+// Ordinarily a static_cast is enough to cast google::protobuf::MessageLite* to a class
+// deriving from it, but we need a reinterpret_cast in cases where the generated
+// message is forward-declared but its full definition is not visible.
+string StaticCast(const string& type, const string& expression,
+ bool implicit_weak_field) {
+ if (implicit_weak_field) {
+ return "static_cast< " + type + " >(" + expression + ")";
+ } else {
+ return expression;
+ }
+}
+
+string ReinterpretCast(const string& type, const string& expression,
+ bool implicit_weak_field) {
+ if (implicit_weak_field) {
+ return "reinterpret_cast< " + type + " >(" + expression + ")";
+ } else {
+ return expression;
+ }
+}
+
void SetMessageVariables(const FieldDescriptor* descriptor,
std::map<string, string>* variables,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
+ (*variables)["casted_member"] =
+ StaticCast((*variables)["type"] + "*", (*variables)["name"] + "_",
+ IsImplicitWeakField(descriptor, options));
(*variables)["type_default_instance"] =
DefaultInstanceName(descriptor->message_type());
+ (*variables)["type_reference_function"] =
+ ReferenceFunctionName(descriptor->message_type());
if (descriptor->options().weak() || !descriptor->containing_oneof()) {
(*variables)["non_null_ptr_to_name"] =
StrCat("this->", (*variables)["name"], "_");
@@ -85,7 +114,8 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
: FieldGenerator(options),
descriptor_(descriptor),
- dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
+ implicit_weak_field_(IsImplicitWeakField(descriptor, options)) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -93,7 +123,11 @@ MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
- printer->Print(variables_, "$type$* $name$_;\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables_, "google::protobuf::MessageLite* $name$_;\n");
+ } else {
+ printer->Print(variables_, "$type$* $name$_;\n");
+ }
}
void MessageFieldGenerator::
@@ -108,7 +142,11 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const {
if (!dependent_field_) {
return;
}
- // Arena manipulation code is out-of-line in the derived message class.
+ // Arena manipulation code is out-of-line in the derived message class. The
+ // one exception is unsafe_arena_release_; this method has to be inline so
+ // that when the implicit weak field optimization is enabled, the method does
+ // not introduce a strong dependency on the submessage type unless the
+ // accessor actually gets called somewhere.
printer->Print(variables_,
"$deprecated_attr$$type$* ${$mutable_$name$$}$();\n");
printer->Annotate("{", "}", descriptor_);
@@ -118,14 +156,22 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const {
"$deprecated_attr$void ${$set_allocated_$name$$}$"
"($type$* $name$);\n");
printer->Annotate("{", "}", descriptor_);
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ variables_,
+ "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
}
void MessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
- "private:\n"
- "void _slow_mutable_$name$();\n");
+ "private:\n");
+ if (!implicit_weak_field_) {
+ printer->Print(variables_, "void _slow_mutable_$name$();\n");
+ }
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables_,
"void _slow_set_allocated_$name$(\n"
@@ -135,6 +181,16 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"$type$* _slow_$release_name$();\n"
"public:\n");
}
+ if (implicit_weak_field_) {
+ // These private accessors are used by MergeFrom and
+ // MergePartialFromCodedStream, and their purpose is to provide access to
+ // the field without creating a strong dependency on the message type.
+ printer->Print(variables_,
+ "private:\n"
+ "const google::protobuf::MessageLite& _internal_$name$() const;\n"
+ "google::protobuf::MessageLite* _internal_mutable_$name$();\n"
+ "public:\n");
+ }
GenerateGetterDeclaration(printer);
if (!dependent_field_) {
printer->Print(variables_,
@@ -146,12 +202,14 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"$deprecated_attr$void ${$set_allocated_$name$$}$"
"($type$* $name$);\n");
printer->Annotate("{", "}", descriptor_);
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ variables_,
+ "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n");
+ printer->Annotate("{", "}", descriptor_);
+ }
}
if (SupportsArenas(descriptor_)) {
- printer->Print(
- variables_,
- "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n");
- printer->Annotate("{", "}", descriptor_);
printer->Print(variables_,
"$deprecated_attr$void "
"${$unsafe_arena_set_allocated_$name$$}$(\n"
@@ -162,9 +220,39 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
io::Printer* printer) const {
- if (SupportsArenas(descriptor_)) {
+ if (implicit_weak_field_) {
printer->Print(variables_,
- "void $classname$::_slow_mutable_$name$() {\n");
+ "const google::protobuf::MessageLite& $classname$::_internal_$name$() const {\n"
+ " if ($name$_ != NULL) {\n"
+ " return *$name$_;\n"
+ " } else if (&$type_default_instance$ != NULL) {\n"
+ " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &$type_default_instance$);\n"
+ " } else {\n"
+ " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &::google::protobuf::internal::implicit_weak_message_default_instance);\n"
+ " }\n"
+ "}\n");
+ }
+ if (SupportsArenas(descriptor_)) {
+ if (implicit_weak_field_) {
+ printer->Print(variables_,
+ "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " if ($name$_ == NULL) {\n"
+ " if (&$type_default_instance$ == NULL) {\n"
+ " $name$_ = ::google::protobuf::Arena::CreateMessage<\n"
+ " ::google::protobuf::internal::ImplicitWeakMessage>(\n"
+ " GetArenaNoVirtual());\n"
+ " } else {\n"
+ " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &$type_default_instance$)->New(GetArenaNoVirtual());\n"
+ " }\n"
+ " }\n"
+ " return $name$_;\n");
+ } else {
+ printer->Print(variables_,
+ "void $classname$::_slow_mutable_$name$() {\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables_,
" $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
@@ -174,23 +262,27 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
" $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
" GetArenaNoVirtual());\n");
}
+ }
printer->Print(variables_,
"}\n"
"$type$* $classname$::_slow_$release_name$() {\n"
" if ($name$_ == NULL) {\n"
" return NULL;\n"
- " } else {\n"
- " $type$* temp = new $type$(*$name$_);\n"
- " $name$_ = NULL;\n"
- " return temp;\n"
+ " } else {\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables_,
+ " google::protobuf::MessageLite* temp = $name$_->New();\n"
+ " temp->CheckTypeAndMergeFrom(*$name$_);\n");
+ } else {
+ printer->Print(variables_,
+ " $type$* temp = new $type$(*$name$_);\n");
+ }
+ printer->Print(variables_, " $name$_ = NULL;\n");
+ printer->Print(
+ " return $result$;\n", "result",
+ StaticCast(variables_.at("type") + "*", "temp", implicit_weak_field_));
+ printer->Print(variables_,
" }\n"
- "}\n"
- "$type$* $classname$::unsafe_arena_release_$name$() {\n"
- " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
- " $clear_hasbit$\n"
- " $type$* temp = $name$_;\n"
- " $name$_ = NULL;\n"
- " return temp;\n"
"}\n");
if (SupportsArenas(descriptor_->message_type())) {
// NOTE: the same logic is mirrored in weak_message_field.cc. Any
@@ -202,12 +294,23 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
" ::google::protobuf::Arena::GetArena(*$name$) == NULL) {\n"
" message_arena->Own(*$name$);\n"
" } else if (message_arena !=\n"
- " ::google::protobuf::Arena::GetArena(*$name$)) {\n"
- " $type$* new_$name$ = \n"
- " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " message_arena);\n"
- " new_$name$->CopyFrom(**$name$);\n"
- " *$name$ = new_$name$;\n"
+ " ::google::protobuf::Arena::GetArena(*$name$)) {\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables_,
+ " google::protobuf::MessageLite* new_$name$ =\n"
+ " reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &$type_default_instance$)->New(GetArenaNoVirtual());\n"
+ " new_$name$->CheckTypeAndMergeFrom(**$name$);\n"
+ " *$name$ = static_cast< $type$* >(new_$name$);\n");
+ } else {
+ printer->Print(variables_,
+ " $type$* new_$name$ =\n"
+ " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
+ " message_arena);\n"
+ " new_$name$->CopyFrom(**$name$);\n"
+ " *$name$ = new_$name$;\n");
+ }
+ printer->Print(variables_,
" }\n"
"}\n");
}
@@ -228,6 +331,20 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
":$full_name$)\n"
"}\n");
+ } else if (implicit_weak_field_) {
+ printer->Print(variables_,
+ "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " if ($name$_ == NULL) {\n"
+ " if (&$type_default_instance$ == NULL) {\n"
+ " $name$_ = new ::google::protobuf::internal::ImplicitWeakMessage;\n"
+ " } else {\n"
+ " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &$type_default_instance$)->New();\n"
+ " }\n"
+ " }\n"
+ " return $name$_;\n"
+ "}\n");
}
}
@@ -243,6 +360,10 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
variables["dependent_classname"] =
DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
variables["this_message"] = DependentBaseDownCast();
+ variables["casted_reference"] =
+ ReinterpretCast(variables["dependent_typename"] + "*&",
+ variables["this_message"] + variables["name"] + "_",
+ implicit_weak_field_);
if (!variables["set_hasbit"].empty()) {
variables["set_hasbit"] =
variables["this_message"] + variables["set_hasbit"];
@@ -255,19 +376,39 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
if (SupportsArenas(descriptor_)) {
printer->Print(variables,
"template <class T>\n"
- "inline $type$* $dependent_classname$::mutable_$name$() {\n"
+ "inline $type$* $dependent_classname$::mutable_$name$() {\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
" $set_hasbit$\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
- " if ($name$_ == NULL) {\n"
- " $this_message$_slow_mutable_$name$();\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
+ " if ($name$_ == NULL) {\n");
+ if (implicit_weak_field_) {
+ if (SupportsArenas(descriptor_->message_type())) {
+ printer->Print(variables,
+ " $name$_ = reinterpret_cast<$dependent_typename$*>(\n"
+ " reinterpret_cast<const google::protobuf::MessageLite*>(\n"
+ " &$type_default_instance$)->New(\n"
+ " $this_message$GetArenaNoVirtual()));\n");
+ }
+ } else {
+ printer->Print(variables,
+ " $this_message$_slow_mutable_$name$();\n");
+ }
+ printer->Print(variables,
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
"}\n"
"template <class T>\n"
"inline $type$* $dependent_classname$::$release_name$() {\n"
- " // @@protoc_insertion_point(field_release:$full_name$)\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
" $clear_hasbit$\n"
" if ($this_message$GetArenaNoVirtual() != NULL) {\n"
" return $this_message$_slow_$release_name$();\n"
@@ -281,7 +422,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
"inline void $dependent_classname$::"
"set_allocated_$name$($type$* $name$) {\n"
" ::google::protobuf::Arena* message_arena = $this_message$GetArenaNoVirtual();\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
" if (message_arena == NULL) {\n"
" delete $name$_;\n"
" }\n"
@@ -311,13 +452,27 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
" }\n"
// TODO(dlj): move insertion points to message class.
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point("
+ "field_unsafe_arena_release:$full_name$)\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
+ " $clear_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
+ " $dependent_typename$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
"}\n");
} else {
printer->Print(variables,
"template <class T>\n"
"inline $type$* $dependent_classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
" if ($name$_ == NULL) {\n"
" $name$_ = new $dependent_typename$;\n"
" }\n"
@@ -326,9 +481,13 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"template <class T>\n"
"inline $type$* $dependent_classname$::$release_name$() {\n"
- " // @@protoc_insertion_point(field_release:$full_name$)\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
" $clear_hasbit$\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
" $dependent_typename$* temp = $name$_;\n"
" $name$_ = NULL;\n"
" return temp;\n"
@@ -336,7 +495,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
"template <class T>\n"
"inline void $dependent_classname$::"
"set_allocated_$name$($type$* $name$) {\n"
- " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$*& $name$_ = $casted_reference$;\n"
" delete $name$_;\n");
if (SupportsArenas(descriptor_->message_type())) {
@@ -366,9 +525,16 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const {
std::map<string, string> variables(variables_);
variables["inline"] = is_inline ? "inline " : "";
+ variables["const_member"] = ReinterpretCast(
+ "const " + variables["type"] + "*", variables["name"] + "_",
+ implicit_weak_field_);
printer->Print(variables,
- "$inline$const $type$& $classname$::$name$() const {\n"
- " const $type$* p = $name$_;\n"
+ "$inline$const $type$& $classname$::$name$() const {\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
+ " const $type$* p = $const_member$;\n"
" // @@protoc_insertion_point(field_get:$full_name$)\n"
" return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n"
" &$type_default_instance$);\n"
@@ -381,11 +547,18 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"$inline$"
"$type$* $classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
- " if ($name$_ == NULL) {\n"
- " _slow_mutable_$name$();\n"
+ " if ($name$_ == NULL) {\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables,
+ " _internal_mutable_$name$();\n");
+ } else {
+ printer->Print(variables,
+ " _slow_mutable_$name$();\n");
+ }
+ printer->Print(variables,
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $name$_;\n"
+ " return $casted_member$;\n"
"}\n"
"$inline$"
"$type$* $classname$::$release_name$() {\n"
@@ -394,7 +567,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" if (GetArenaNoVirtual() != NULL) {\n"
" return _slow_$release_name$();\n"
" } else {\n"
- " $type$* temp = $name$_;\n"
+ " $type$* temp = $casted_member$;\n"
" $name$_ = NULL;\n"
" return temp;\n"
" }\n"
@@ -429,6 +602,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" $clear_hasbit$\n"
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n"
+ "$inline$"
+ "$type$* $classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point("
+ "field_unsafe_arena_release:$full_name$)\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables, " $type_reference_function$();\n");
+ }
+ printer->Print(variables,
+ " $clear_hasbit$\n"
+ " $type$* temp = $casted_member$;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
"}\n");
} else {
printer->Print(variables,
@@ -439,13 +625,13 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" $name$_ = new $type$;\n"
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $name$_;\n"
+ " return $casted_member$;\n"
"}\n"
"$inline$"
"$type$* $classname$::$release_name$() {\n"
" // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
- " $type$* temp = $name$_;\n"
+ " $type$* temp = $casted_member$;\n"
" $name$_ = NULL;\n"
" return temp;\n"
"}\n"
@@ -485,6 +671,9 @@ GenerateClearingCode(io::Printer* printer) const {
"if ($this_message$GetArenaNoVirtual() == NULL && "
"$this_message$$name$_ != NULL) delete $this_message$$name$_;\n"
"$this_message$$name$_ = NULL;\n");
+ } else if (implicit_weak_field_) {
+ printer->Print(variables,
+ "if ($this_message$$name$_ != NULL) $this_message$$name$_->Clear();\n");
} else {
printer->Print(variables,
"if ($this_message$$name$_ != NULL) $this_message$$name$_->"
@@ -502,6 +691,10 @@ GenerateMessageClearingCode(io::Printer* printer) const {
" delete $name$_;\n"
"}\n"
"$name$_ = NULL;\n");
+ } else if (implicit_weak_field_) {
+ printer->Print(variables_,
+ "GOOGLE_DCHECK($name$_ != NULL);\n"
+ "$name$_->Clear();\n");
} else {
printer->Print(variables_,
"GOOGLE_DCHECK($name$_ != NULL);\n"
@@ -511,8 +704,14 @@ GenerateMessageClearingCode(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
- printer->Print(variables_,
- "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+ if (implicit_weak_field_) {
+ printer->Print(variables_,
+ "_internal_mutable_$name$()->CheckTypeAndMergeFrom(\n"
+ " from._internal_$name$());\n");
+ } else {
+ printer->Print(variables_,
+ "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+ }
}
void MessageFieldGenerator::
@@ -557,17 +756,24 @@ GenerateCopyConstructorCode(io::Printer* printer) const {
// 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");
+ string new_expression = (implicit_weak_field_ ? "from.$name$_->New()"
+ : "new $type$(*from.$name$_)");
+ string output =
+ "if (from.has_$name$()) {\n"
+ " $name$_ = " + new_expression + ";\n"
+ "} else {\n"
+ " $name$_ = NULL;\n"
+ "}\n";
+ printer->Print(variables_, output.c_str());
}
void MessageFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
- if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ if (implicit_weak_field_) {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(\n"
+ " input, _internal_mutable_$name$()));\n");
+ } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(variables_,
"DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
" input, mutable_$name$()));\n");
@@ -595,9 +801,11 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
- printer->Print(variables_,
+ std::map<string, string> variables = variables_;
+ variables["no_virtual"] = (implicit_weak_field_ ? "" : "NoVirtual");
+ printer->Print(variables,
"total_size += $tag_size$ +\n"
- " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size$no_virtual$(\n"
" *$non_null_ptr_to_name$);\n");
}
@@ -771,13 +979,15 @@ void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions(
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n"
- "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::unsafe_arena_release_$name$() {\n"
" // @@protoc_insertion_point(field_unsafe_arena_release"
":$full_name$)\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ " if ($this_message$has_$name$()) {\n"
+ " $this_message$clear_has_$oneof_name$();\n"
+ " $dependent_typename$* temp = $this_message$$oneof_prefix$$name$_;\n"
+ " $this_message$$oneof_prefix$$name$_ = NULL;\n"
" return temp;\n"
" } else {\n"
" return NULL;\n"