// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/compiler/cpp/cpp_string_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>



namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

namespace {

void SetStringVariables(const FieldDescriptor* descriptor,
                        std::map<std::string, std::string>* variables,
                        const Options& options) {
  SetCommonFieldVariables(descriptor, variables, options);
  (*variables)["default"] = DefaultValue(options, descriptor);
  (*variables)["default_length"] =
      StrCat(descriptor->default_value_string().length());
  std::string default_variable_string = MakeDefaultName(descriptor);
  (*variables)["default_variable_name"] = default_variable_string;
  (*variables)["default_variable"] =
      descriptor->default_value_string().empty()
          ? "&::" + (*variables)["proto_ns"] +
                "::internal::GetEmptyStringAlreadyInited()"
          : "&" + QualifiedClassName(descriptor->containing_type(), options) +
                "::" + default_variable_string + ".get()";
  (*variables)["pointer_type"] =
      descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
  (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n";
  // NOTE: Escaped here to unblock proto1->proto2 migration.
  // TODO(liujisi): Extend this to apply for other conflicting methods.
  (*variables)["release_name"] =
      SafeFunctionName(descriptor->containing_type(),
                       descriptor, "release_");
  (*variables)["full_name"] = descriptor->full_name();

  if (options.opensource_runtime) {
    (*variables)["string_piece"] = "::std::string";
  } else {
    (*variables)["string_piece"] = "::StringPiece";
  }

  (*variables)["lite"] =
      HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite";
}

}  // namespace

// ===================================================================

StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
                                           const Options& options)
    : FieldGenerator(descriptor, options),
      lite_(!HasDescriptorMethods(descriptor->file(), options)),
      inlined_(IsStringInlined(descriptor, options)) {
  SetStringVariables(descriptor, &variables_, options);
}

StringFieldGenerator::~StringFieldGenerator() {}

void StringFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (inlined_) {
    format("::$proto_ns$::internal::InlinedStringField $name$_;\n");
  } else {
    // 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.
    format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
  }
}

void StringFieldGenerator::
GenerateStaticMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!descriptor_->default_value_string().empty()) {
    // We make the default instance public, so it can be initialized by
    // non-friend code.
    format(
        "public:\n"
        "static ::$proto_ns$::internal::ExplicitlyConstructed<std::string>"
        " $default_variable_name$;\n"
        "private:\n");
  }
}

void StringFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // If we're using StringFieldGenerator for a field with a ctype, it's
  // because that ctype isn't actually implemented.  In particular, this is
  // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
  // We aren't releasing Cord because it has too many Google-specific
  // dependencies and we aren't releasing StringPiece because it's hardly
  // useful outside of Google and because it would get confusing to have
  // multiple instances of the StringPiece class in different libraries (PCRE
  // already includes it for their C++ bindings, which came from Google).
  //
  // In any case, we make all the accessors private while still actually
  // using a string to represent the field internally.  This way, we can
  // guarantee that if we do ever implement the ctype, it won't break any
  // existing users who might be -- for whatever reason -- already using .proto
  // files that applied the ctype.  The field can still be accessed via the
  // reflection interface since the reflection interface is independent of
  // the string's underlying representation.

  bool unknown_ctype = descriptor_->options().ctype() !=
                       EffectiveStringCType(descriptor_, options_);

  if (unknown_ctype) {
    format.Outdent();
    format(
        " private:\n"
        "  // Hidden due to unknown ctype option.\n");
    format.Indent();
  }

  format(
      "$deprecated_attr$const std::string& ${1$$name$$}$() const;\n"
      "$deprecated_attr$void ${1$set_$name$$}$(const std::string& value);\n"
      "$deprecated_attr$void ${1$set_$name$$}$(std::string&& value);\n"
      "$deprecated_attr$void ${1$set_$name$$}$(const char* value);\n",
      descriptor_);
  if (!options_.opensource_runtime) {
    format(
        "$deprecated_attr$void ${1$set_$name$$}$(::StringPiece value);\n",
        descriptor_);
  }
  format(
      "$deprecated_attr$void ${1$set_$name$$}$(const $pointer_type$* "
      "value, size_t size)"
      ";\n"
      "$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
      "$deprecated_attr$std::string* ${1$$release_name$$}$();\n"
      "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
      "$name$);\n",
      descriptor_);
  if (options_.opensource_runtime) {
    if (SupportsArenas(descriptor_)) {
      format(
          "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors "
          "for\"\n"
          "\"    string fields are deprecated and will be removed in a\"\n"
          "\"    future release.\")\n"
          "std::string* ${1$unsafe_arena_release_$name$$}$();\n"
          "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors "
          "for\"\n"
          "\"    string fields are deprecated and will be removed in a\"\n"
          "\"    future release.\")\n"
          "void ${1$unsafe_arena_set_allocated_$name$$}$(\n"
          "    std::string* $name$);\n",
          descriptor_);
    }
  }

  if (unknown_ctype) {
    format.Outdent();
    format(" public:\n");
    format.Indent();
  }
}

void StringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_)) {
    format(
        "inline const std::string& $classname$::$name$() const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  return $name$_.Get();\n"
        "}\n"
        "inline void $classname$::set_$name$(const std::string& value) {\n"
        "  $set_hasbit$\n"
        "  $name$_.Set$lite$($default_variable$, value, GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(std::string&& value) {\n"
        "  $set_hasbit$\n"
        "  $name$_.Set$lite$(\n"
        "    $default_variable$, ::std::move(value), GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(const char* value) {\n"
        "  $null_check$"
        "  $set_hasbit$\n"
        "  $name$_.Set$lite$($default_variable$, $string_piece$(value),\n"
        "              GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
        "}\n");
    if (!options_.opensource_runtime) {
      format(
          "inline void $classname$::set_$name$(::StringPiece value) {\n"
          "  $set_hasbit$\n"
          "  $name$_.Set$lite$($default_variable$, value, "
          "GetArenaNoVirtual());\n"
          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
          "}\n");
    }
    format(
        "inline "
        "void $classname$::set_$name$(const $pointer_type$* value,\n"
        "    size_t size) {\n"
        "  $set_hasbit$\n"
        "  $name$_.Set$lite$($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"
        "  // @@protoc_insertion_point(field_release:$full_name$)\n");

    if (HasFieldPresence(descriptor_->file())) {
      format(
          "  if (!has_$name$()) {\n"
          "    return nullptr;\n"
          "  }\n"
          "  $clear_hasbit$\n"
          "  return $name$_.ReleaseNonDefault("
          "$default_variable$, GetArenaNoVirtual());\n");
    } else {
      format(
          "  $clear_hasbit$\n"
          "  return $name$_.Release($default_variable$, "
          "GetArenaNoVirtual());\n");
    }

    format(
        "}\n"
        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
        "  if ($name$ != nullptr) {\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");
    if (options_.opensource_runtime) {
      format(
          "inline std::string* $classname$::unsafe_arena_release_$name$() {\n"
          "  // "
          "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
          "  $DCHK$(GetArenaNoVirtual() != nullptr);\n"
          "  $clear_hasbit$\n"
          "  return $name$_.UnsafeArenaRelease($default_variable$,\n"
          "      GetArenaNoVirtual());\n"
          "}\n"
          "inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
          "    std::string* $name$) {\n"
          "  $DCHK$(GetArenaNoVirtual() != nullptr);\n"
          "  if ($name$ != nullptr) {\n"
          "    $set_hasbit$\n"
          "  } else {\n"
          "    $clear_hasbit$\n"
          "  }\n"
          "  $name$_.UnsafeArenaSetAllocated($default_variable$,\n"
          "      $name$, GetArenaNoVirtual());\n"
          "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
          "$full_name$)\n"
          "}\n");
    }
  } else {
    // No-arena case.
    format(
        "inline const std::string& $classname$::$name$() const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  return $name$_.GetNoArena();\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$(std::string&& value) {\n"
        "  $set_hasbit$\n"
        "  $name$_.SetNoArena(\n"
        "    $default_variable$, ::std::move(value));\n"
        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(const char* value) {\n"
        "  $null_check$"
        "  $set_hasbit$\n"
        "  $name$_.SetNoArena($default_variable$, $string_piece$(value));\n"
        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
        "}\n");
    if (!options_.opensource_runtime) {
      format(
          "inline void $classname$::set_$name$(::StringPiece value) {\n"
          "  $set_hasbit$\n"
          "  $name$_.SetNoArena($default_variable$, value);\n"
          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
          "}\n");
    }
    format(
        "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"
        "  // @@protoc_insertion_point(field_release:$full_name$)\n");

    if (HasFieldPresence(descriptor_->file())) {
      format(
          "  if (!has_$name$()) {\n"
          "    return nullptr;\n"
          "  }\n"
          "  $clear_hasbit$\n"
          "  return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n");
    } else {
      format(
          "  $clear_hasbit$\n"
          "  return $name$_.ReleaseNoArena($default_variable$);\n");
    }

    format(
        "}\n"
        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
        "  if ($name$ != nullptr) {\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");
  }
}

