// 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/java/message.h>

#include <algorithm>
#include <cstdint>
#include <map>
#include <memory>
#include <vector>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/compiler/java/context.h>
#include <google/protobuf/compiler/java/doc_comment.h>
#include <google/protobuf/compiler/java/enum.h>
#include <google/protobuf/compiler/java/extension.h>
#include <google/protobuf/compiler/java/generator_factory.h>
#include <google/protobuf/compiler/java/helpers.h>
#include <google/protobuf/compiler/java/message_builder.h>
#include <google/protobuf/compiler/java/message_builder_lite.h>
#include <google/protobuf/compiler/java/name_resolver.h>
#include <google/protobuf/descriptor.pb.h>

// Must be last.
#include <google/protobuf/port_def.inc>

namespace google {
namespace protobuf {
namespace compiler {
namespace java {

using internal::WireFormat;
using internal::WireFormatLite;

namespace {
std::string MapValueImmutableClassdName(const Descriptor* descriptor,
                                        ClassNameResolver* name_resolver) {
  const FieldDescriptor* value_field = descriptor->map_value();
  GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
  return name_resolver->GetImmutableClassName(value_field->message_type());
}
}  // namespace

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

MessageGenerator::MessageGenerator(const Descriptor* descriptor)
    : descriptor_(descriptor) {
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (IsRealOneof(descriptor_->field(i))) {
      oneofs_.insert(descriptor_->field(i)->containing_oneof());
    }
  }
}

MessageGenerator::~MessageGenerator() {}

// ===================================================================
ImmutableMessageGenerator::ImmutableMessageGenerator(
    const Descriptor* descriptor, Context* context)
    : MessageGenerator(descriptor),
      context_(context),
      name_resolver_(context->GetNameResolver()),
      field_generators_(descriptor, context_) {
  GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
      << "Generator factory error: A non-lite message generator is used to "
         "generate lite messages.";
}

ImmutableMessageGenerator::~ImmutableMessageGenerator() {}

void ImmutableMessageGenerator::GenerateStaticVariables(
    io::Printer* printer, int* bytecode_estimate) {
  // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
  // used in the construction of descriptors, we have a tricky bootstrapping
  // problem.  To help control static initialization order, we make sure all
  // descriptors and other static data that depends on them are members of
  // the outermost class in the file.  This way, they will be initialized in
  // a deterministic order.

  std::map<std::string, std::string> vars;
  vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
  vars["index"] = StrCat(descriptor_->index());
  vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
  if (descriptor_->containing_type() != NULL) {
    vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
  }
  if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
    // We can only make these package-private since the classes that use them
    // are in separate files.
    vars["private"] = "";
  } else {
    vars["private"] = "private ";
  }
  if (*bytecode_estimate <= kMaxStaticSize) {
    vars["final"] = "final ";
  } else {
    vars["final"] = "";
  }

  // The descriptor for this type.
  printer->Print(
      vars,
      // TODO(teboring): final needs to be added back. The way to fix it is to
      // generate methods that can construct the types, and then still declare
      // the types, and then init them in clinit with the new method calls.
      "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
      "  internal_$identifier$_descriptor;\n");
  *bytecode_estimate += 30;

  // And the FieldAccessorTable.
  GenerateFieldAccessorTable(printer, bytecode_estimate);

  // Generate static members for all nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // TODO(kenton):  Reuse MessageGenerator objects?
    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
        .GenerateStaticVariables(printer, bytecode_estimate);
  }
}

int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
    io::Printer* printer) {
  int bytecode_estimate = 0;
  std::map<std::string, std::string> vars;
  vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
  vars["index"] = StrCat(descriptor_->index());
  vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
  if (descriptor_->containing_type() != NULL) {
    vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
  }

  // The descriptor for this type.
  if (descriptor_->containing_type() == NULL) {
    printer->Print(vars,
                   "internal_$identifier$_descriptor =\n"
                   "  getDescriptor().getMessageTypes().get($index$);\n");
    bytecode_estimate += 30;
  } else {
    printer->Print(
        vars,
        "internal_$identifier$_descriptor =\n"
        "  internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
    bytecode_estimate += 30;
  }

  // And the FieldAccessorTable.
  bytecode_estimate += GenerateFieldAccessorTableInitializer(printer);

  // Generate static member initializers for all nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // TODO(kenton):  Reuse MessageGenerator objects?
    bytecode_estimate +=
        ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
            .GenerateStaticVariableInitializers(printer);
  }
  return bytecode_estimate;
}

void ImmutableMessageGenerator::GenerateFieldAccessorTable(
    io::Printer* printer, int* bytecode_estimate) {
  std::map<std::string, std::string> vars;
  vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
  if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
    // We can only make these package-private since the classes that use them
    // are in separate files.
    vars["private"] = "";
  } else {
    vars["private"] = "private ";
  }
  if (*bytecode_estimate <= kMaxStaticSize) {
    vars["final"] = "final ";
  } else {
    vars["final"] = "";
  }
  vars["ver"] = GeneratedCodeVersionSuffix();
  printer->Print(
      vars,
      "$private$static $final$\n"
      "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
      "    internal_$identifier$_fieldAccessorTable;\n");

  // The following bytecode_estimate calculation logic must stay in sync with
  // the similar logic in the GenerateFieldAccessorTableInitializer method below
  // to make sure that the generated static final fields are initialized  in the
  // static initialization block directly.
  //
  // 6 bytes per field and oneof
  *bytecode_estimate +=
      10 + 6 * descriptor_->field_count() + 6 * descriptor_->oneof_decl_count();
}

