// 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 <map>

#include <google/protobuf/compiler/cpp/cpp_enum.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 {
// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
// generation of the GOOGLE_ARRAYSIZE constant.
bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
  int32 max_value = descriptor->value(0)->number();
  for (int i = 0; i < descriptor->value_count(); i++) {
    if (descriptor->value(i)->number() > max_value) {
      max_value = descriptor->value(i)->number();
    }
  }
  return max_value != ::google::protobuf::kint32max;
}
}  // namespace

EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
                             const Options& options)
  : descriptor_(descriptor),
    classname_(ClassName(descriptor, false)),
    options_(options),
    generate_array_size_(ShouldGenerateArraySize(descriptor)) {
}

EnumGenerator::~EnumGenerator() {}

void EnumGenerator::FillForwardDeclaration(
    std::map<string, const EnumDescriptor*>* enum_names) {
  if (!options_.proto_h) {
    return;
  }
  (*enum_names)[classname_] = descriptor_;
}

void EnumGenerator::GenerateDefinition(io::Printer* printer) {
  std::map<string, string> vars;
  vars["classname"] = classname_;
  vars["short_name"] = descriptor_->name();
  vars["enumbase"] = options_.proto_h ? " : int" : "";
  // These variables are placeholders to pick out the beginning and ends of
  // identifiers for annotations (when doing so with existing variables would
  // be ambiguous or impossible). They should never be set to anything but the
  // empty string.
  vars["{"] = "";
  vars["}"] = "";

  printer->Print(vars, "enum $classname$$enumbase$ {\n");
  printer->Annotate("classname", descriptor_);
  printer->Indent();

  const EnumValueDescriptor* min_value = descriptor_->value(0);
  const EnumValueDescriptor* max_value = descriptor_->value(0);

  for (int i = 0; i < descriptor_->value_count(); i++) {
    vars["name"] = EnumValueName(descriptor_->value(i));
    // In C++, an value of -2147483648 gets interpreted as the negative of
    // 2147483648, and since 2147483648 can't fit in an integer, this produces a
    // compiler warning.  This works around that issue.
    vars["number"] = Int32ToString(descriptor_->value(i)->number());
    vars["prefix"] = (descriptor_->containing_type() == NULL) ?
      "" : classname_ + "_";
    vars["deprecation"] = descriptor_->value(i)->options().deprecated() ?
        " PROTOBUF_DEPRECATED" : "";

    if (i > 0) printer->Print(",\n");
    printer->Print(vars, "${$$prefix$$name$$}$$deprecation$ = $number$");
    printer->Annotate("{", "}", descriptor_->value(i));

    if (descriptor_->value(i)->number() < min_value->number()) {
      min_value = descriptor_->value(i);
    }
    if (descriptor_->value(i)->number() > max_value->number()) {
      max_value = descriptor_->value(i);
    }
  }

  if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
    // For new enum semantics: generate min and max sentinel values equal to
    // INT32_MIN and INT32_MAX
    if (descriptor_->value_count() > 0) printer->Print(",\n");
    printer->Print(vars,
        "$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,\n"
        "$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max");
  }

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

  vars["min_name"] = EnumValueName(min_value);
  vars["max_name"] = EnumValueName(max_value);

  if (options_.dllexport_decl.empty()) {
    vars["dllexport"] = "";
  } else {
    vars["dllexport"] = options_.dllexport_decl + " ";
  }

  printer->Print(vars,
                 "$dllexport$bool $classname$_IsValid(int value);\n"
                 "const $classname$ ${$$prefix$$short_name$_MIN$}$ = "
                 "$prefix$$min_name$;\n");
  printer->Annotate("{", "}", descriptor_);
  printer->Print(vars,
                 "const $classname$ ${$$prefix$$short_name$_MAX$}$ = "
                 "$prefix$$max_name$;\n");
  printer->Annotate("{", "}", descriptor_);

  if (generate_array_size_) {
    printer->Print(vars,
                   "const int ${$$prefix$$short_name$_ARRAYSIZE$}$ = "
                   "$prefix$$short_name$_MAX + 1;\n\n");
    printer->Annotate("{", "}", descriptor_);
  }

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(vars,
      "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
    // The _Name and _Parse methods
    printer->Print(
        vars,
        "inline const ::std::string& $classname$_Name($classname$ value) {\n"
        "  return ::google::protobuf::internal::NameOfEnum(\n"
        "    $classname$_descriptor(), value);\n"
        "}\n");
    printer->Print(vars,
      "inline bool $classname$_Parse(\n"
      "    const ::std::string& name, $classname$* value) {\n"
      "  return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
      "    $classname$_descriptor(), name, value);\n"
      "}\n");
  }
}

void EnumGenerator::
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
  printer->Print(
      "template <> struct is_proto_enum< $classname$> : ::std::true_type "
      "{};\n",
      "classname", ClassName(descriptor_, true));
  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(
      "template <>\n"
      "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
      "  return $classname$_descriptor();\n"
      "}\n",
      "classname", ClassName(descriptor_, true));
  }
}