void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!descriptor_->default_value_string().empty()) {
    // Initialized in GenerateDefaultInstanceAllocator.
    format(
        "::$proto_ns$::internal::ExplicitlyConstructed<std::string> "
        "$classname$::$default_variable_name$;\n");
  }
}

void StringFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // 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()) {
      format(
          "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
    } else {
      format(
          "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
    }
  } else {
    if (descriptor_->default_value_string().empty()) {
      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
    } else {
      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
    }
  }
}

void StringFieldGenerator::
GenerateMessageClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // Two-dimension specialization here: supporting arenas, field presence, 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 we have field presence, then the Clear() method of the protocol buffer
  // will have checked that this field is set.  If so, we can avoid redundant
  // checks against default_variable.
  const bool must_be_present =
      HasFieldPresence(descriptor_->file());

  if (inlined_ && must_be_present) {
    // Calling mutable_$name$() gives us a string reference and sets the has bit
    // for $name$ (in proto2).  We may get here when the string field is inlined
    // but the string's contents have not been changed by the user, so we cannot
    // make an assertion about the contents of the string and could never make
    // an assertion about the string instance.
    //
    // For non-inlined strings, we distinguish from non-default by comparing
    // instances, rather than contents.
    format("$DCHK$(!$name$_.IsDefault($default_variable$));\n");
  }

  if (SupportsArenas(descriptor_)) {
    if (descriptor_->default_value_string().empty()) {
      if (must_be_present) {
        format("$name$_.ClearNonDefaultToEmpty();\n");
      } else {
        format(
            "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n");
      }
    } else {
      // Clear to a non-empty default is more involved, as we try to use the
      // Arena if one is present and may need to reallocate the string.
      format(
          "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n");
    }
  } else if (must_be_present) {
    // When Arenas are disabled and field presence has been checked, we can
    // safely treat the ArenaStringPtr as a string*.
    if (descriptor_->default_value_string().empty()) {
      format("$name$_.ClearNonDefaultToEmptyNoArena();\n");
    } else {
      format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n");
    }
  } else {
    if (descriptor_->default_value_string().empty()) {
      format("$name$_.ClearToEmptyNoArena($default_variable$);\n");
    } else {
      format("$name$_.ClearToDefaultNoArena($default_variable$);\n");
    }
  }
}

void StringFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
    // TODO(gpike): improve this
    format("set_$name$(from.$name$());\n");
  } else {
    format(
        "$set_hasbit$\n"
        "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
  }
}

void StringFieldGenerator::
GenerateSwappingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (inlined_) {
    format("$name$_.Swap(&other->$name$_);\n");
  } else {
    format(
        "$name$_.Swap(&other->$name$_, $default_variable$,\n"
        "  GetArenaNoVirtual());\n");
  }
}

void StringFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // TODO(ckennelly): Construct non-empty strings as part of the initializer
  // list.
  if (inlined_ && descriptor_->default_value_string().empty()) {
    // Automatic initialization will construct the string.
    return;
  }

  format("$name$_.UnsafeSetDefault($default_variable$);\n");
}

void StringFieldGenerator::
GenerateCopyConstructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  GenerateConstructorCode(printer);

  if (HasFieldPresence(descriptor_->file())) {
    format("if (from.has_$name$()) {\n");
  } else {
    format("if (from.$name$().size() > 0) {\n");
  }

  format.Indent();

  if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) {
    // TODO(gpike): improve this
    format(
        "$name$_.Set$lite$($default_variable$, from.$name$(),\n"
        "  GetArenaNoVirtual());\n");
  } else {
    format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n");
  }

  format.Outdent();
  format("}\n");
}