int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer(
    io::Printer* printer) {
  int bytecode_estimate = 10;
  printer->Print(
      "internal_$identifier$_fieldAccessorTable = new\n"
      "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
      "    internal_$identifier$_descriptor,\n"
      "    new java.lang.String[] { ",
      "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
      GeneratedCodeVersionSuffix());
  // All the bytecode_estimate calculation logic in this method must stay in
  // sync with the similar logic in the GenerateFieldAccessorTable method
  // above. See the corresponding comment in GenerateFieldAccessorTable for
  // details.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
    bytecode_estimate += 6;
    printer->Print("\"$field_name$\", ", "field_name", info->capitalized_name);
  }
  // We reproduce synthetic oneofs here since proto reflection needs these.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
    const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
    bytecode_estimate += 6;
    printer->Print("\"$oneof_name$\", ", "oneof_name", info->capitalized_name);
  }
  printer->Print("});\n");
  return bytecode_estimate;
}

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

void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
  MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
                                /* immutable = */ true, "OrBuilder");
  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
        "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
        "    $extra_interfaces$\n"
        "    com.google.protobuf.GeneratedMessage$ver$.\n"
        "        ExtendableMessageOrBuilder<$classname$> {\n",
        "deprecation",
        descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
        "classname", descriptor_->name(), "{", "", "}", "", "ver",
        GeneratedCodeVersionSuffix());
  } else {
    printer->Print(
        "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
        "    $extra_interfaces$\n"
        "    com.google.protobuf.MessageOrBuilder {\n",
        "deprecation",
        descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
        "classname", descriptor_->name(), "{", "", "}", "");
  }
  printer->Annotate("{", "}", descriptor_);

  printer->Indent();
  for (int i = 0; i < descriptor_->field_count(); i++) {
    printer->Print("\n");
    field_generators_.get(descriptor_->field(i))
        .GenerateInterfaceMembers(printer);
  }
  for (auto oneof : oneofs_) {
    printer->Print(
        "\n"
        "public $classname$.$oneof_capitalized_name$Case "
        "get$oneof_capitalized_name$Case();\n",
        "oneof_capitalized_name",
        context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
        context_->GetNameResolver()->GetImmutableClassName(descriptor_));
  }
  printer->Outdent();

  printer->Print("}\n");
}

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

