// 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_message_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>

#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
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 std::string& type, const std::string& expression,
                  bool implicit_weak_field) {
  if (implicit_weak_field) {
    return "static_cast< " + type + " >(" + expression + ")";
  } else {
    return expression;
  }
}

string ReinterpretCast(const std::string& type, const std::string& expression,
                       bool implicit_weak_field) {
  if (implicit_weak_field) {
    return "reinterpret_cast< " + type + " >(" + expression + ")";
  } else {
    return expression;
  }
}

void SetMessageVariables(const FieldDescriptor* descriptor,
                         const Options& options, bool implicit_weak,
                         std::map<std::string, std::string>* variables) {
  SetCommonFieldVariables(descriptor, variables, options);
  (*variables)["type"] = FieldMessageTypeName(descriptor, options);
  (*variables)["casted_member"] = ReinterpretCast(
      (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
  (*variables)["type_default_instance"] =
      DefaultInstanceName(descriptor->message_type(), options);
  (*variables)["type_reference_function"] =
      implicit_weak
          ? ("  " + ReferenceFunctionName(descriptor->message_type(), options) +
             "();\n")
          : "";
  (*variables)["stream_writer"] =
      (*variables)["declared_type"] +
      (HasFastArraySerialization(descriptor->message_type()->file(), options)
           ? "MaybeToArray"
           : "");
  // 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();
}

}  // namespace

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

MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
                                             const Options& options,
                                             MessageSCCAnalyzer* scc_analyzer)
    : FieldGenerator(descriptor, options),
      implicit_weak_field_(
          IsImplicitWeakField(descriptor, options, scc_analyzer)) {
  SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
}

MessageFieldGenerator::~MessageFieldGenerator() {}

void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format("::$proto_ns$::MessageLite* $name$_;\n");
  } else {
    format("$type$* $name$_;\n");
  }
}

void MessageFieldGenerator::GenerateAccessorDeclarations(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
      "$deprecated_attr$$type$* ${1$$release_name$$}$();\n"
      "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
      "$deprecated_attr$void ${1$set_allocated_$name$$}$"
      "($type$* $name$);\n",
      descriptor_);
  if (SupportsArenas(descriptor_)) {
    format(
        "$deprecated_attr$void "
        "${1$unsafe_arena_set_allocated_$name$$}$(\n"
        "    $type$* $name$);\n"
        "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
        descriptor_);
  }
}

void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_)) {
    format(
        "void $classname$::unsafe_arena_set_allocated_$name$(\n"
        "    $type$* $name$) {\n"
        // If we're not on an arena, free whatever we were holding before.
        // (If we are on arena, we can just forget the earlier pointer.)
        "  if (GetArenaNoVirtual() == nullptr) {\n"
        "    delete $name$_;\n"
        "  }\n"
        "  $name$_ = $name$;\n"
        "  if ($name$) {\n"
        "    $set_hasbit$\n"
        "  } else {\n"
        "    $clear_hasbit$\n"
        "  }\n"
        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
        ":$full_name$)\n"
        "}\n");
  }
}

