// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// 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 <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/javanano/javanano_message.h>
#include <google/protobuf/compiler/javanano/javanano_enum.h>
#include <google/protobuf/compiler/javanano/javanano_extension.h>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/descriptor.pb.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace javanano {

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

namespace {

struct FieldOrderingByNumber {
  inline bool operator()(const FieldDescriptor* a,
                         const FieldDescriptor* b) const {
    return a->number() < b->number();
  }
};

// Sort the fields of the given Descriptor by number into a new[]'d array
// and return it.
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  const FieldDescriptor** fields =
    new const FieldDescriptor*[descriptor->field_count()];
  for (int i = 0; i < descriptor->field_count(); i++) {
    fields[i] = descriptor->field(i);
  }
  std::sort(fields, fields + descriptor->field_count(),
       FieldOrderingByNumber());
  return fields;
}

}  // namespace

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

MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
  : params_(params),
    descriptor_(descriptor),
    field_generators_(descriptor, params) {
}

MessageGenerator::~MessageGenerator() {}

void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
  // Generate static members for all nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    // TODO(kenton):  Reuse MessageGenerator objects?
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    MessageGenerator(descriptor_->nested_type(i), params_)
      .GenerateStaticVariables(printer);
  }
}

void MessageGenerator::GenerateStaticVariableInitializers(
    io::Printer* printer) {
  // Generate static member initializers for all nested types.
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
   // TODO(kenton):  Reuse MessageGenerator objects?
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    MessageGenerator(descriptor_->nested_type(i), params_)
      .GenerateStaticVariableInitializers(printer);
  }
}