void ImmutableMessageGenerator::Generate(io::Printer* printer) {
  bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);

  std::map<std::string, std::string> variables;
  variables["static"] = is_own_file ? "" : "static ";
  variables["classname"] = descriptor_->name();
  variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
  variables["ver"] = GeneratedCodeVersionSuffix();
  variables["deprecation"] =
      descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";

  WriteMessageDocComment(printer, descriptor_);
  MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
                                /* immutable = */ true);
  // The builder_type stores the super type name of the nested Builder class.
  std::string builder_type;
  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
        variables,
        "$deprecation$public $static$final class $classname$ extends\n");
    printer->Annotate("classname", descriptor_);
    printer->Print(
        variables,
        "    com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
        "      $classname$> implements\n"
        "    $extra_interfaces$\n"
        "    $classname$OrBuilder {\n");
    builder_type = strings::Substitute(
        "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
        name_resolver_->GetImmutableClassName(descriptor_),
        GeneratedCodeVersionSuffix());
  } else {
    printer->Print(
        variables,
        "$deprecation$public $static$final class $classname$ extends\n");
    printer->Annotate("classname", descriptor_);
    printer->Print(variables,
                   "    com.google.protobuf.GeneratedMessage$ver$ implements\n"
                   "    $extra_interfaces$\n"
                   "    $classname$OrBuilder {\n");
    builder_type =
        strings::Substitute("com.google.protobuf.GeneratedMessage$0.Builder<?>",
                         GeneratedCodeVersionSuffix());
  }
  printer->Print("private static final long serialVersionUID = 0L;\n");

  printer->Indent();
  // Using builder_type, instead of Builder, prevents the Builder class from
  // being loaded into PermGen space when the default instance is created.
  // This optimizes the PermGen space usage for clients that do not modify
  // messages.
  printer->Print(
      "// Use $classname$.newBuilder() to construct.\n"
      "private $classname$($buildertype$ builder) {\n"
      "  super(builder);\n"
      "}\n",
      "classname", descriptor_->name(), "buildertype", builder_type);
  printer->Print("private $classname$() {\n", "classname", descriptor_->name());
  printer->Indent();
  GenerateInitializers(printer);
  printer->Outdent();
  printer->Print(
      "}\n"
      "\n");

  printer->Print(variables,
                 "@java.lang.Override\n"
                 "@SuppressWarnings({\"unused\"})\n"
                 "protected java.lang.Object newInstance(\n"
                 "    UnusedPrivateParameter unused) {\n"
                 "  return new $classname$();\n"
                 "}\n"
                 "\n");

  // TODO(b/248149118): Remove this superfluous override.
  printer->Print(
      "@java.lang.Override\n"
      "public final com.google.protobuf.UnknownFieldSet\n"
      "getUnknownFields() {\n"
      "  return this.unknownFields;\n"
      "}\n");

  GenerateDescriptorMethods(printer);

  // Nested types
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    EnumGenerator(descriptor_->enum_type(i), true, context_).Generate(printer);
  }

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // Don't generate Java classes for map entry messages.
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    ImmutableMessageGenerator messageGenerator(descriptor_->nested_type(i),
                                               context_);
    messageGenerator.GenerateInterface(printer);
    messageGenerator.Generate(printer);
  }

  // Integers for bit fields.
  int totalBits = 0;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    totalBits +=
        field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
  }
  int totalInts = (totalBits + 31) / 32;
  for (int i = 0; i < totalInts; i++) {
    printer->Print("private int $bit_field_name$;\n", "bit_field_name",
                   GetBitFieldName(i));
  }

  // oneof
  std::map<std::string, std::string> vars;
  for (auto oneof : oneofs_) {
    vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
    vars["oneof_capitalized_name"] =
        context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
    vars["oneof_index"] = StrCat((oneof)->index());
    // oneofCase_ and oneof_
    printer->Print(vars,
                   "private int $oneof_name$Case_ = 0;\n"
                   "private java.lang.Object $oneof_name$_;\n");
    // OneofCase enum
    printer->Print(
        vars,
        "public enum $oneof_capitalized_name$Case\n"
        // TODO(dweis): Remove EnumLite when we want to break compatibility with
        // 3.x users
        "    implements com.google.protobuf.Internal.EnumLite,\n"
        "        com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n");
    printer->Indent();
    for (int j = 0; j < (oneof)->field_count(); j++) {
      const FieldDescriptor* field = (oneof)->field(j);
      printer->Print(
          "$deprecation$$field_name$($field_number$),\n", "deprecation",
          field->options().deprecated() ? "@java.lang.Deprecated " : "",
          "field_name", ToUpper(field->name()), "field_number",
          StrCat(field->number()));
    }
    printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
                   ToUpper(vars["oneof_name"]));
    printer->Print(vars,
                   "private final int value;\n"
                   "private $oneof_capitalized_name$Case(int value) {\n"
                   "  this.value = value;\n"
                   "}\n");
    printer->Print(
        vars,
        "/**\n"
        " * @param value The number of the enum to look for.\n"
        " * @return The enum associated with the given number.\n"
        " * @deprecated Use {@link #forNumber(int)} instead.\n"
        " */\n"
        "@java.lang.Deprecated\n"
        "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
        "  return forNumber(value);\n"
        "}\n"
        "\n"
        "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
        "  switch (value) {\n");
    for (int j = 0; j < (oneof)->field_count(); j++) {
      const FieldDescriptor* field = (oneof)->field(j);
      printer->Print("    case $field_number$: return $field_name$;\n",
                     "field_number", StrCat(field->number()),
                     "field_name", ToUpper(field->name()));
    }
    printer->Print(
        "    case 0: return $cap_oneof_name$_NOT_SET;\n"
        "    default: return null;\n"
        "  }\n"
        "}\n"
        "public int getNumber() {\n"
        "  return this.value;\n"
        "}\n",
        "cap_oneof_name", ToUpper(vars["oneof_name"]));
    printer->Outdent();
    printer->Print("};\n\n");
    // oneofCase()
    printer->Print(vars,
                   "public $oneof_capitalized_name$Case\n"
                   "get$oneof_capitalized_name$Case() {\n"
                   "  return $oneof_capitalized_name$Case.forNumber(\n"
                   "      $oneof_name$Case_);\n"
                   "}\n"
                   "\n");
  }

  if (IsAnyMessage(descriptor_)) {
    GenerateAnyMethods(printer);
  }

  // Fields
  for (int i = 0; i < descriptor_->field_count(); i++) {
    printer->Print("public static final int $constant_name$ = $number$;\n",
                   "constant_name", FieldConstantName(descriptor_->field(i)),
                   "number", StrCat(descriptor_->field(i)->number()));
    printer->Annotate("constant_name", descriptor_->field(i));
    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
    printer->Print("\n");
  }

  if (context_->HasGeneratedMethods(descriptor_)) {
    GenerateIsInitialized(printer);
    GenerateMessageSerializationMethods(printer);
    GenerateEqualsAndHashCode(printer);
  }


  GenerateParseFromMethods(printer);
  GenerateBuilder(printer);

  printer->Print(
      "\n"
      "// @@protoc_insertion_point(class_scope:$full_name$)\n",
      "full_name", descriptor_->full_name());

  // Carefully initialize the default instance in such a way that it doesn't
  // conflict with other initialization.
  printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
                 "classname",
                 name_resolver_->GetImmutableClassName(descriptor_));
  printer->Print(
      "static {\n"
      "  DEFAULT_INSTANCE = new $classname$();\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));

  printer->Print(
      "public static $classname$ getDefaultInstance() {\n"
      "  return DEFAULT_INSTANCE;\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));

  // 'of' method for Wrappers
  if (IsWrappersProtoFile(descriptor_->file())) {
    printer->Print(
        "public static $classname$ of($field_type$ value) {\n"
        "  return newBuilder().setValue(value).build();\n"
        "}\n"
        "\n",
        "classname", name_resolver_->GetImmutableClassName(descriptor_),
        "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
  }

  GenerateParser(printer);

  printer->Print(
      "@java.lang.Override\n"
      "public $classname$ getDefaultInstanceForType() {\n"
      "  return DEFAULT_INSTANCE;\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));

  // Extensions must be declared after the DEFAULT_INSTANCE is initialized
  // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
  // the outer class's FileDescriptor.
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    ImmutableExtensionGenerator(descriptor_->extension(i), context_)
        .Generate(printer);
  }

  printer->Outdent();
  printer->Print("}\n\n");
}

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

void ImmutableMessageGenerator::GenerateMessageSerializationMethods(
    io::Printer* printer) {
  std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
      SortFieldsByNumber(descriptor_));

  std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  sorted_extensions.reserve(descriptor_->extension_range_count());
  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
    sorted_extensions.push_back(descriptor_->extension_range(i));
  }
  std::sort(sorted_extensions.begin(), sorted_extensions.end(),
            ExtensionRangeOrdering());
  printer->Print(
      "@java.lang.Override\n"
      "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
      "                    throws java.io.IOException {\n");
  printer->Indent();

  if (HasPackedFields(descriptor_)) {
    // writeTo(CodedOutputStream output) might be invoked without
    // getSerializedSize() ever being called, but we need the memoized
    // sizes in case this message has packed fields. Rather than emit checks
    // for each packed field, just call getSerializedSize() up front. In most
    // cases, getSerializedSize() will have already been called anyway by one
    // of the wrapper writeTo() methods, making this call cheap.
    printer->Print("getSerializedSize();\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    if (descriptor_->options().message_set_wire_format()) {
      printer->Print(
          "com.google.protobuf.GeneratedMessage$ver$\n"
          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
          "    extensionWriter = newMessageSetExtensionWriter();\n",
          "classname", name_resolver_->GetImmutableClassName(descriptor_),
          "ver", GeneratedCodeVersionSuffix());
    } else {
      printer->Print(
          "com.google.protobuf.GeneratedMessage$ver$\n"
          "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
          "    extensionWriter = newExtensionWriter();\n",
          "classname", name_resolver_->GetImmutableClassName(descriptor_),
          "ver", GeneratedCodeVersionSuffix());
    }
  }

  // Merge the fields and the extension ranges, both sorted by field number.
  for (int i = 0, j = 0;
       i < descriptor_->field_count() || j < sorted_extensions.size();) {
    if (i == descriptor_->field_count()) {
      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
    } else if (j == sorted_extensions.size()) {
      GenerateSerializeOneField(printer, sorted_fields[i++]);
    } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
      GenerateSerializeOneField(printer, sorted_fields[i++]);
    } else {
      GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
    }
  }

  if (descriptor_->options().message_set_wire_format()) {
    printer->Print("getUnknownFields().writeAsMessageSetTo(output);\n");
  } else {
    printer->Print("getUnknownFields().writeTo(output);\n");
  }

  printer->Outdent();
  printer->Print(
      "}\n"
      "\n"
      "@java.lang.Override\n"
      "public int getSerializedSize() {\n"
      "  int size = memoizedSize;\n"
      "  if (size != -1) return size;\n"
      "\n");
  printer->Indent();

  printer->Print("size = 0;\n");

  for (int i = 0; i < descriptor_->field_count(); i++) {
    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
  }

  if (descriptor_->extension_range_count() > 0) {
    if (descriptor_->options().message_set_wire_format()) {
      printer->Print("size += extensionsSerializedSizeAsMessageSet();\n");
    } else {
      printer->Print("size += extensionsSerializedSize();\n");
    }
  }

  if (descriptor_->options().message_set_wire_format()) {
    printer->Print(
        "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
  } else {
    printer->Print("size += getUnknownFields().getSerializedSize();\n");
  }

  printer->Print(
      "memoizedSize = size;\n"
      "return size;\n");

  printer->Outdent();
  printer->Print(
      "}\n"
      "\n");
}