void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "inline const $type$& $classname$::$name$() const {\n"
      "  const $type$* p = $casted_member$;\n"
      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
      "  return p != nullptr ? *p : *reinterpret_cast<const $type$*>(\n"
      "      &$type_default_instance$);\n"
      "}\n");

  format(
      "inline $type$* $classname$::$release_name$() {\n"
      "  // @@protoc_insertion_point(field_release:$full_name$)\n"
      "$type_reference_function$"
      "  $clear_hasbit$\n"
      "  $type$* temp = $casted_member$;\n");
  if (SupportsArenas(descriptor_)) {
    format(
        "  if (GetArenaNoVirtual() != nullptr) {\n"
        "    temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
        "  }\n");
  }
  format(
      "  $name$_ = nullptr;\n"
      "  return temp;\n"
      "}\n");

  if (SupportsArenas(descriptor_)) {
    format(
        "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
        "  // "
        "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
        "$type_reference_function$"
        "  $clear_hasbit$\n"
        "  $type$* temp = $casted_member$;\n"
        "  $name$_ = nullptr;\n"
        "  return temp;\n"
        "}\n");
  }

  format(
      "inline $type$* $classname$::mutable_$name$() {\n"
      "  $set_hasbit$\n"
      "  if ($name$_ == nullptr) {\n"
      "    auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n");
  if (implicit_weak_field_) {
    format("    $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
  } else {
    format("    $name$_ = p;\n");
  }
  format(
      "  }\n"
      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
      "  return $casted_member$;\n"
      "}\n");

  // We handle the most common case inline, and delegate less common cases to
  // the slow fallback function.
  format(
      "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
      "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n");
  format("  if (message_arena == nullptr) {\n");
  if (IsCrossFileMessage(descriptor_)) {
    format(
        "    delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
  } else {
    format("    delete $name$_;\n");
  }
  format(
      "  }\n"
      "  if ($name$) {\n");
  if (SupportsArenas(descriptor_->message_type()) &&
      IsCrossFileMessage(descriptor_)) {
    // We have to read the arena through the virtual method, because the type
    // isn't defined in this file.
    format(
        "    ::$proto_ns$::Arena* submessage_arena =\n"
        "      "
        "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
  } else if (!SupportsArenas(descriptor_->message_type())) {
    format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
  } else {
    format(
        "    ::$proto_ns$::Arena* submessage_arena =\n"
        "      ::$proto_ns$::Arena::GetArena($name$);\n");
  }
  format(
      "    if (message_arena != submessage_arena) {\n"
      "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
      "          message_arena, $name$, submessage_arena);\n"
      "    }\n"
      "    $set_hasbit$\n"
      "  } else {\n"
      "    $clear_hasbit$\n"
      "  }\n");
  if (implicit_weak_field_) {
    format("  $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
  } else {
    format("  $name$_ = $name$;\n");
  }
  format(
      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
      "}\n");
}

void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format(
        "static const ::$proto_ns$::MessageLite& $name$("
        "const $classname$* msg);\n"
        "static ::$proto_ns$::MessageLite* mutable_$name$("
        "$classname$* msg);\n");
  } else {
    format("static const $type$& $name$(const $classname$* msg);\n");
  }
}

void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
    io::Printer* printer) const {
  // In theory, these accessors could be inline in HasBitSetters. However, in
  // practice, the linker is then not able to throw them out making implicit
  // weak dependencies not work at all.
  Formatter format(printer, variables_);
  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.
    format(
        "const ::$proto_ns$::MessageLite& $classname$::HasBitSetters::$name$(\n"
        "    const $classname$* msg) {\n"
        "  if (msg->$name$_ != nullptr) {\n"
        "    return *msg->$name$_;\n"
        "  } else if (&$type_default_instance$ != nullptr) {\n"
        "    return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
        "        &$type_default_instance$);\n"
        "  } else {\n"
        "    return "
        "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
        "  }\n"
        "}\n");
    if (SupportsArenas(descriptor_)) {
      format(
          "::$proto_ns$::MessageLite*\n"
          "$classname$::HasBitSetters::mutable_$name$($classname$* msg) {\n");
      if (HasFieldPresence(descriptor_->file())) {
        format("  msg->$set_hasbit$\n");
      }
      format(
          "  if (msg->$name$_ == nullptr) {\n"
          "    if (&$type_default_instance$ == nullptr) {\n"
          "      msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
          "          ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
          "              msg->GetArenaNoVirtual());\n"
          "    } else {\n"
          "      msg->$name$_ = reinterpret_cast<const "
          "::$proto_ns$::MessageLite*>(\n"
          "          &$type_default_instance$)->New("
          "msg->GetArenaNoVirtual());\n"
          "    }\n"
          "  }\n"
          "  return msg->$name$_;\n"
          "}\n");
    } else {
      format(
          "::$proto_ns$::MessageLite*\n"
          "$classname$::HasBitSetters::mutable_$name$($classname$* msg) {\n");
      if (HasFieldPresence(descriptor_->file())) {
        format("  msg->$set_hasbit$\n");
      }
      format(
          "  if (msg->$name$_ == nullptr) {\n"
          "    if (&$type_default_instance$ == nullptr) {\n"
          "      msg->$name$_ = "
          "new ::$proto_ns$::internal::ImplicitWeakMessage;\n"
          "    } else {\n"
          "      msg->$name$_ = "
          "reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
          "          &$type_default_instance$)->New();\n"
          "    }\n"
          "  }\n"
          "  return msg->$name$_;\n"
          "}\n");
    }
  } else {
    // This inline accessor directly returns member field and is used in
    // Serialize such that AFDO profile correctly captures access information to
    // message fields under serialize.
    format(
        "const $type$&\n"
        "$classname$::HasBitSetters::$name$(const $classname$* msg) {\n"
        "  return *msg->$field_member$;\n"
        "}\n");
  }
}