void MessageGenerator::Generate(io::Printer* printer) {
  if (!params_.store_unknown_fields() &&
      (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
    GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
        "'store_unknown_fields' generator option is 'true'\n";
  }

  const string& file_name = descriptor_->file()->name();
  bool is_own_file =
    params_.java_multiple_files(file_name)
      && descriptor_->containing_type() == NULL;

  if (is_own_file) {
    // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below)
    // may have the same names as constants in the nested classes. This causes Java warnings, but
    // is not fatal, so we suppress those warnings here in the top-most class declaration.
    printer->Print(
      "\n"
      "@SuppressWarnings(\"hiding\")\n"
      "public final class $classname$ extends\n",
      "classname", descriptor_->name());
  } else {
    printer->Print(
      "\n"
      "public static final class $classname$ extends\n",
      "classname", descriptor_->name());
  }
  if (params_.store_unknown_fields() && params_.parcelable_messages()) {
    printer->Print(
      "    com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>",
      "classname", descriptor_->name());
  } else if (params_.store_unknown_fields()) {
    printer->Print(
      "    com.google.protobuf.nano.ExtendableMessageNano<$classname$>",
      "classname", descriptor_->name());
  } else if (params_.parcelable_messages()) {
    printer->Print(
      "    com.google.protobuf.nano.android.ParcelableMessageNano");
  } else {
    printer->Print(
      "    com.google.protobuf.nano.MessageNano");
  }
  if (params_.generate_clone()) {
    printer->Print(" implements java.lang.Cloneable {\n");
  } else {
    printer->Print(" {\n");
  }
  printer->Indent();

  if (params_.parcelable_messages()) {
    printer->Print(
      "\n"
      "// Used by Parcelable\n"
      "@SuppressWarnings({\"unused\"})\n"
      "public static final android.os.Parcelable.Creator<$classname$> CREATOR =\n"
      "    new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<\n"
      "        $classname$>($classname$.class);\n",
      "classname", descriptor_->name());
  }

  // Nested types and extensions
  for (int i = 0; i < descriptor_->extension_count(); i++) {
    ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
  }

  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
    EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
  }

  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
    if (IsMapEntry(descriptor_->nested_type(i))) continue;
    MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
  }

  // oneof
  std::map<string, string> vars;
  vars["message_name"] = descriptor_->name();
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i);
    vars["oneof_name"] = UnderscoresToCamelCase(oneof_desc);
    vars["oneof_capitalized_name"] =
        UnderscoresToCapitalizedCamelCase(oneof_desc);
    vars["oneof_index"] = SimpleItoa(oneof_desc->index());
    // Oneof Constants
    for (int j = 0; j < oneof_desc->field_count(); j++) {
      const FieldDescriptor* field = oneof_desc->field(j);
      vars["number"] = SimpleItoa(field->number());
      vars["cap_field_name"] = ToUpper(field->name());
      printer->Print(vars,
        "public static final int $cap_field_name$_FIELD_NUMBER = $number$;\n");
    }
    // oneofCase_ and oneof_
    printer->Print(vars,
      "private int $oneof_name$Case_ = 0;\n"
      "private java.lang.Object $oneof_name$_;\n");
    printer->Print(vars,
      "public int get$oneof_capitalized_name$Case() {\n"
      "  return this.$oneof_name$Case_;\n"
      "}\n");
    // Oneof clear
    printer->Print(vars,
      "public $message_name$ clear$oneof_capitalized_name$() {\n"
      "  this.$oneof_name$Case_ = 0;\n"
      "  this.$oneof_name$_ = null;\n"
      "  return this;\n"
      "}\n");
  }

  // Lazy initialization of otherwise static final fields can help prevent the
  // class initializer from being generated. We want to prevent it because it
  // stops ProGuard from inlining any methods in this class into call sites and
  // therefore reducing the method count. However, extensions are best kept as
  // public static final fields with initializers, so with their existence we
  // won't bother with lazy initialization.
  bool lazy_init = descriptor_->extension_count() == 0;

  // Empty array
  if (lazy_init) {
    printer->Print(
      "\n"
      "private static volatile $classname$[] _emptyArray;\n"
      "public static $classname$[] emptyArray() {\n"
      "  // Lazily initializes the empty array\n"
      "  if (_emptyArray == null) {\n"
      "    synchronized (\n"
      "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
      "      if (_emptyArray == null) {\n"
      "        _emptyArray = new $classname$[0];\n"
      "      }\n"
      "    }\n"
      "  }\n"
      "  return _emptyArray;\n"
      "}\n",
      "classname", descriptor_->name());
  } else {
    printer->Print(
      "\n"
      "private static final $classname$[] EMPTY_ARRAY = {};\n"
      "public static $classname$[] emptyArray() {\n"
      "  return EMPTY_ARRAY;\n"
      "}\n",
      "classname", descriptor_->name());
  }

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

  // Fields and maybe their default values
  for (int i = 0; i < descriptor_->field_count(); i++) {
    printer->Print("\n");
    PrintFieldComment(printer, descriptor_->field(i));
    field_generators_.get(descriptor_->field(i)).GenerateMembers(
        printer, lazy_init);
  }

  // Constructor, with lazy init code if needed
  if (lazy_init && field_generators_.saved_defaults_needed()) {
    printer->Print(
      "\n"
      "private static volatile boolean _classInitialized;\n"
      "\n"
      "public $classname$() {\n"
      "  // Lazily initializes the field defaults\n"
      "  if (!_classInitialized) {\n"
      "    synchronized (\n"
      "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
      "      if (!_classInitialized) {\n",
      "classname", descriptor_->name());
    printer->Indent();
    printer->Indent();
    printer->Indent();
    printer->Indent();
    for (int i = 0; i < descriptor_->field_count(); i++) {
      field_generators_.get(descriptor_->field(i))
          .GenerateInitSavedDefaultCode(printer);
    }
    printer->Outdent();
    printer->Outdent();
    printer->Outdent();
    printer->Outdent();
    printer->Print(
      "        _classInitialized = true;\n"
      "      }\n"
      "    }\n"
      "  }\n");
    if (params_.generate_clear()) {
      printer->Print("  clear();\n");
    }
    printer->Print("}\n");
  } else {
    printer->Print(
      "\n"
      "public $classname$() {\n",
      "classname", descriptor_->name());
    if (params_.generate_clear()) {
      printer->Print("  clear();\n");
    } else {
      printer->Indent();
      GenerateFieldInitializers(printer);
      printer->Outdent();
    }
    printer->Print("}\n");
  }

  // Other methods in this class

  GenerateClear(printer);

  if (params_.generate_clone()) {
    GenerateClone(printer);
  }

  if (params_.generate_equals()) {
    GenerateEquals(printer);
    GenerateHashCode(printer);
  }

  GenerateMessageSerializationMethods(printer);
  GenerateMergeFromMethods(printer);
  GenerateParseFromMethods(printer);

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

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