void ImmutableMessageGenerator::GenerateParseFromMethods(io::Printer* printer) {
  // Note:  These are separate from GenerateMessageSerializationMethods()
  //   because they need to be generated even for messages that are optimized
  //   for code size.
  printer->Print(
      "public static $classname$ parseFrom(\n"
      "    java.nio.ByteBuffer data)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    java.nio.ByteBuffer data,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data, extensionRegistry);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    com.google.protobuf.ByteString data)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    com.google.protobuf.ByteString data,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data, extensionRegistry);\n"
      "}\n"
      "public static $classname$ parseFrom(byte[] data)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    byte[] data,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  return PARSER.parseFrom(data, extensionRegistry);\n"
      "}\n"
      "public static $classname$ parseFrom(java.io.InputStream input)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseWithIOException(PARSER, input);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    java.io.InputStream input,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
      "}\n"
      "public static $classname$ parseDelimitedFrom(java.io.InputStream "
      "input)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseDelimitedWithIOException(PARSER, input);\n"
      "}\n"
      "public static $classname$ parseDelimitedFrom(\n"
      "    java.io.InputStream input,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseDelimitedWithIOException(PARSER, input, "
      "extensionRegistry);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    com.google.protobuf.CodedInputStream input)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseWithIOException(PARSER, input);\n"
      "}\n"
      "public static $classname$ parseFrom(\n"
      "    com.google.protobuf.CodedInputStream input,\n"
      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "    throws java.io.IOException {\n"
      "  return com.google.protobuf.GeneratedMessage$ver$\n"
      "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver",
      GeneratedCodeVersionSuffix());
}

void ImmutableMessageGenerator::GenerateSerializeOneField(
    io::Printer* printer, const FieldDescriptor* field) {
  field_generators_.get(field).GenerateSerializationCode(printer);
}

void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
    io::Printer* printer, const Descriptor::ExtensionRange* range) {
  printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
                 StrCat(range->end));
}

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

void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
  // LITE_RUNTIME implements this at the GeneratedMessageLite level.
  printer->Print(
      "@java.lang.Override\n"
      "public Builder newBuilderForType() { return newBuilder(); }\n");

  printer->Print(
      "public static Builder newBuilder() {\n"
      "  return DEFAULT_INSTANCE.toBuilder();\n"
      "}\n"
      "public static Builder newBuilder($classname$ prototype) {\n"
      "  return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
      "}\n"
      "@java.lang.Override\n"
      "public Builder toBuilder() {\n"
      "  return this == DEFAULT_INSTANCE\n"
      "      ? new Builder() : new Builder().mergeFrom(this);\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));

  printer->Print(
      "@java.lang.Override\n"
      "protected Builder newBuilderForType(\n"
      "    com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
      "  Builder builder = new Builder(parent);\n"
      "  return builder;\n"
      "}\n",
      "ver", GeneratedCodeVersionSuffix());

  MessageBuilderGenerator builderGenerator(descriptor_, context_);
  builderGenerator.Generate(printer);
}

