diff options
author | Feng Xiao <xfxyjwf@gmail.com> | 2014-11-10 17:34:54 -0800 |
---|---|---|
committer | Feng Xiao <xfxyjwf@gmail.com> | 2014-11-10 17:34:54 -0800 |
commit | 6ef984af4b0c63c1c33127a12dcfc8e6359f0c9e (patch) | |
tree | d17c61ff9f3ae28224fbddac6d26bfc59e2cf755 /src/google/protobuf/compiler/cpp/cpp_string_field.cc | |
parent | baca1a8a1aa180c42de6278d3b8286c4496c6a10 (diff) |
Down-integrate from internal code base.
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_string_field.cc')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_string_field.cc | 538 |
1 files changed, 369 insertions, 169 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 180d236b..a2a8c81c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -52,9 +52,14 @@ void SetStringVariables(const FieldDescriptor* descriptor, (*variables)["default"] = DefaultValue(descriptor); (*variables)["default_length"] = SimpleItoa(descriptor->default_value_string().length()); - (*variables)["default_variable"] = descriptor->default_value_string().empty() - ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()" - : "_default_" + FieldName(descriptor) + "_"; + string default_variable_string = + descriptor->default_value_string().empty() + ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()" + : "_default_" + FieldName(descriptor) + "_"; + (*variables)["default_variable"] = default_variable_string; + (*variables)["default_value_init"] = + descriptor->default_value_string().empty() + ? "" : "*" + default_variable_string; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; // NOTE: Escaped here to unblock proto1->proto2 migration. @@ -63,6 +68,8 @@ void SetStringVariables(const FieldDescriptor* descriptor, SafeFunctionName(descriptor->containing_type(), descriptor, "release_"); (*variables)["full_name"] = descriptor->full_name(); + + (*variables)["string_piece"] = "::std::string"; } } // namespace @@ -80,7 +87,19 @@ StringFieldGenerator::~StringFieldGenerator() {} void StringFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "::std::string* $name$_;\n"); + // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for + // string fields, even when SupportArenas(descriptor_) == false. Why? + // The simple answer is to avoid unmaintainable complexity. The reflection + // code assumes ArenaStringPtrs. These are *almost* in-memory-compatible with + // string*, except for the pointer tags and related ownership semantics. We + // could modify the runtime code to use string* for the not-supporting-arenas + // case, but this would require a way to detect which type of class was + // generated (adding overhead and complexity to GeneratedMessageReflection) + // and littering the runtime code paths with conditionals. It's simpler to + // stick with this but use lightweight accessors that assume arena == NULL. + // There should be very little overhead anyway because it's just a tagged + // pointer in-memory. + printer->Print(variables_, "::google::protobuf::internal::ArenaStringPtr $name$_;\n"); } void StringFieldGenerator:: @@ -125,6 +144,12 @@ GenerateAccessorDeclarations(io::Printer* printer) const { "inline ::std::string* mutable_$name$()$deprecation$;\n" "inline ::std::string* $release_name$()$deprecation$;\n" "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "inline ::std::string* unsafe_arena_release_$name$()$deprecation$;\n" + "inline void unsafe_arena_set_allocated_$name$(\n" + " ::std::string* $name$)$deprecation$;\n"); + } if (descriptor_->options().ctype() != FieldOptions::STRING) { @@ -136,74 +161,113 @@ GenerateAccessorDeclarations(io::Printer* printer) const { void StringFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" - " // @@protoc_insertion_point(field_get:$full_name$)\n" - " return *$name$_;\n" - "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" - " set_has_$name$();\n" - " if ($name$_ == $default_variable$) {\n" - " $name$_ = new ::std::string;\n" - " }\n" - " $name$_->assign(value);\n" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - " set_has_$name$();\n" - " if ($name$_ == $default_variable$) {\n" - " $name$_ = new ::std::string;\n" - " }\n" - " $name$_->assign(value);\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n" - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" - " set_has_$name$();\n" - " if ($name$_ == $default_variable$) {\n" - " $name$_ = new ::std::string;\n" - " }\n" - " $name$_->assign(reinterpret_cast<const char*>(value), size);\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" - " set_has_$name$();\n" - " if ($name$_ == $default_variable$) {\n"); - if (descriptor_->default_value_string().empty()) { + if (SupportsArenas(descriptor_)) { printer->Print(variables_, - " $name$_ = new ::std::string;\n"); + "inline const ::std::string& $classname$::$name$() const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " return $name$_.Get($default_variable$);\n" + "}\n" + "inline void $classname$::set_$name$(const ::std::string& value) {\n" + " $set_hasbit$\n" + " $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + " $set_hasbit$\n" + " $name$_.Set($default_variable$, $string_piece$(value),\n" + " GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + "}\n" + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + " $set_hasbit$\n" + " $name$_.Set($default_variable$, $string_piece$(\n" + " reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$() {\n" + " $set_hasbit$\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n" + "}\n" + "inline ::std::string* $classname$::$release_name$() {\n" + " $clear_hasbit$\n" + " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n" + "}\n" + "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" + " $clear_hasbit$\n" + " return $name$_.UnsafeArenaRelease($default_variable$,\n" + " GetArenaNoVirtual());\n" + "}\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if ($name$ != NULL) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " $name$_.SetAllocated($default_variable$, $name$,\n" + " GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n" + "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" + " ::std::string* $name$) {\n" + " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" + " if ($name$ != NULL) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " $set_hasbit$\n" + " $name$_.UnsafeArenaSetAllocated($default_variable$,\n" + " $name$, GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } else { + // No-arena case. printer->Print(variables_, - " $name$_ = new ::std::string(*$default_variable$);\n"); + "inline const ::std::string& $classname$::$name$() const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " return $name$_.GetNoArena($default_variable$);\n" + "}\n" + "inline void $classname$::set_$name$(const ::std::string& value) {\n" + " $set_hasbit$\n" + " $name$_.SetNoArena($default_variable$, value);\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + " $set_hasbit$\n" + " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + "}\n" + "inline " + "void $classname$::set_$name$(const $pointer_type$* value, " + "size_t size) {\n" + " $set_hasbit$\n" + " $name$_.SetNoArena($default_variable$,\n" + " $string_piece$(reinterpret_cast<const char*>(value), size));\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$() {\n" + " $set_hasbit$\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + " return $name$_.MutableNoArena($default_variable$);\n" + "}\n" + "inline ::std::string* $classname$::$release_name$() {\n" + " $clear_hasbit$\n" + " return $name$_.ReleaseNoArena($default_variable$);\n" + "}\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if ($name$ != NULL) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " $name$_.SetAllocatedNoArena($default_variable$, $name$);\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } - printer->Print(variables_, - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_;\n" - "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" - " clear_has_$name$();\n" - " if ($name$_ == $default_variable$) {\n" - " return NULL;\n" - " } else {\n" - " ::std::string* temp = $name$_;\n" - " $name$_ = const_cast< ::std::string*>($default_variable$);\n" - " return temp;\n" - " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" - " if ($name$_ != $default_variable$) {\n" - " delete $name$_;\n" - " }\n" - " if ($name$) {\n" - " set_has_$name$();\n" - " $name$_ = $name$;\n" - " } else {\n" - " clear_has_$name$();\n" - " $name$_ = const_cast< ::std::string*>($default_variable$);\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); } void StringFieldGenerator:: @@ -217,16 +281,26 @@ GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { void StringFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "if ($name$_ != $default_variable$) {\n" - " $name$_->clear();\n" - "}\n"); + // Two-dimension specialization here: supporting arenas or not, and default + // value is the empty string or not. Complexity here ensures the minimal + // number of branches / amount of extraneous code at runtime (given that the + // below methods are inlined one-liners)! + if (SupportsArenas(descriptor_)) { + if (descriptor_->default_value_string().empty()) { + printer->Print(variables_, + "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, + "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n"); + } } else { - printer->Print(variables_, - "if ($name$_ != $default_variable$) {\n" - " $name$_->assign(*$default_variable$);\n" - "}\n"); + if (descriptor_->default_value_string().empty()) { + printer->Print(variables_, + "$name$_.ClearToEmptyNoArena($default_variable$);\n"); + } else { + printer->Print(variables_, + "$name$_.ClearToDefaultNoArena($default_variable$);\n"); + } } } @@ -237,21 +311,24 @@ GenerateMergingCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); } void StringFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { printer->Print(variables_, - "$name$_ = const_cast< ::std::string*>($default_variable$);\n"); + "$name$_.UnsafeSetDefault($default_variable$);\n"); } void StringFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($name$_ != $default_variable$) {\n" - " delete $name$_;\n" - "}\n"); + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "$name$_.Destroy($default_variable$, GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, + "$name$_.DestroyNoArena($default_variable$);\n"); + } } void StringFieldGenerator:: @@ -276,13 +353,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { printer->Print(variables_, "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" " input, this->mutable_$name$()));\n"); + if (HasUtf8Verification(descriptor_->file()) && descriptor_->type() == FieldDescriptor::TYPE_STRING) { printer->Print(variables_, "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" " this->$name$().data(), this->$name$().length(),\n" " ::google::protobuf::internal::WireFormat::PARSE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } } @@ -294,7 +372,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" " this->$name$().data(), this->$name$().length(),\n" " ::google::protobuf::internal::WireFormat::SERIALIZE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } printer->Print(variables_, "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n" @@ -309,7 +387,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" " this->$name$().data(), this->$name$().length(),\n" " ::google::protobuf::internal::WireFormat::SERIALIZE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } printer->Print(variables_, "target =\n" @@ -338,84 +416,186 @@ StringOneofFieldGenerator::~StringOneofFieldGenerator() {} void StringOneofFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" - " if (has_$name$()) {\n" - " return *$oneof_prefix$$name$_;\n" - " }\n"); - if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, - " return ::google::protobuf::internal::GetEmptyStringAlreadyInited();\n"); - } else { - printer->Print(variables_, - " return *$default_variable$;\n"); - } - printer->Print(variables_, - "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" - " if (!has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $oneof_prefix$$name$_ = new ::std::string;\n" - " }\n" - " $oneof_prefix$$name$_->assign(value);\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - " if (!has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $oneof_prefix$$name$_ = new ::std::string;\n" - " }\n" - " $oneof_prefix$$name$_->assign(value);\n" - "}\n" - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" - " if (!has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $oneof_prefix$$name$_ = new ::std::string;\n" - " }\n" - " $oneof_prefix$$name$_->assign(\n" - " reinterpret_cast<const char*>(value), size);\n" - "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" - " if (!has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n"); - if (descriptor_->default_value_string().empty()) { + if (SupportsArenas(descriptor_)) { printer->Print(variables_, - " $oneof_prefix$$name$_ = new ::std::string;\n"); + "inline const ::std::string& $classname$::$name$() const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " if (has_$name$()) {\n" + " return $oneof_prefix$$name$_.Get($default_variable$);\n" + " }\n" + " return *$default_variable$;\n" + "}\n" + "inline void $classname$::set_$name$(const ::std::string& value) {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.Set($default_variable$, value,\n" + " GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.Set($default_variable$,\n" + " $string_piece$(value), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + "}\n" + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.Set($default_variable$, $string_piece$(\n" + " reinterpret_cast<const char*>(value), size),\n" + " GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$() {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " return $oneof_prefix$$name$_.Mutable($default_variable$,\n" + " GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::$release_name$() {\n" + " if (has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " return $oneof_prefix$$name$_.Release($default_variable$,\n" + " GetArenaNoVirtual());\n" + " } else {\n" + " return NULL;\n" + " }\n" + "}\n" + "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" + " if (has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " return $oneof_prefix$$name$_.UnsafeArenaRelease(\n" + " $default_variable$, GetArenaNoVirtual());\n" + " } else {\n" + " return NULL;\n" + " }\n" + "}\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if (!has_$name$()) {\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " clear_$oneof_name$();\n" + " if ($name$ != NULL) {\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.SetAllocated($default_variable$, $name$,\n" + " GetArenaNoVirtual());\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n" + "inline void $classname$::unsafe_arena_set_allocated_$name$(" + "::std::string* $name$) {\n" + " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" + " if (!has_$name$()) {\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " clear_$oneof_name$();\n" + " if ($name$) {\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeArenaSetAllocated($default_variable$, " + "$name$, GetArenaNoVirtual());\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } else { + // No-arena case. printer->Print(variables_, - " $oneof_prefix$$name$_ = new ::std::string(*$default_variable$);\n"); + "inline const ::std::string& $classname$::$name$() const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " if (has_$name$()) {\n" + " return $oneof_prefix$$name$_.GetNoArena($default_variable$);\n" + " }\n" + " return *$default_variable$;\n" + "}\n" + "inline void $classname$::set_$name$(const ::std::string& value) {\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.SetNoArena($default_variable$,\n" + " $string_piece$(value));\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + "}\n" + "inline " + "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.SetNoArena($default_variable$, $string_piece$(\n" + " reinterpret_cast<const char*>(value), size));\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::mutable_$name$() {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + " return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n" + "}\n" + "inline ::std::string* $classname$::$release_name$() {\n" + " if (has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n" + " } else {\n" + " return NULL;\n" + " }\n" + "}\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if (!has_$name$()) {\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " clear_$oneof_name$();\n" + " if ($name$ != NULL) {\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.SetAllocatedNoArena($default_variable$,\n" + " $name$);\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } - printer->Print(variables_, - " }\n" - " return $oneof_prefix$$name$_;\n" - "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" - " if (has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " ::std::string* temp = $oneof_prefix$$name$_;\n" - " $oneof_prefix$$name$_ = NULL;\n" - " return temp;\n" - " } else {\n" - " return NULL;\n" - " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" - " clear_$oneof_name$();\n" - " if ($name$) {\n" - " set_has_$name$();\n" - " $oneof_prefix$$name$_ = $name$;\n" - " }\n" - "}\n"); } void StringOneofFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "delete $oneof_prefix$$name$_;\n"); + "$oneof_prefix$$name$_.Destroy($default_variable$,\n" + " GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, + "$oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n"); + } } void StringOneofFieldGenerator:: @@ -425,25 +605,45 @@ GenerateSwappingCode(io::Printer* printer) const { void StringOneofFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { - if (!descriptor_->default_value_string().empty()) { + printer->Print(variables_, + " const_cast< ::google::protobuf::internal::ArenaStringPtr*>(" + "&$classname$_default_oneof_instance_->$name$_)->UnsafeSetDefault(" + "$default_variable$);\n"); +} + +void StringOneofFieldGenerator:: +GenerateDestructorCode(io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { printer->Print(variables_, - " $classname$_default_oneof_instance_->$name$_ = " - "$classname$::$default_variable$;\n"); + "if (has_$name$()) {\n" + " $oneof_prefix$$name$_.Destroy($default_variable$,\n" + " GetArenaNoVirtual());\n" + "}\n"); } else { printer->Print(variables_, - " $classname$_default_oneof_instance_->$name$_ = " - "$default_variable$;\n"); + "if (has_$name$()) {\n" + " $oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n" + "}\n"); } } void StringOneofFieldGenerator:: -GenerateDestructorCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has_$name$()) {\n" - " delete $oneof_prefix$$name$_;\n" - "}\n"); +GenerateMergeFromCodedStream(io::Printer* printer) const { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n" + " input, this->mutable_$name$()));\n"); + + if (HasUtf8Verification(descriptor_->file()) && + descriptor_->type() == FieldDescriptor::TYPE_STRING) { + printer->Print(variables_, + "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" + " this->$name$().data(), this->$name$().length(),\n" + " ::google::protobuf::internal::WireFormat::PARSE,\n" + " \"$full_name$\");\n"); + } } + // =================================================================== RepeatedStringFieldGenerator:: @@ -566,7 +766,7 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); + printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n"); } void RepeatedStringFieldGenerator:: @@ -586,7 +786,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { " this->$name$(this->$name$_size() - 1).data(),\n" " this->$name$(this->$name$_size() - 1).length(),\n" " ::google::protobuf::internal::WireFormat::PARSE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } } @@ -600,7 +800,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" " this->$name$(i).data(), this->$name$(i).length(),\n" " ::google::protobuf::internal::WireFormat::SERIALIZE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } printer->Print(variables_, " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n" @@ -618,7 +818,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { " ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n" " this->$name$(i).data(), this->$name$(i).length(),\n" " ::google::protobuf::internal::WireFormat::SERIALIZE,\n" - " \"$name$\");\n"); + " \"$full_name$\");\n"); } printer->Print(variables_, " target = ::google::protobuf::internal::WireFormatLite::\n" |