void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!HasFieldPresence(descriptor_->file())) {
    // If we don't have has-bits, message presence is indicated only by ptr !=
    // NULL. Thus on clear, we need to delete the object.
    format(
        "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n"
        "  delete $name$_;\n"
        "}\n"
        "$name$_ = nullptr;\n");
  } else {
    format("if ($name$_ != nullptr) $name$_->Clear();\n");
  }
}

void MessageFieldGenerator::GenerateMessageClearingCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (!HasFieldPresence(descriptor_->file())) {
    // If we don't have has-bits, message presence is indicated only by ptr !=
    // NULL. Thus on clear, we need to delete the object.
    format(
        "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n"
        "  delete $name$_;\n"
        "}\n"
        "$name$_ = nullptr;\n");
  } else {
    format(
        "$DCHK$($name$_ != nullptr);\n"
        "$name$_->Clear();\n");
  }
}

void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format(
        "HasBitSetters::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
        "    HasBitSetters::$name$(&from));\n");
  } else {
    format("mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
  }
}

void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("swap($name$_, other->$name$_);\n");
}

void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (options_.opensource_runtime) {
    // TODO(gerbens) Remove this when we don't need to destruct default
    // instances.  In google3 a default instance will never get deleted so we
    // don't need to worry about that but in opensource protobuf default
    // instances are deleted in shutdown process and we need to take special
    // care when handling them.
    format("if (this != internal_default_instance()) ");
  }
  format("delete $name$_;\n");
}

void MessageFieldGenerator::GenerateConstructorCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format("$name$_ = nullptr;\n");
}

void MessageFieldGenerator::GenerateCopyConstructorCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "if (from.has_$name$()) {\n"
      "  $name$_ = new $type$(*from.$name$_);\n"
      "} else {\n"
      "  $name$_ = nullptr;\n"
      "}\n");
}

void MessageFieldGenerator::GenerateMergeFromCodedStream(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
        "     input, HasBitSetters::mutable_$name$(this)));\n");
  } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessage(\n"
        "     input, mutable_$name$()));\n");
  } else {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::ReadGroup(\n"
        "      $number$, input, mutable_$name$()));\n");
  }
}

void MessageFieldGenerator::GenerateSerializeWithCachedSizes(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
      "  $number$, HasBitSetters::$name$(this), output);\n");
}

void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "target = ::$proto_ns$::internal::WireFormatLite::\n"
      "  InternalWrite$declared_type$ToArray(\n"
      "    $number$, HasBitSetters::$name$(this), target);\n");
}

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

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

MessageOneofFieldGenerator::MessageOneofFieldGenerator(
    const FieldDescriptor* descriptor, const Options& options,
    MessageSCCAnalyzer* scc_analyzer)
    : MessageFieldGenerator(descriptor, options, scc_analyzer) {
  SetCommonOneofFieldVariables(descriptor, &variables_);
}

MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}