void StringFieldGenerator::
GenerateDestructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (inlined_) {
    // The destructor is automatically invoked.
    return;
  }

  format("$name$_.DestroyNoArena($default_variable$);\n");
}

bool StringFieldGenerator::GenerateArenaDestructorCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!inlined_) {
    return false;
  }

  format("_this->$name$_.DestroyNoArena($default_variable$);\n");
  return true;
}

void StringFieldGenerator::
GenerateDefaultInstanceAllocator(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!descriptor_->default_value_string().empty()) {
    format(
        "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n"
        "*$ns$::$classname$::$default_variable_name$.get_mutable() = "
        "std::string($default$, $default_length$);\n"
        "::$proto_ns$::internal::OnShutdownDestroyString(\n"
        "    $ns$::$classname$::$default_variable_name$.get_mutable());\n");
  }
}

void StringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // The google3 version of proto2 has ArenaStrings and parses into them
  // directly, but for the open-source release, we always parse into std::string
  // instances. Note that for lite, we do similarly to the open source release
  // and use std::string, not ArenaString.
  if (!options_.opensource_runtime && !inlined_ &&
      SupportsArenas(descriptor_) && !lite_) {
    // If arena != NULL, the current string is either an ArenaString (no
    // destructor necessary) or a materialized std::string (and is on the
    // Arena's destructor list).  No call to ArenaStringPtr::Destroy is needed.
    format(
        "if (arena != nullptr) {\n"
        "  ::$proto_ns$::internal::TaggedPtr<std::string> str =\n"
        "    ::$proto_ns$::internal::ReadArenaString(input, arena);\n"
        "  DO_(!str.IsNull());\n"
        "  $set_hasbit_io$\n"
        "  $name$_.UnsafeSetTaggedPointer(str);\n"
        "} else {\n"
        "  DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
        "        input, this->mutable_$name$()));\n"
        "}\n");
  } else {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
        "      input, this->mutable_$name$()));\n");
  }

  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, true,
        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
        format);
  }
}

bool StringFieldGenerator::
MergeFromCodedStreamNeedsArena() const {
  return !lite_ && !inlined_ && !options_.opensource_runtime;
}

void StringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, false,
        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
        format);
  }
  format(
      "::$proto_ns$::internal::WireFormatLite::Write$declared_type$"
      "MaybeAliased(\n"
      "  $number$, this->$name$(), output);\n");
}

void StringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, false,
        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
        format);
  }
  format(
      "target =\n"
      "  ::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray(\n"
      "    $number$, this->$name$(), target);\n");
}

void StringFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "total_size += $tag_size$ +\n"
      "  ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
      "    this->$name$());\n");
}

uint32 StringFieldGenerator::CalculateFieldTag() const {
  return inlined_ ? 1 : 0;
}

// ===================================================================

StringOneofFieldGenerator::StringOneofFieldGenerator(
    const FieldDescriptor* descriptor, const Options& options)
    : StringFieldGenerator(descriptor, options) {
  inlined_ = false;

  SetCommonOneofFieldVariables(descriptor, &variables_);
}

StringOneofFieldGenerator::~StringOneofFieldGenerator() {}

void StringOneofFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_)) {
    format(
        "inline const std::string& $classname$::$name$() const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  if (has_$name$()) {\n"
        "    return $field_member$.Get();\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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.Set$lite$($default_variable$, value,\n"
        "      GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(std::string&& value) {\n"
        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
        "  if (!has_$name$()) {\n"
        "    clear_$oneof_name$();\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.Set$lite$(\n"
        "    $default_variable$, ::std::move(value), GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(const char* value) {\n"
        "  $null_check$"
        "  if (!has_$name$()) {\n"
        "    clear_$oneof_name$();\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.Set$lite$($default_variable$,\n"
        "      $string_piece$(value), GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
        "}\n");
    if (!options_.opensource_runtime) {
      format(
          "inline void $classname$::set_$name$(::StringPiece value) {\n"
          "  if (!has_$name$()) {\n"
          "    clear_$oneof_name$();\n"
          "    set_has_$name$();\n"
          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
          "  }\n"
          "  $field_member$.Set$lite$($default_variable$, value,\n"
          "      GetArenaNoVirtual());\n"
          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
          "}\n");
    }
    format(
        "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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.Set$lite$(\n"
        "      $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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  return $field_member$.Mutable($default_variable$,\n"
        "      GetArenaNoVirtual());\n"
        "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
        "}\n"
        "inline std::string* $classname$::$release_name$() {\n"
        "  // @@protoc_insertion_point(field_release:$full_name$)\n"
        "  if (has_$name$()) {\n"
        "    clear_has_$oneof_name$();\n"
        "    return $field_member$.Release($default_variable$,\n"
        "        GetArenaNoVirtual());\n"
        "  } else {\n"
        "    return nullptr;\n"
        "  }\n"
        "}\n"
        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
        "  if (has_$oneof_name$()) {\n"
        "    clear_$oneof_name$();\n"
        "  }\n"
        "  if ($name$ != nullptr) {\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($name$);\n"
        "  }\n"
        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
        "}\n");
    if (options_.opensource_runtime) {
      format(
          "inline std::string* $classname$::unsafe_arena_release_$name$() {\n"
          "  // "
          "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
          "  $DCHK$(GetArenaNoVirtual() != nullptr);\n"
          "  if (has_$name$()) {\n"
          "    clear_has_$oneof_name$();\n"
          "    return $field_member$.UnsafeArenaRelease(\n"
          "        $default_variable$, GetArenaNoVirtual());\n"
          "  } else {\n"
          "    return nullptr;\n"
          "  }\n"
          "}\n"
          "inline void $classname$::unsafe_arena_set_allocated_$name$("
          "std::string* $name$) {\n"
          "  $DCHK$(GetArenaNoVirtual() != nullptr);\n"
          "  if (!has_$name$()) {\n"
          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
          "  }\n"
          "  clear_$oneof_name$();\n"
          "  if ($name$) {\n"
          "    set_has_$name$();\n"
          "    $field_member$.UnsafeArenaSetAllocated($default_variable$, "
          "$name$, GetArenaNoVirtual());\n"
          "  }\n"
          "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
          "$full_name$)\n"
          "}\n");
    }
  } else {
    // No-arena case.
    format(
        "inline const std::string& $classname$::$name$() const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  if (has_$name$()) {\n"
        "    return $field_member$.GetNoArena();\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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.SetNoArena($default_variable$, value);\n"
        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(std::string&& value) {\n"
        "  // @@protoc_insertion_point(field_set:$full_name$)\n"
        "  if (!has_$name$()) {\n"
        "    clear_$oneof_name$();\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.SetNoArena($default_variable$, ::std::move(value));\n"
        "  // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
        "}\n"
        "inline void $classname$::set_$name$(const char* value) {\n"
        "  $null_check$"
        "  if (!has_$name$()) {\n"
        "    clear_$oneof_name$();\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.SetNoArena($default_variable$,\n"
        "      $string_piece$(value));\n"
        "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
        "}\n");
    if (!options_.opensource_runtime) {
      format(
          "inline void $classname$::set_$name$(::StringPiece value) {\n"
          "  if (!has_$name$()) {\n"
          "    clear_$oneof_name$();\n"
          "    set_has_$name$();\n"
          "    $field_member$.UnsafeSetDefault($default_variable$);\n"
          "  }\n"
          "  $field_member$.SetNoArena($default_variable$, value);\n"
          "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
          "}\n");
    }
    format(
        "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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  $field_member$.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"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "  }\n"
        "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
        "  return $field_member$.MutableNoArena($default_variable$);\n"
        "}\n"
        "inline std::string* $classname$::$release_name$() {\n"
        "  // @@protoc_insertion_point(field_release:$full_name$)\n"
        "  if (has_$name$()) {\n"
        "    clear_has_$oneof_name$();\n"
        "    return $field_member$.ReleaseNoArena($default_variable$);\n"
        "  } else {\n"
        "    return nullptr;\n"
        "  }\n"
        "}\n"
        "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
        "  if (has_$oneof_name$()) {\n"
        "    clear_$oneof_name$();\n"
        "  }\n"
        "  if ($name$ != nullptr) {\n"
        "    set_has_$name$();\n"
        "    $field_member$.UnsafeSetDefault($name$);\n"
        "  }\n"
        "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
        "}\n");
  }
}

void StringOneofFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_)) {
    format(
        "$field_member$.Destroy($default_variable$,\n"
        "    GetArenaNoVirtual());\n");
  } else {
    format("$field_member$.DestroyNoArena($default_variable$);\n");
  }
}