void MessageGenerator::
GenerateMessageSerializationMethods(io::Printer* printer) {
  // Rely on the parent implementations of writeTo() and getSerializedSize()
  // if there are no fields to serialize in this message.
  if (descriptor_->field_count() == 0) {
    return;
  }

  scoped_array<const FieldDescriptor*> sorted_fields(
    SortFieldsByNumber(descriptor_));

  printer->Print(
    "\n"
    "@Override\n"
    "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
    "    throws java.io.IOException {\n");
  printer->Indent();

  // Output the fields in sorted order
  for (int i = 0; i < descriptor_->field_count(); i++) {
    GenerateSerializeOneField(printer, sorted_fields[i]);
  }

  // The parent implementation will write any unknown fields if necessary.
  printer->Print(
    "super.writeTo(output);\n");

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

  // The parent implementation will get the serialized size for unknown
  // fields if necessary.
  printer->Print(
    "\n"
    "@Override\n"
    "protected int computeSerializedSize() {\n"
    "  int size = super.computeSerializedSize();\n");
  printer->Indent();

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

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

void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
  scoped_array<const FieldDescriptor*> sorted_fields(
    SortFieldsByNumber(descriptor_));

  printer->Print(
    "\n"
    "@Override\n"
    "public $classname$ mergeFrom(\n"
    "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
    "    throws java.io.IOException {\n",
    "classname", descriptor_->name());

  printer->Indent();
  if (HasMapField(descriptor_)) {
    printer->Print(
      "com.google.protobuf.nano.MapFactories.MapFactory mapFactory =\n"
      "  com.google.protobuf.nano.MapFactories.getMapFactory();\n");
  }

  printer->Print(
    "while (true) {\n");
  printer->Indent();

  printer->Print(
    "int tag = input.readTag();\n"
    "switch (tag) {\n");
  printer->Indent();

  printer->Print(
    "case 0:\n"          // zero signals EOF / limit reached
    "  return this;\n"
    "default: {\n");

  printer->Indent();
  if (params_.store_unknown_fields()) {
    printer->Print(
        "if (!storeUnknownField(input, tag)) {\n"
        "  return this;\n"
        "}\n");
  } else {
    printer->Print(
        "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
        "  return this;\n"   // it's an endgroup tag
        "}\n");
  }
  printer->Print("break;\n");
  printer->Outdent();
  printer->Print("}\n");

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = sorted_fields[i];
    uint32 tag = WireFormatLite::MakeTag(field->number(),
      WireFormat::WireTypeForFieldType(field->type()));

    printer->Print(
      "case $tag$: {\n",
      "tag", SimpleItoa(tag));
    printer->Indent();

    field_generators_.get(field).GenerateMergingCode(printer);

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

    if (field->is_packable()) {
      // To make packed = true wire compatible, we generate parsing code from a
      // packed version of this field regardless of field->options().packed().
      uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
        WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
      printer->Print(
        "case $tag$: {\n",
        "tag", SimpleItoa(packed_tag));
      printer->Indent();

      field_generators_.get(field).GenerateMergingCodeFromPacked(printer);

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

  printer->Outdent();
  printer->Outdent();
  printer->Outdent();
  printer->Print(
    "    }\n"     // switch (tag)
    "  }\n"       // while (true)
    "}\n");
}

void MessageGenerator::
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(
    "\n"
    "public static $classname$ parseFrom(byte[] data)\n"
    "    throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n"
    "  return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n"
    "}\n"
    "\n"
    "public static $classname$ parseFrom(\n"
    "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
    "    throws java.io.IOException {\n"
    "  return new $classname$().mergeFrom(input);\n"
    "}\n",
    "classname", descriptor_->name());
}

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

