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

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

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


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

namespace {

// Returns the fully-qualified class name of the message that this field
// extends. This function is used in the Google-internal code to handle some
// legacy cases.
string ExtendeeClassName(const FieldDescriptor* descriptor) {
  const Descriptor* extendee = descriptor->containing_type();
  return ClassName(extendee, true);
}

}  // anonymous namespace

ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
                                       const Options& options)
  : descriptor_(descriptor),
    options_(options) {
  // Construct type_traits_.
  if (descriptor_->is_repeated()) {
    type_traits_ = "Repeated";
  }

  switch (descriptor_->cpp_type()) {
    case FieldDescriptor::CPPTYPE_ENUM:
      type_traits_.append("EnumTypeTraits< ");
      type_traits_.append(ClassName(descriptor_->enum_type(), true));
      type_traits_.append(", ");
      type_traits_.append(ClassName(descriptor_->enum_type(), true));
      type_traits_.append("_IsValid>");
      break;
    case FieldDescriptor::CPPTYPE_STRING:
      type_traits_.append("StringTypeTraits");
      break;
    case FieldDescriptor::CPPTYPE_MESSAGE:
      type_traits_.append("MessageTypeTraits< ");
      type_traits_.append(ClassName(descriptor_->message_type(), true));
      type_traits_.append(" >");
      break;
    default:
      type_traits_.append("PrimitiveTypeTraits< ");
      type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
      type_traits_.append(" >");
      break;
  }
}

ExtensionGenerator::~ExtensionGenerator() {}

void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
  std::map<string, string> vars;
  vars["extendee"     ] = ExtendeeClassName(descriptor_);
  vars["number"       ] = SimpleItoa(descriptor_->number());
  vars["type_traits"  ] = type_traits_;
  vars["name"         ] = descriptor_->name();
  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
  vars["constant_name"] = FieldConstantName(descriptor_);

  // If this is a class member, it needs to be declared "static".  Otherwise,
  // it needs to be "extern".  In the latter case, it also needs the DLL
  // export/import specifier.
  if (descriptor_->extension_scope() == NULL) {
    vars["qualifier"] = "extern";
    if (!options_.dllexport_decl.empty()) {
      vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
    }
  } else {
    vars["qualifier"] = "static";
  }

  printer->Print(vars,
    "static const int $constant_name$ = $number$;\n"
    "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
    "  $name$;\n"
    );
}

void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
  // If this is a class member, it needs to be declared in its class scope.
  string scope = (descriptor_->extension_scope() == NULL) ? "" :
    ClassName(descriptor_->extension_scope(), false) + "::";
  string name = scope + descriptor_->name();

  std::map<string, string> vars;
  vars["extendee"     ] = ExtendeeClassName(descriptor_);
  vars["type_traits"  ] = type_traits_;
  vars["name"         ] = name;
  vars["constant_name"] = FieldConstantName(descriptor_);
  vars["default"      ] = DefaultValue(descriptor_);
  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
  vars["scope"        ] = scope;

  if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
    // We need to declare a global string which will contain the default value.
    // We cannot declare it at class scope because that would require exposing
    // it in the header which would be annoying for other reasons.  So we
    // replace :: with _ in the name and declare it as a global.
    string global_name = StringReplace(name, "::", "_", true);
    vars["global_name"] = global_name;
    printer->Print(vars,
      "const ::std::string $global_name$_default($default$);\n");

    // Update the default to refer to the string global.
    vars["default"] = global_name + "_default";
  }

  // Likewise, class members need to declare the field constant variable.
  if (descriptor_->extension_scope() != NULL) {
    printer->Print(vars,
      "#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"
      "const int $scope$$constant_name$;\n"
      "#endif\n");
  }

  printer->Print(vars,
    "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
    "  $name$($constant_name$, $default$);\n");
}

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