void ImmutableMessageGenerator::GenerateDescriptorMethods(
    io::Printer* printer) {
  if (!descriptor_->options().no_standard_descriptor_accessor()) {
    printer->Print(
        "public static final com.google.protobuf.Descriptors.Descriptor\n"
        "    getDescriptor() {\n"
        "  return $fileclass$.internal_$identifier$_descriptor;\n"
        "}\n"
        "\n",
        "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
        "identifier", UniqueFileScopeIdentifier(descriptor_));
  }
  std::vector<const FieldDescriptor*> map_fields;
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (GetJavaType(field) == JAVATYPE_MESSAGE &&
        IsMapEntry(field->message_type())) {
      map_fields.push_back(field);
    }
  }
  if (!map_fields.empty()) {
    printer->Print(
        "@SuppressWarnings({\"rawtypes\"})\n"
        "@java.lang.Override\n"
        "protected com.google.protobuf.MapField internalGetMapField(\n"
        "    int number) {\n"
        "  switch (number) {\n");
    printer->Indent();
    printer->Indent();
    for (int i = 0; i < map_fields.size(); ++i) {
      const FieldDescriptor* field = map_fields[i];
      const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
      printer->Print(
          "case $number$:\n"
          "  return internalGet$capitalized_name$();\n",
          "number", StrCat(field->number()), "capitalized_name",
          info->capitalized_name);
    }
    printer->Print(
        "default:\n"
        "  throw new RuntimeException(\n"
        "      \"Invalid map field number: \" + number);\n");
    printer->Outdent();
    printer->Outdent();
    printer->Print(
        "  }\n"
        "}\n");
  }
  printer->Print(
      "@java.lang.Override\n"
      "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
      "    internalGetFieldAccessorTable() {\n"
      "  return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
      "      .ensureFieldAccessorsInitialized(\n"
      "          $classname$.class, $classname$.Builder.class);\n"
      "}\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_),
      "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
      "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
      GeneratedCodeVersionSuffix());
}

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

void ImmutableMessageGenerator::GenerateIsInitialized(io::Printer* printer) {
  // Memoizes whether the protocol buffer is fully initialized (has all
  // required fields). -1 means not yet computed. 0 means false and 1 means
  // true.
  printer->Print("private byte memoizedIsInitialized = -1;\n");
  printer->Print(
      "@java.lang.Override\n"
      "public final boolean isInitialized() {\n");
  printer->Indent();

  // Don't directly compare to -1 to avoid an Android x86 JIT bug.
  printer->Print(
      "byte isInitialized = memoizedIsInitialized;\n"
      "if (isInitialized == 1) return true;\n"
      "if (isInitialized == 0) return false;\n"
      "\n");

  // Check that all required fields in this message are set.
  // TODO(kenton):  We can optimize this when we switch to putting all the
  //   "has" fields into a single bitfield.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);

    if (field->is_required()) {
      printer->Print(
          "if (!has$name$()) {\n"
          "  memoizedIsInitialized = 0;\n"
          "  return false;\n"
          "}\n",
          "name", info->capitalized_name);
    }
  }

  // Now check that all embedded messages are initialized.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
    if (GetJavaType(field) == JAVATYPE_MESSAGE &&
        HasRequiredFields(field->message_type())) {
      switch (field->label()) {
        case FieldDescriptor::LABEL_REQUIRED:
          printer->Print(
              "if (!get$name$().isInitialized()) {\n"
              "  memoizedIsInitialized = 0;\n"
              "  return false;\n"
              "}\n",
              "type",
              name_resolver_->GetImmutableClassName(field->message_type()),
              "name", info->capitalized_name);
          break;
        case FieldDescriptor::LABEL_OPTIONAL:
          printer->Print(
              "if (has$name$()) {\n"
              "  if (!get$name$().isInitialized()) {\n"
              "    memoizedIsInitialized = 0;\n"
              "    return false;\n"
              "  }\n"
              "}\n",
              "name", info->capitalized_name);
          break;
        case FieldDescriptor::LABEL_REPEATED:
          if (IsMapEntry(field->message_type())) {
            printer->Print(
                "for ($type$ item : get$name$Map().values()) {\n"
                "  if (!item.isInitialized()) {\n"
                "    memoizedIsInitialized = 0;\n"
                "    return false;\n"
                "  }\n"
                "}\n",
                "type",
                MapValueImmutableClassdName(field->message_type(),
                                            name_resolver_),
                "name", info->capitalized_name);
          } else {
            printer->Print(
                "for (int i = 0; i < get$name$Count(); i++) {\n"
                "  if (!get$name$(i).isInitialized()) {\n"
                "    memoizedIsInitialized = 0;\n"
                "    return false;\n"
                "  }\n"
                "}\n",
                "type",
                name_resolver_->GetImmutableClassName(field->message_type()),
                "name", info->capitalized_name);
          }
          break;
      }
    }
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
        "if (!extensionsAreInitialized()) {\n"
        "  memoizedIsInitialized = 0;\n"
        "  return false;\n"
        "}\n");
  }

  printer->Outdent();

  printer->Print("  memoizedIsInitialized = 1;\n");

  printer->Print(
      "  return true;\n"
      "}\n"
      "\n");
}

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

namespace {
bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
  if (field->is_repeated()) {
    return false;
  }
  if (HasHasbit(field)) {
    return true;
  }
  return GetJavaType(field) == JAVATYPE_MESSAGE && !IsRealOneof(field);
}
}  // namespace