void MessageGenerator::GenerateClear(io::Printer* printer) {
  if (!params_.generate_clear()) {
    return;
  }
  printer->Print(
    "\n"
    "public $classname$ clear() {\n",
    "classname", descriptor_->name());
  printer->Indent();

  GenerateFieldInitializers(printer);

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

void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) {
  // Clear bit fields.
  int totalInts = (field_generators_.total_bits() + 31) / 32;
  for (int i = 0; i < totalInts; i++) {
    printer->Print("$bit_field_name$ = 0;\n",
      "bit_field_name", GetBitFieldName(i));
  }

  // Call clear for all of the fields.
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    field_generators_.get(field).GenerateClearCode(printer);
  }

  // Clear oneofs.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    printer->Print(
      "clear$oneof_capitalized_name$();\n",
      "oneof_capitalized_name", UnderscoresToCapitalizedCamelCase(
          descriptor_->oneof_decl(i)));
  }

  // Clear unknown fields.
  if (params_.store_unknown_fields()) {
    printer->Print("unknownFieldData = null;\n");
  }
  printer->Print("cachedSize = -1;\n");
}

void MessageGenerator::GenerateClone(io::Printer* printer) {
  printer->Print(
    "@Override\n"
    "public $classname$ clone() {\n",
    "classname", descriptor_->name());
  printer->Indent();

  printer->Print(
    "$classname$ cloned;\n"
    "try {\n"
    "  cloned = ($classname$) super.clone();\n"
    "} catch (java.lang.CloneNotSupportedException e) {\n"
    "  throw new java.lang.AssertionError(e);\n"
    "}\n",
    "classname", descriptor_->name());

  for (int i = 0; i < descriptor_->field_count(); i++) {
    field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer);
  }

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

void MessageGenerator::GenerateEquals(io::Printer* printer) {
  // Don't override if there are no fields. We could generate an
  // equals method that compares types, but often empty messages
  // are used as namespaces.
  if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
    return;
  }

  printer->Print(
    "\n"
    "@Override\n"
    "public boolean equals(Object o) {\n");
  printer->Indent();
  printer->Print(
    "if (o == this) {\n"
    "  return true;\n"
    "}\n"
    "if (!(o instanceof $classname$)) {\n"
    "  return false;\n"
    "}\n"
    "$classname$ other = ($classname$) o;\n",
    "classname", descriptor_->name());

  // Checking oneof case before checking each oneof field.
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
    const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i);
    printer->Print(
      "if (this.$oneof_name$Case_ != other.$oneof_name$Case_) {\n"
      "  return false;\n"
      "}\n",
      "oneof_name", UnderscoresToCamelCase(oneof_desc));
  }

  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    field_generators_.get(field).GenerateEqualsCode(printer);
  }

  if (params_.store_unknown_fields()) {
    printer->Print(
      "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n"
      "  return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n"
      "} else {\n"
      "  return unknownFieldData.equals(other.unknownFieldData);\n"
      "}");
  } else {
    printer->Print(
      "return true;\n");
  }

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

void MessageGenerator::GenerateHashCode(io::Printer* printer) {
  if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
    return;
  }

  printer->Print(
    "\n"
    "@Override\n"
    "public int hashCode() {\n");
  printer->Indent();

  printer->Print("int result = 17;\n");
  printer->Print("result = 31 * result + getClass().getName().hashCode();\n");
  for (int i = 0; i < descriptor_->field_count(); i++) {
    const FieldDescriptor* field = descriptor_->field(i);
    field_generators_.get(field).GenerateHashCodeCode(printer);
  }

  if (params_.store_unknown_fields()) {
    printer->Print(
      "result = 31 * result + \n"
      "  (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n"
      "  unknownFieldData.hashCode());\n");
  }

  printer->Print("return result;\n");

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

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

}  // namespace javanano
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