void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "void $classname$::set_allocated_$name$($type$* $name$) {\n"
      "  ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n"
      "  clear_$oneof_name$();\n"
      "  if ($name$) {\n");
  if (SupportsArenas(descriptor_->message_type()) &&
      descriptor_->file() != descriptor_->message_type()->file()) {
    // We have to read the arena through the virtual method, because the type
    // isn't defined in this file.
    format(
        "    ::$proto_ns$::Arena* submessage_arena =\n"
        "      "
        "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
  } else if (!SupportsArenas(descriptor_->message_type())) {
    format("    ::$proto_ns$::Arena* submessage_arena = nullptr;\n");
  } else {
    format(
        "    ::$proto_ns$::Arena* submessage_arena =\n"
        "      ::$proto_ns$::Arena::GetArena($name$);\n");
  }
  format(
      "    if (message_arena != submessage_arena) {\n"
      "      $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
      "          message_arena, $name$, submessage_arena);\n"
      "    }\n"
      "    set_has_$name$();\n"
      "    $field_member$ = $name$;\n"
      "  }\n"
      "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
      "}\n");
}

void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "inline $type$* $classname$::$release_name$() {\n"
      "  // @@protoc_insertion_point(field_release:$full_name$)\n"
      "  if (has_$name$()) {\n"
      "    clear_has_$oneof_name$();\n"
      "      $type$* temp = $field_member$;\n");
  if (SupportsArenas(descriptor_)) {
    format(
        "    if (GetArenaNoVirtual() != nullptr) {\n"
        "      temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
        "    }\n");
  }
  format(
      "    $field_member$ = nullptr;\n"
      "    return temp;\n"
      "  } else {\n"
      "    return nullptr;\n"
      "  }\n"
      "}\n");

  format(
      "inline const $type$& $classname$::$name$() const {\n"
      "  // @@protoc_insertion_point(field_get:$full_name$)\n"
      "  return has_$name$()\n"
      "      ? *$field_member$\n"
      "      : *reinterpret_cast< $type$*>(&$type_default_instance$);\n"
      "}\n");

  if (SupportsArenas(descriptor_)) {
    format(
        "inline $type$* $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 = $field_member$;\n"
        "    $field_member$ = nullptr;\n"
        "    return temp;\n"
        "  } else {\n"
        "    return nullptr;\n"
        "  }\n"
        "}\n"
        "inline void $classname$::unsafe_arena_set_allocated_$name$"
        "($type$* $name$) {\n"
        // We rely on the oneof clear method to free the earlier contents of
        // this oneof. We can directly use the pointer we're given to set the
        // new value.
        "  clear_$oneof_name$();\n"
        "  if ($name$) {\n"
        "    set_has_$name$();\n"
        "    $field_member$ = $name$;\n"
        "  }\n"
        "  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
        "$full_name$)\n"
        "}\n");
  }

  format(
      "inline $type$* $classname$::mutable_$name$() {\n"
      "  if (!has_$name$()) {\n"
      "    clear_$oneof_name$();\n"
      "    set_has_$name$();\n"
      "    $field_member$ = CreateMaybeMessage< $type$ >(\n"
      "        GetArenaNoVirtual());\n"
      "  }\n"
      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
      "  return $field_member$;\n"
      "}\n");
}

void MessageOneofFieldGenerator::GenerateClearingCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (SupportsArenas(descriptor_)) {
    format(
        "if (GetArenaNoVirtual() == nullptr) {\n"
        "  delete $field_member$;\n"
        "}\n");
  } else {
    format("delete $field_member$;\n");
  }
}

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

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

void MessageOneofFieldGenerator::GenerateDestructorCode(
    io::Printer* printer) const {
  // We inherit from MessageFieldGenerator, so we need to override the default
  // behavior.
}

void MessageOneofFieldGenerator::GenerateConstructorCode(
    io::Printer* printer) const {
  // Don't print any constructor code. The field is in a union. We allocate
  // space only when this field is used.
}

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

RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
    const FieldDescriptor* descriptor, const Options& options,
    MessageSCCAnalyzer* scc_analyzer)
    : FieldGenerator(descriptor, options),
      implicit_weak_field_(
          IsImplicitWeakField(descriptor, options, scc_analyzer)) {
  SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
}

RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}

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

void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
      "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
      "    ${1$mutable_$name$$}$();\n"
      "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
      "$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
      "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
      "    ${1$$name$$}$() const;\n",
      descriptor_);
}