void ImmutableMessageGenerator::GenerateEqualsAndHashCode(
    io::Printer* printer) {
  printer->Print(
      "@java.lang.Override\n"
      "public boolean equals(");
  printer->Print("final java.lang.Object obj) {\n");
  printer->Indent();
  printer->Print(
      "if (obj == this) {\n"
      " return true;\n"
      "}\n"
      "if (!(obj instanceof $classname$)) {\n"
      "  return super.equals(obj);\n"
      "}\n"
      "$classname$ other = ($classname$) obj;\n"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (!IsRealOneof(field)) {
      const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
      bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
      if (check_has_bits) {
        printer->Print(
            "if (has$name$() != other.has$name$()) return false;\n"
            "if (has$name$()) {\n",
            "name", info->capitalized_name);
        printer->Indent();
      }
      field_generators_.get(field).GenerateEqualsCode(printer);
      if (check_has_bits) {
        printer->Outdent();
        printer->Print("}\n");
      }
    }
  }

  // Compare oneofs.
  for (auto oneof : oneofs_) {
    printer->Print(
        "if (!get$oneof_capitalized_name$Case().equals("
        "other.get$oneof_capitalized_name$Case())) return false;\n",
        "oneof_capitalized_name",
        context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
    printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
                   context_->GetOneofGeneratorInfo(oneof)->name);
    printer->Indent();
    for (int j = 0; j < (oneof)->field_count(); j++) {
      const FieldDescriptor* field = (oneof)->field(j);
      printer->Print("case $field_number$:\n", "field_number",
                     StrCat(field->number()));
      printer->Indent();
      field_generators_.get(field).GenerateEqualsCode(printer);
      printer->Print("break;\n");
      printer->Outdent();
    }
    printer->Print(
        "case 0:\n"
        "default:\n");
    printer->Outdent();
    printer->Print("}\n");
  }

  // Always consider unknown fields for equality. This will sometimes return
  // false for non-canonical ordering when running in LITE_RUNTIME but it's
  // the best we can do.
  printer->Print(
      "if (!getUnknownFields().equals(other.getUnknownFields())) return "
      "false;\n");
  if (descriptor_->extension_range_count() > 0) {
    printer->Print(
        "if (!getExtensionFields().equals(other.getExtensionFields()))\n"
        "  return false;\n");
  }
  printer->Print("return true;\n");
  printer->Outdent();
  printer->Print(
      "}\n"
      "\n");

  printer->Print(
      "@java.lang.Override\n"
      "public int hashCode() {\n");
  printer->Indent();
  printer->Print("if (memoizedHashCode != 0) {\n");
  printer->Indent();
  printer->Print("return memoizedHashCode;\n");
  printer->Outdent();
  printer->Print(
      "}\n"
      "int hash = 41;\n");

  // If we output a getDescriptor() method, use that as it is more efficient.
  if (descriptor_->options().no_standard_descriptor_accessor()) {
    printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
  } else {
    printer->Print("hash = (19 * hash) + getDescriptor().hashCode();\n");
  }

  // hashCode non-oneofs.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (!IsRealOneof(field)) {
      const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
      bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
      if (check_has_bits) {
        printer->Print("if (has$name$()) {\n", "name", info->capitalized_name);
        printer->Indent();
      }
      field_generators_.get(field).GenerateHashCode(printer);
      if (check_has_bits) {
        printer->Outdent();
        printer->Print("}\n");
      }
    }
  }

  // hashCode oneofs.
  for (auto oneof : oneofs_) {
    printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
                   context_->GetOneofGeneratorInfo(oneof)->name);
    printer->Indent();
    for (int j = 0; j < (oneof)->field_count(); j++) {
      const FieldDescriptor* field = (oneof)->field(j);
      printer->Print("case $field_number$:\n", "field_number",
                     StrCat(field->number()));
      printer->Indent();
      field_generators_.get(field).GenerateHashCode(printer);
      printer->Print("break;\n");
      printer->Outdent();
    }
    printer->Print(
        "case 0:\n"
        "default:\n");
    printer->Outdent();
    printer->Print("}\n");
  }

  if (descriptor_->extension_range_count() > 0) {
    printer->Print("hash = hashFields(hash, getExtensionFields());\n");
  }

  printer->Print("hash = (29 * hash) + getUnknownFields().hashCode();\n");
  printer->Print(
      "memoizedHashCode = hash;\n"
      "return hash;\n");
  printer->Outdent();
  printer->Print(
      "}\n"
      "\n");
}

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

void ImmutableMessageGenerator::GenerateExtensionRegistrationCode(
    io::Printer* printer) {
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    ImmutableExtensionGenerator(descriptor_->extension(i), context_)
        .GenerateRegistrationCode(printer);
  }

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
        .GenerateExtensionRegistrationCode(printer);
  }
}

// ===================================================================
void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
  printer->Print(
      "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
      "    PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n"
      "  @java.lang.Override\n"
      "  public $classname$ parsePartialFrom(\n"
      "      com.google.protobuf.CodedInputStream input,\n"
      "      com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
      "      throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "    Builder builder = newBuilder();\n"
      "    try {\n"
      "      builder.mergeFrom(input, extensionRegistry);\n"
      "    } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
      "      throw e.setUnfinishedMessage(builder.buildPartial());\n"
      "    } catch (com.google.protobuf.UninitializedMessageException e) {\n"
      "      throw "
      "e.asInvalidProtocolBufferException().setUnfinishedMessage(builder."
      "buildPartial());\n"
      "    } catch (java.io.IOException e) {\n"
      "      throw new com.google.protobuf.InvalidProtocolBufferException(e)\n"
      "          .setUnfinishedMessage(builder.buildPartial());\n"
      "    }\n"
      "    return builder.buildPartial();\n"
      "  }\n"
      "};\n"
      "\n"
      "public static com.google.protobuf.Parser<$classname$> parser() {\n"
      "  return PARSER;\n"
      "}\n"
      "\n"
      "@java.lang.Override\n"
      "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
      "  return PARSER;\n"
      "}\n"
      "\n",
      "visibility",
      ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
                                              : "private",
      "classname", descriptor_->name());
}