void StringOneofFieldGenerator::
GenerateMessageClearingCode(io::Printer* printer) const {
  return GenerateClearingCode(printer);
}

void StringOneofFieldGenerator::
GenerateSwappingCode(io::Printer* printer) const {
  // Don't print any swapping code. Swapping the union will swap this field.
}

void StringOneofFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n"
      "    $default_variable$);\n");
}

void StringOneofFieldGenerator::
GenerateDestructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "if (has_$name$()) {\n"
      "  $field_member$.DestroyNoArena($default_variable$);\n"
      "}\n");
}

void StringOneofFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // See above: ArenaString is not included in the open-source release.
  if (!options_.opensource_runtime && SupportsArenas(descriptor_) && !lite_) {
    // If has_$name$(), then the current string is either an ArenaString (no
    // destructor necessary) or a materialized std::string (and is on the
    // Arena's destructor list).  No call to ArenaStringPtr::Destroy is needed.
    format(
        "if (arena != nullptr) {\n"
        "  clear_$oneof_name$();\n"
        "  if (!has_$name$()) {\n"
        "    $field_member$.UnsafeSetDefault($default_variable$);\n"
        "    set_has_$name$();\n"
        "  }\n"
        "  ::$proto_ns$::internal::TaggedPtr<std::string> new_value =\n"
        "    ::$proto_ns$::internal::ReadArenaString(input, arena);\n"
        "  DO_(!new_value.IsNull());\n"
        "  $field_member$.UnsafeSetTaggedPointer(new_value);\n"
        "} else {\n"
        "  DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
        "        input, this->mutable_$name$()));\n"
        "}\n");
  } else {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
        "      input, this->mutable_$name$()));\n");
  }

  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, true,
        "this->$name$().data(), static_cast<int>(this->$name$().length()),\n",
        format);
  }
}


// ===================================================================

RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
    const FieldDescriptor* descriptor, const Options& options)
    : FieldGenerator(descriptor, options) {
  SetStringVariables(descriptor, &variables_, options);
}

RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}

void RepeatedStringFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("::$proto_ns$::RepeatedPtrField<std::string> $name$_;\n");
}

void RepeatedStringFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
  Formatter format(printer, variables_);
  // See comment above about unknown ctypes.
  bool unknown_ctype = descriptor_->options().ctype() !=
                       EffectiveStringCType(descriptor_, options_);

  if (unknown_ctype) {
    format.Outdent();
    format(
        " private:\n"
        "  // Hidden due to unknown ctype option.\n");
    format.Indent();
  }

  format(
      "$deprecated_attr$const std::string& ${1$$name$$}$(int index) const;\n"
      "$deprecated_attr$std::string* ${1$mutable_$name$$}$(int index);\n"
      "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
      "std::string& value);\n"
      "$deprecated_attr$void ${1$set_$name$$}$(int index, std::string&& "
      "value);\n"
      "$deprecated_attr$void ${1$set_$name$$}$(int index, const "
      "char* value);\n",
      descriptor_);
  if (!options_.opensource_runtime) {
    format(
        "$deprecated_attr$void ${1$set_$name$$}$(int index, "
        "StringPiece value);\n",
        descriptor_);
  }
  format(
      "$deprecated_attr$void ${1$set_$name$$}$("
      "int index, const $pointer_type$* value, size_t size);\n"
      "$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
      "$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
      "$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
      "$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
      descriptor_);
  if (!options_.opensource_runtime) {
    format(
        "$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n",
        descriptor_);
  }
  format(
      "$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
      "value, size_t size)"
      ";\n"
      "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
      "${1$$name$$}$() "
      "const;\n"
      "$deprecated_attr$::$proto_ns$::RepeatedPtrField<std::string>* "
      "${1$mutable_$name$$}$()"
      ";\n",
      descriptor_);

  if (unknown_ctype) {
    format.Outdent();
    format(" public:\n");
    format.Indent();
  }
}

void RepeatedStringFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (options_.safe_boundary_check) {
    format(
        "inline const std::string& $classname$::$name$(int index) const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  return $name$_.InternalCheckedGet(\n"
        "      index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
        "}\n");
  } else {
    format(
        "inline const std::string& $classname$::$name$(int index) const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  return $name$_.Get(index);\n"
        "}\n");
  }
  format(
      "inline std::string* $classname$::mutable_$name$(int index) {\n"
      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
      "  return $name$_.Mutable(index);\n"
      "}\n"
      "inline void $classname$::set_$name$(int index, const std::string& "
      "value) "
      "{\n"
      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
      "  $name$_.Mutable(index)->assign(value);\n"
      "}\n"
      "inline void $classname$::set_$name$(int index, std::string&& value) {\n"
      "  // @@protoc_insertion_point(field_set:$full_name$)\n"
      "  $name$_.Mutable(index)->assign(std::move(value));\n"
      "}\n"
      "inline void $classname$::set_$name$(int index, const char* value) {\n"
      "  $null_check$"
      "  $name$_.Mutable(index)->assign(value);\n"
      "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
      "}\n");
  if (!options_.opensource_runtime) {
    format(
        "inline void "
        "$classname$::set_$name$(int index, StringPiece value) {\n"
        "  $name$_.Mutable(index)->assign(value.data(), value.size());\n"
        "  // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
        "}\n");
  }
  format(
      "inline void "
      "$classname$::set_$name$"
      "(int index, const $pointer_type$* value, size_t size) {\n"
      "  $name$_.Mutable(index)->assign(\n"
      "    reinterpret_cast<const char*>(value), size);\n"
      "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
      "}\n"
      "inline std::string* $classname$::add_$name$() {\n"
      "  // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
      "  return $name$_.Add();\n"
      "}\n"
      "inline void $classname$::add_$name$(const std::string& value) {\n"
      "  $name$_.Add()->assign(value);\n"
      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
      "}\n"
      "inline void $classname$::add_$name$(std::string&& value) {\n"
      "  $name$_.Add(std::move(value));\n"
      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
      "}\n"
      "inline void $classname$::add_$name$(const char* value) {\n"
      "  $null_check$"
      "  $name$_.Add()->assign(value);\n"
      "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
      "}\n");
  if (!options_.opensource_runtime) {
    format(
        "inline void $classname$::add_$name$(StringPiece value) {\n"
        "  $name$_.Add()->assign(value.data(), value.size());\n"
        "  // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
        "}\n");
  }
  format(
      "inline void "
      "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
      "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
      "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
      "}\n"
      "inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
      "$classname$::$name$() const {\n"
      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
      "  return $name$_;\n"
      "}\n"
      "inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
      "$classname$::mutable_$name$() {\n"
      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
      "  return &$name$_;\n"
      "}\n");
}

void RepeatedStringFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.Clear();\n");
}

void RepeatedStringFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.MergeFrom(from.$name$_);\n");
}

void RepeatedStringFieldGenerator::
GenerateSwappingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.InternalSwap(CastToBase(&other->$name$_));\n");
}

void RepeatedStringFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
  // Not needed for repeated fields.
}

void RepeatedStringFieldGenerator::
GenerateCopyConstructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_.CopyFrom(from.$name$_);");
}

void RepeatedStringFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "DO_(::$proto_ns$::internal::WireFormatLite::Read$declared_type$(\n"
      "      input, this->add_$name$()));\n");
  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, true,
        "this->$name$(this->$name$_size() - 1).data(),\n"
        "static_cast<int>(this->$name$(this->$name$_size() - 1).length()),\n",
        format);
  }
}

void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
  format.Indent();
  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, false,
        "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
        format);
  }
  format.Outdent();
  format(
      "  ::$proto_ns$::internal::WireFormatLite::Write$declared_type$(\n"
      "    $number$, this->$name$(i), output);\n"
      "}\n");
}

void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("for (int i = 0, n = this->$name$_size(); i < n; i++) {\n");
  format.Indent();
  if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
    GenerateUtf8CheckCodeForString(
        descriptor_, options_, false,
        "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n",
        format);
  }
  format.Outdent();
  format(
      "  target = ::$proto_ns$::internal::WireFormatLite::\n"
      "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
      "}\n");
}

void RepeatedStringFieldGenerator::
GenerateByteSize(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "total_size += $tag_size$ *\n"
      "    ::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
      "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"
      "  total_size += "
      "::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
      "    this->$name$(i));\n"
      "}\n");
}

}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
