diff options
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_message_field.cc')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_message_field.cc | 336 |
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" |