// ===================================================================
void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
  for (int i = 0; i < descriptor_->field_count(); i++) {
    if (!IsRealOneof(descriptor_->field(i))) {
      field_generators_.get(descriptor_->field(i))
          .GenerateInitializationCode(printer);
    }
  }
}

// ===================================================================
void ImmutableMessageGenerator::GenerateMutableCopy(io::Printer* printer) {
  printer->Print(
      "protected com.google.protobuf.MutableMessage\n"
      "    internalMutableDefault() {\n"
      "  return MutableDefaultLoader.get();\n"
      "}\n"
      "\n"
      "private static final class MutableDefaultLoader {\n"
      "  private static final java.lang.Object defaultOrRuntimeException;\n"
      "  static {\n"
      "    java.lang.Object local;\n"
      "    try {\n"
      "      local = internalMutableDefault(\"$mutable_name$\");\n"
      "    } catch (java.lang.RuntimeException e) {\n"
      "      local = e;\n"
      "    }\n"
      "    defaultOrRuntimeException = local;\n"
      "  }\n"
      "\n"
      "  private MutableDefaultLoader() {}\n"
      "\n"
      "  public static com.google.protobuf.MutableMessage get() {\n"
      "    if (defaultOrRuntimeException\n"
      "         instanceof java.lang.RuntimeException) {\n"
      "      throw (java.lang.RuntimeException) defaultOrRuntimeException;\n"
      "    }\n"
      "    return\n"
      "        (com.google.protobuf.MutableMessage) "
      "defaultOrRuntimeException;\n"
      "  }\n"
      "}\n",
      "mutable_name", name_resolver_->GetJavaMutableClassName(descriptor_));
}

void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const {
  printer->Print(
      "@kotlin.OptIn"
      "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
      "@com.google.protobuf.kotlin.ProtoDslMarker\n");
  printer->Print(
      "class Dsl private constructor(\n"
      "  private val _builder: $message$.Builder\n"
      ") {\n"
      "  companion object {\n"
      "    @kotlin.jvm.JvmSynthetic\n"
      "    @kotlin.PublishedApi\n"
      "    internal fun _create(builder: $message$.Builder): Dsl = "
      "Dsl(builder)\n"
      "  }\n"
      "\n"
      "  @kotlin.jvm.JvmSynthetic\n"
      "  @kotlin.PublishedApi\n"
      "  internal fun _build(): $message$ = _builder.build()\n",
      "message", name_resolver_->GetClassName(descriptor_, true));

  printer->Indent();

  for (int i = 0; i < descriptor_->field_count(); i++) {
    printer->Print("\n");
    field_generators_.get(descriptor_->field(i))
        .GenerateKotlinDslMembers(printer);
  }

  for (auto oneof : oneofs_) {
    printer->Print(
        "val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
        "  @JvmName(\"get$oneof_capitalized_name$Case\")\n"
        "  get() = _builder.get$oneof_capitalized_name$Case()\n\n"
        "fun clear$oneof_capitalized_name$() {\n"
        "  _builder.clear$oneof_capitalized_name$()\n"
        "}\n",
        "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name,
        "oneof_capitalized_name",
        context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message",
        name_resolver_->GetClassName(descriptor_, true));
  }

  if (descriptor_->extension_range_count() > 0) {
    GenerateKotlinExtensions(printer);
  }

  printer->Outdent();
  printer->Print("}\n");
}

void ImmutableMessageGenerator::GenerateKotlinMembers(
    io::Printer* printer) const {
  printer->Print(
      "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n"
      "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> "
      "kotlin.Unit): "
      "$message$ "
      "=\n"
      "  $message_kt$.Dsl._create($message$.newBuilder()).apply { block() "
      "}._build()\n",
      "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_),
      "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_),
      "message", name_resolver_->GetClassName(descriptor_, true));

  printer->Print("object $name$Kt {\n", "name", descriptor_->name());
  printer->Indent();
  GenerateKotlinDsl(printer);
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
        .GenerateKotlinMembers(printer);
  }
  printer->Outdent();
  printer->Print("}\n");
}

void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers(
    io::Printer* printer) const {
  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "inline fun $message$.copy(block: $message_kt$.Dsl.() -> "
      "kotlin.Unit): "
      "$message$ =\n"
      "  $message_kt$.Dsl._create(this.toBuilder()).apply { block() "
      "}._build()\n\n",
      "message", name_resolver_->GetClassName(descriptor_, true), "message_kt",
      name_resolver_->GetKotlinExtensionsClassName(descriptor_));

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
        .GenerateTopLevelKotlinMembers(printer);
  }

  GenerateKotlinOrNull(printer);
}

void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) {
      printer->Print(
          "val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n"
          "  get() = if (has$name$()) get$name$() else null\n\n",
          "full_classname", name_resolver_->GetClassName(descriptor_, true),
          "camelcase_name", context_->GetFieldGeneratorInfo(field)->name,
          "full_name",
          name_resolver_->GetImmutableClassName(field->message_type()), "name",
          context_->GetFieldGeneratorInfo(field)->capitalized_name);
    }
  }
}