void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
  std::map<string, string> vars;
  vars["nested_name"] = descriptor_->name();
  vars["classname"] = classname_;
  vars["constexpr"] = options_.proto_h ? "constexpr " : "";
  vars["{"] = "";
  vars["}"] = "";
  printer->Print(vars, "typedef $classname$ $nested_name$;\n");

  for (int j = 0; j < descriptor_->value_count(); j++) {
    vars["tag"] = EnumValueName(descriptor_->value(j));
    vars["deprecated_attr"] = descriptor_->value(j)->options().deprecated() ?
      "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : "";
    printer->Print(vars,
      "$deprecated_attr$static $constexpr$const $nested_name$ ${$$tag$$}$ =\n"
      "  $classname$_$tag$;\n");
    printer->Annotate("{", "}", descriptor_->value(j));
  }

  printer->Print(vars,
    "static inline bool $nested_name$_IsValid(int value) {\n"
    "  return $classname$_IsValid(value);\n"
    "}\n"
    "static const $nested_name$ ${$$nested_name$_MIN$}$ =\n"
    "  $classname$_$nested_name$_MIN;\n");
  printer->Annotate("{", "}", descriptor_);
  printer->Print(vars,
    "static const $nested_name$ ${$$nested_name$_MAX$}$ =\n"
    "  $classname$_$nested_name$_MAX;\n");
  printer->Annotate("{", "}", descriptor_);
  if (generate_array_size_) {
    printer->Print(vars,
      "static const int ${$$nested_name$_ARRAYSIZE$}$ =\n"
      "  $classname$_$nested_name$_ARRAYSIZE;\n");
    printer->Annotate("{", "}", descriptor_);
  }

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(vars,
      "static inline const ::google::protobuf::EnumDescriptor*\n"
      "$nested_name$_descriptor() {\n"
      "  return $classname$_descriptor();\n"
      "}\n");
    printer->Print(vars,
                   "static inline const ::std::string& "
                   "$nested_name$_Name($nested_name$ value) {"
                   "\n"
                   "  return $classname$_Name(value);\n"
                   "}\n");
    printer->Print(vars,
      "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
      "    $nested_name$* value) {\n"
      "  return $classname$_Parse(name, value);\n"
      "}\n");
  }
}

void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
  std::map<string, string> vars;
  vars["classname"] = classname_;
  vars["index_in_metadata"] = SimpleItoa(idx);
  vars["constexpr"] = options_.proto_h ? "constexpr " : "";
  vars["file_namespace"] = FileLevelNamespace(descriptor_->file()->name());

  if (HasDescriptorMethods(descriptor_->file(), options_)) {
    printer->Print(
        vars,
        "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
        "  $file_namespace$::protobuf_AssignDescriptorsOnce();\n"
        "  return "
        "$file_namespace$::file_level_enum_descriptors[$index_in_metadata$];\n"
        "}\n");
  }

  printer->Print(vars,
    "bool $classname$_IsValid(int value) {\n"
    "  switch (value) {\n");

  // Multiple values may have the same number.  Make sure we only cover
  // each number once by first constructing a set containing all valid
  // numbers, then printing a case statement for each element.

  std::set<int> numbers;
  for (int j = 0; j < descriptor_->value_count(); j++) {
    const EnumValueDescriptor* value = descriptor_->value(j);
    numbers.insert(value->number());
  }

  for (std::set<int>::iterator iter = numbers.begin();
       iter != numbers.end(); ++iter) {
    printer->Print(
      "    case $number$:\n",
      "number", Int32ToString(*iter));
  }

  printer->Print(vars,
    "      return true;\n"
    "    default:\n"
    "      return false;\n"
    "  }\n"
    "}\n"
    "\n");

  if (descriptor_->containing_type() != NULL) {
    // We need to "define" the static constants which were declared in the
    // header, to give the linker a place to put them.  Or at least the C++
    // standard says we have to.  MSVC actually insists that we do _not_ define
    // them again in the .cc file, prior to VC++ 2015.
    printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");

    vars["parent"] = ClassName(descriptor_->containing_type(), false);
    vars["nested_name"] = descriptor_->name();
    for (int i = 0; i < descriptor_->value_count(); i++) {
      vars["value"] = EnumValueName(descriptor_->value(i));
      printer->Print(vars,
        "$constexpr$const $classname$ $parent$::$value$;\n");
    }
    printer->Print(vars,
      "const $classname$ $parent$::$nested_name$_MIN;\n"
      "const $classname$ $parent$::$nested_name$_MAX;\n");
    if (generate_array_size_) {
      printer->Print(vars,
        "const int $parent$::$nested_name$_ARRAYSIZE;\n");
    }

    printer->Print("#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900\n");
  }
}

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