void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "inline $type$* $classname$::mutable_$name$(int index) {\n"
      // TODO(dlj): move insertion points
      "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
      "$type_reference_function$"
      "  return $name$_.Mutable(index);\n"
      "}\n"
      "inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
      "$classname$::mutable_$name$() {\n"
      "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
      "$type_reference_function$"
      "  return &$name$_;\n"
      "}\n");

  if (options_.safe_boundary_check) {
    format(
        "inline const $type$& $classname$::$name$(int index) const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "  return $name$_.InternalCheckedGet(index,\n"
        "      *reinterpret_cast<const $type$*>(&$type_default_instance$));\n"
        "}\n");
  } else {
    format(
        "inline const $type$& $classname$::$name$(int index) const {\n"
        "  // @@protoc_insertion_point(field_get:$full_name$)\n"
        "$type_reference_function$"
        "  return $name$_.Get(index);\n"
        "}\n");
  }

  format(
      "inline $type$* $classname$::add_$name$() {\n"
      "  // @@protoc_insertion_point(field_add:$full_name$)\n"
      "  return $name$_.Add();\n"
      "}\n");

  format(
      "inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
      "$classname$::$name$() const {\n"
      "  // @@protoc_insertion_point(field_list:$full_name$)\n"
      "$type_reference_function$"
      "  return $name$_;\n"
      "}\n");
}

void RepeatedMessageFieldGenerator::GenerateClearingCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format(
        "CastToBase(&$name$_)->Clear<"
        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>();\n");
  } else {
    format("$name$_.Clear();\n");
  }
}

void RepeatedMessageFieldGenerator::GenerateMergingCode(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (implicit_weak_field_) {
    format(
        "CastToBase(&$name$_)->MergeFrom<"
        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>(CastToBase("
        "from.$name$_));\n");
  } else {
    format("$name$_.MergeFrom(from.$name$_);\n");
  }
}

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

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

void RepeatedMessageFieldGenerator::GenerateMergeFromCodedStream(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
    if (implicit_weak_field_) {
      format(
          "DO_(::$proto_ns$::internal::WireFormatLite::"
          "ReadMessage(input, CastToBase(&$name$_)->AddWeak(\n"
          "    reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
          "        &$type_default_instance$))));\n");
    } else {
      format(
          "DO_(::$proto_ns$::internal::WireFormatLite::"
          "ReadMessage(\n"
          "      input, add_$name$()));\n");
    }
  } else {
    format(
        "DO_(::$proto_ns$::internal::WireFormatLite::"
        "ReadGroup($number$, input, add_$name$()));\n");
  }
}

void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizes(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "for (unsigned int i = 0,\n"
      "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
      "  ::$proto_ns$::internal::WireFormatLite::Write$stream_writer$(\n"
      "    $number$,\n");
  if (implicit_weak_field_) {
    format(
        "    CastToBase($name$_).Get<"
        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
        "static_cast<int>(i)),\n");
  } else {
    format("    this->$name$(static_cast<int>(i)),\n");
  }
  format(
      "    output);\n"
      "}\n");
}

void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "for (unsigned int i = 0,\n"
      "    n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n"
      "  target = ::$proto_ns$::internal::WireFormatLite::\n"
      "    InternalWrite$declared_type$ToArray(\n"
      "      $number$, this->$name$(static_cast<int>(i)), target);\n"
      "}\n");
}

void RepeatedMessageFieldGenerator::GenerateByteSize(
    io::Printer* printer) const {
  Formatter format(printer, variables_);
  format(
      "{\n"
      "  unsigned int count = static_cast<unsigned "
      "int>(this->$name$_size());\n");
  format.Indent();
  format(
      "total_size += $tag_size$UL * count;\n"
      "for (unsigned int i = 0; i < count; i++) {\n"
      "  total_size +=\n"
      "    ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n");
  if (implicit_weak_field_) {
    format(
        "      CastToBase($name$_).Get<"
        "::$proto_ns$::internal::ImplicitWeakTypeHandler<$type$>>("
        "static_cast<int>(i)));\n");
  } else {
    format("      this->$name$(static_cast<int>(i)));\n");
  }
  format("}\n");
  format.Outdent();
  format("}\n");
}

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