void ImmutableMessageGenerator::GenerateKotlinExtensions(
    io::Printer* printer) const {
  std::string message_name = name_resolver_->GetClassName(descriptor_, true);

  printer->Print(
      "@Suppress(\"UNCHECKED_CAST\")\n"
      "@kotlin.jvm.JvmSynthetic\n"
      "operator fun <T : kotlin.Any> get(extension: "
      "com.google.protobuf.ExtensionLite<$message$, T>): T {\n"
      "  return if (extension.isRepeated) {\n"
      "    get(extension as com.google.protobuf.ExtensionLite<$message$, "
      "List<*>>) as T\n"
      "  } else {\n"
      "    _builder.getExtension(extension)\n"
      "  }\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@kotlin.OptIn"
      "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
      "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n"
      "operator fun <E : kotlin.Any> get(\n"
      "  extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n"
      "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n"
      "  return com.google.protobuf.kotlin.ExtensionList(extension, "
      "_builder.getExtension(extension))\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "operator fun contains(extension: "
      "com.google.protobuf.ExtensionLite<$message$, *>): "
      "Boolean {\n"
      "  return _builder.hasExtension(extension)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "fun clear(extension: "
      "com.google.protobuf.ExtensionLite<$message$, *>) "
      "{\n"
      "  _builder.clearExtension(extension)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@kotlin.PublishedApi\n"
      "internal fun <T : kotlin.Any> setExtension(extension: "
      "com.google.protobuf.ExtensionLite<$message$, T>, "
      "value: T) {\n"
      "  _builder.setExtension(extension, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline operator fun <T : Comparable<T>> set(\n"
      "  extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
      "  value: T\n"
      ") {\n"
      "  setExtension(extension, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline operator fun set(\n"
      "  extension: com.google.protobuf.ExtensionLite<$message$, "
      "com.google.protobuf.ByteString>,\n"
      "  value: com.google.protobuf.ByteString\n"
      ") {\n"
      "  setExtension(extension, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline operator fun <T : com.google.protobuf.MessageLite> set(\n"
      "  extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
      "  value: T\n"
      ") {\n"
      "  setExtension(extension, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "fun <E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, "
      "$message$>.add(value: E) {\n"
      "  _builder.addExtension(this.extension, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline operator fun <E : kotlin.Any> "
      "com.google.protobuf.kotlin.ExtensionList<E, "
      "$message$>.plusAssign"
      "(value: E) {\n"
      "  add(value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "fun <E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, "
      "$message$>.addAll(values: Iterable<E>) {\n"
      "  for (value in values) {\n"
      "    add(value)\n"
      "  }\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline operator fun <E : kotlin.Any> "
      "com.google.protobuf.kotlin.ExtensionList<E, "
      "$message$>.plusAssign(values: "
      "Iterable<E>) {\n"
      "  addAll(values)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "operator fun <E : kotlin.Any> "
      "com.google.protobuf.kotlin.ExtensionList<E, "
      "$message$>.set(index: Int, value: "
      "E) {\n"
      "  _builder.setExtension(this.extension, index, value)\n"
      "}\n\n",
      "message", message_name);

  printer->Print(
      "@kotlin.jvm.JvmSynthetic\n"
      "@Suppress(\"NOTHING_TO_INLINE\")\n"
      "inline fun com.google.protobuf.kotlin.ExtensionList<*, "
      "$message$>.clear() {\n"
      "  clear(extension)\n"
      "}\n\n",
      "message", message_name);
}

void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
  printer->Print(
      "private static String getTypeUrl(\n"
      "    java.lang.String typeUrlPrefix,\n"
      "    com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
      "  return typeUrlPrefix.endsWith(\"/\")\n"
      "      ? typeUrlPrefix + descriptor.getFullName()\n"
      "      : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
      "}\n"
      "\n"
      "private static String getTypeNameFromTypeUrl(\n"
      "    java.lang.String typeUrl) {\n"
      "  int pos = typeUrl.lastIndexOf('/');\n"
      "  return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
      "}\n"
      "\n"
      "public static <T extends com.google.protobuf.Message> Any pack(\n"
      "    T message) {\n"
      "  return Any.newBuilder()\n"
      "      .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
      "                             message.getDescriptorForType()))\n"
      "      .setValue(message.toByteString())\n"
      "      .build();\n"
      "}\n"
      "\n"
      "/**\n"
      " * Packs a message using the given type URL prefix. The type URL will\n"
      " * be constructed by concatenating the message type's full name to the\n"
      " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
      " * with \"/\" already.\n"
      " */\n"
      "public static <T extends com.google.protobuf.Message> Any pack(\n"
      "    T message, java.lang.String typeUrlPrefix) {\n"
      "  return Any.newBuilder()\n"
      "      .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
      "                             message.getDescriptorForType()))\n"
      "      .setValue(message.toByteString())\n"
      "      .build();\n"
      "}\n"
      "\n"
      "public <T extends com.google.protobuf.Message> boolean is(\n"
      "    java.lang.Class<T> clazz) {\n"
      "  T defaultInstance =\n"
      "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
      "  return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
      "      defaultInstance.getDescriptorForType().getFullName());\n"
      "}\n"
      "\n"
      "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
      "\n"
      "@java.lang.SuppressWarnings(\"unchecked\")\n"
      "public <T extends com.google.protobuf.Message> T unpack(\n"
      "    java.lang.Class<T> clazz)\n"
      "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
      "  boolean invalidClazz = false;\n"
      "  if (cachedUnpackValue != null) {\n"
      "    if (cachedUnpackValue.getClass() == clazz) {\n"
      "      return (T) cachedUnpackValue;\n"
      "    }\n"
      "    invalidClazz = true;\n"
      "  }\n"
      "  if (invalidClazz || !is(clazz)) {\n"
      "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
      "        \"Type of the Any message does not match the given class.\");\n"
      "  }\n"
      "  T defaultInstance =\n"
      "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
      "  T result = (T) defaultInstance.getParserForType()\n"
      "      .parseFrom(getValue());\n"
      "  cachedUnpackValue = result;\n"
      "  return result;\n"
      "}\n");
}

}  // namespace java
}  // namespace compiler
}  // namespace protobuf
}  // namespace google

#include <google/protobuf/port_undef.inc>
