//===-- JavaASTContext.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <sstream>

#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/JavaASTContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Stream.h"

#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h"

using namespace lldb;
using namespace lldb_private;

namespace lldb_private {

class JavaASTContext::JavaType {
public:
  enum LLVMCastKind {
    eKindPrimitive,
    eKindObject,
    eKindReference,
    eKindArray,
    kNumKinds
  };

  JavaType(LLVMCastKind kind) : m_kind(kind) {}

  virtual ~JavaType() = default;

  virtual ConstString GetName() = 0;

  virtual void Dump(Stream *s) = 0;

  virtual bool IsCompleteType() = 0;

  LLVMCastKind getKind() const { return m_kind; }

private:
  LLVMCastKind m_kind;
};

} // end of namespace lldb_private

namespace {

class JavaPrimitiveType : public JavaASTContext::JavaType {
public:
  enum TypeKind {
    eTypeByte,
    eTypeShort,
    eTypeInt,
    eTypeLong,
    eTypeFloat,
    eTypeDouble,
    eTypeBoolean,
    eTypeChar,
  };

  JavaPrimitiveType(TypeKind type_kind)
      : JavaType(JavaType::eKindPrimitive), m_type_kind(type_kind) {}

  ConstString GetName() override {
    switch (m_type_kind) {
    case eTypeByte:
      return ConstString("byte");
    case eTypeShort:
      return ConstString("short");
    case eTypeInt:
      return ConstString("int");
    case eTypeLong:
      return ConstString("long");
    case eTypeFloat:
      return ConstString("float");
    case eTypeDouble:
      return ConstString("double");
    case eTypeBoolean:
      return ConstString("boolean");
    case eTypeChar:
      return ConstString("char");
    }
    return ConstString();
  }

  TypeKind GetTypeKind() { return m_type_kind; }

  void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); }

  bool IsCompleteType() override { return true; }

  static bool classof(const JavaType *jt) {
    return jt->getKind() == JavaType::eKindPrimitive;
  }

private:
  const TypeKind m_type_kind;
};

class JavaDynamicType : public JavaASTContext::JavaType {
public:
  JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name)
      : JavaType(kind), m_linkage_name(linkage_name),
        m_dynamic_type_id(nullptr) {}

  ConstString GetLinkageName() const { return m_linkage_name; }

  void SetDynamicTypeId(const DWARFExpression &type_id) {
    m_dynamic_type_id = type_id;
  }

  uint64_t CalculateDynamicTypeId(ExecutionContext *exe_ctx,
                                  ValueObject &value_obj) {
    if (!m_dynamic_type_id.IsValid())
      return UINT64_MAX;

    Value obj_load_address = value_obj.GetValue();
    obj_load_address.ResolveValue(exe_ctx);
    obj_load_address.SetValueType(Value::eValueTypeLoadAddress);

    Value result;
    if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(),
                                   nullptr, nullptr, 0, &obj_load_address,
                                   nullptr, result, nullptr)) {
      Status error;

      lldb::addr_t type_id_addr = result.GetScalar().UInt();
      lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
      if (process_sp)
        return process_sp->ReadUnsignedIntegerFromMemory(
            type_id_addr, process_sp->GetAddressByteSize(), UINT64_MAX, error);
    }

    return UINT64_MAX;
  }

public:
  ConstString m_linkage_name;
  DWARFExpression m_dynamic_type_id;
};

class JavaObjectType : public JavaDynamicType {
public:
  struct Field {
    ConstString m_name;
    CompilerType m_type;
    uint32_t m_offset;
  };

  JavaObjectType(const ConstString &name, const ConstString &linkage_name,
                 uint32_t byte_size)
      : JavaDynamicType(JavaType::eKindObject, linkage_name), m_name(name),
        m_byte_size(byte_size), m_base_class_offset(0), m_is_complete(false) {}

  ConstString GetName() override { return m_name; }

  uint32_t GetByteSize() const { return m_byte_size; }

  uint32_t GetNumFields() { return m_fields.size(); }

  void Dump(Stream *s) override {
    if (m_base_class.IsValid())
      s->Printf("%s : %s\n", GetName().GetCString(),
                m_base_class.GetTypeName().GetCString());
    else
      s->Printf("%s\n", GetName().GetCString());

    s->IndentMore();
    for (const Field &f : m_fields)
      s->Printf("%s %s\n", f.m_type.GetTypeName().GetCString(),
                f.m_name.GetCString());
    s->IndentLess();
  }

  Field *GetFieldAtIndex(size_t idx) {
    if (idx < m_fields.size())
      return &m_fields[idx];
    return nullptr;
  }

  CompilerType GetBaseClass() { return m_base_class; }

  uint32_t GetBaseClassOffset() { return m_base_class_offset; }

  uint32_t GetNumInterfaces() { return m_interfaces.size(); }

  CompilerType GetInterfaceAtIndex(uint32_t idx) {
    if (m_interfaces.size() < idx)
      return m_interfaces[idx];
    return CompilerType();
  }

  bool IsCompleteType() override { return m_is_complete; }

  void SetCompleteType(bool is_complete) {
    m_is_complete = is_complete;
    if (m_byte_size == 0) {
      // Try to calcualte the size of the object based on it's values
      for (const Field &field : m_fields) {
        uint32_t field_end = field.m_offset + field.m_type.GetByteSize(nullptr);
        if (field_end > m_byte_size)
          m_byte_size = field_end;
      }
    }
  }

  void AddBaseClass(const CompilerType &type, uint32_t offset) {
    // TODO: Check if type is an interface and add it to the interface list in
    // that case
    m_base_class = type;
    m_base_class_offset = offset;
  }

  void AddField(const ConstString &name, const CompilerType &type,
                uint32_t offset) {
    m_fields.push_back({name, type, offset});
  }

  static bool classof(const JavaType *jt) {
    return jt->getKind() == JavaType::eKindObject;
  }

private:
  ConstString m_name;
  uint32_t m_byte_size;
  CompilerType m_base_class;
  uint32_t m_base_class_offset;
  std::vector<CompilerType> m_interfaces;
  std::vector<Field> m_fields;
  bool m_is_complete;
};

class JavaReferenceType : public JavaASTContext::JavaType {
public:
  JavaReferenceType(CompilerType pointee_type)
      : JavaType(JavaType::eKindReference), m_pointee_type(pointee_type) {}

  static bool classof(const JavaType *jt) {
    return jt->getKind() == JavaType::eKindReference;
  }

  CompilerType GetPointeeType() { return m_pointee_type; }

  ConstString GetName() override {
    ConstString pointee_type_name =
        static_cast<JavaType *>(GetPointeeType().GetOpaqueQualType())
            ->GetName();
    return ConstString(std::string(pointee_type_name.AsCString()) + "&");
  }

  void Dump(Stream *s) override {
    static_cast<JavaType *>(m_pointee_type.GetOpaqueQualType())->Dump(s);
  }

  bool IsCompleteType() override { return m_pointee_type.IsCompleteType(); }

private:
  CompilerType m_pointee_type;
};

class JavaArrayType : public JavaDynamicType {
public:
  JavaArrayType(const ConstString &linkage_name, CompilerType element_type,
                const DWARFExpression &length_expression,
                lldb::addr_t data_offset)
      : JavaDynamicType(JavaType::eKindArray, linkage_name),
        m_element_type(element_type), m_length_expression(length_expression),
        m_data_offset(data_offset) {}

  static bool classof(const JavaType *jt) {
    return jt->getKind() == JavaType::eKindArray;
  }

  CompilerType GetElementType() { return m_element_type; }

  ConstString GetName() override {
    ConstString element_type_name =
        static_cast<JavaType *>(GetElementType().GetOpaqueQualType())
            ->GetName();
    return ConstString(std::string(element_type_name.AsCString()) + "[]");
  }

  void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); }

  bool IsCompleteType() override { return m_length_expression.IsValid(); }

  uint32_t GetNumElements(ValueObject *value_obj) {
    if (!m_length_expression.IsValid())
      return UINT32_MAX;

    Status error;
    ValueObjectSP address_obj = value_obj->AddressOf(error);
    if (error.Fail())
      return UINT32_MAX;

    Value obj_load_address = address_obj->GetValue();
    obj_load_address.SetValueType(Value::eValueTypeLoadAddress);

    Value result;
    ExecutionContextScope *exec_ctx_scope = value_obj->GetExecutionContextRef()
                                                .Lock(true)
                                                .GetBestExecutionContextScope();
    if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0,
                                     nullptr, &obj_load_address, result,
                                     nullptr))
      return result.GetScalar().UInt();

    return UINT32_MAX;
  }

  uint64_t GetElementOffset(size_t idx) {
    return m_data_offset + idx * m_element_type.GetByteSize(nullptr);
  }

private:
  CompilerType m_element_type;
  DWARFExpression m_length_expression;
  lldb::addr_t m_data_offset;
};

} // end of anonymous namespace

ConstString JavaASTContext::GetPluginNameStatic() {
  return ConstString("java");
}

ConstString JavaASTContext::GetPluginName() {
  return JavaASTContext::GetPluginNameStatic();
}

uint32_t JavaASTContext::GetPluginVersion() { return 1; }

lldb::TypeSystemSP JavaASTContext::CreateInstance(lldb::LanguageType language,
                                                  Module *module,
                                                  Target *target) {
  if (language == eLanguageTypeJava) {
    if (module)
      return std::make_shared<JavaASTContext>(module->GetArchitecture());
    if (target)
      return std::make_shared<JavaASTContext>(target->GetArchitecture());
    assert(false && "Either a module or a target has to be specifed to create "
                    "a JavaASTContext");
  }
  return lldb::TypeSystemSP();
}

void JavaASTContext::EnumerateSupportedLanguages(
    std::set<lldb::LanguageType> &languages_for_types,
    std::set<lldb::LanguageType> &languages_for_expressions) {
  static std::vector<lldb::LanguageType> s_languages_for_types(
      {lldb::eLanguageTypeJava});
  static std::vector<lldb::LanguageType> s_languages_for_expressions({});

  languages_for_types.insert(s_languages_for_types.begin(),
                             s_languages_for_types.end());
  languages_for_expressions.insert(s_languages_for_expressions.begin(),
                                   s_languages_for_expressions.end());
}

void JavaASTContext::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in",
                                CreateInstance, EnumerateSupportedLanguages);
}

void JavaASTContext::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

JavaASTContext::JavaASTContext(const ArchSpec &arch)
    : TypeSystem(eKindJava), m_pointer_byte_size(arch.GetAddressByteSize()) {}

JavaASTContext::~JavaASTContext() {}

uint32_t JavaASTContext::GetPointerByteSize() { return m_pointer_byte_size; }

DWARFASTParser *JavaASTContext::GetDWARFParser() {
  if (!m_dwarf_ast_parser_ap)
    m_dwarf_ast_parser_ap.reset(new DWARFASTParserJava(*this));
  return m_dwarf_ast_parser_ap.get();
}

ConstString JavaASTContext::DeclGetName(void *opaque_decl) {
  return ConstString();
}

std::vector<CompilerDecl> JavaASTContext::DeclContextFindDeclByName(
    void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) {
  return std::vector<CompilerDecl>();
}

bool JavaASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) {
  return false;
}

ConstString JavaASTContext::DeclContextGetName(void *opaque_decl_ctx) {
  return ConstString();
}

bool JavaASTContext::DeclContextIsClassMethod(
    void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
    bool *is_instance_method_ptr, ConstString *language_object_name_ptr) {
  return false;
}

bool JavaASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
                                 CompilerType *element_type, uint64_t *size,
                                 bool *is_incomplete) {
  if (element_type)
    element_type->Clear();
  if (size)
    *size = 0;
  if (is_incomplete)
    *is_incomplete = false;

  if (JavaArrayType *array =
          llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type))) {
    if (element_type)
      *element_type = array->GetElementType();
    return true;
  }
  return false;
}

bool JavaASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
  return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
}

bool JavaASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
    return ptype->GetTypeKind() == JavaPrimitiveType::eTypeChar;
  return false;
}

bool JavaASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
                                         uint32_t &count, bool &is_complex) {
  is_complex = true;

  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeFloat:
    case JavaPrimitiveType::eTypeDouble:
      count = 1;
      return true;
    default:
      break;
    }
  }

  count = 0;
  return false;
}

bool JavaASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
                                    bool *is_variadic_ptr) {
  if (is_variadic_ptr)
    *is_variadic_ptr = false;
  return false;
}

size_t JavaASTContext::GetNumberOfFunctionArguments(
    lldb::opaque_compiler_type_t type) {
  return 0;
}

CompilerType
JavaASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                           const size_t index) {
  return CompilerType();
}

bool JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool JavaASTContext::IsBlockPointerType(
    lldb::opaque_compiler_type_t type,
    CompilerType *function_pointer_type_ptr) {
  return false;
}

bool JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
                                   bool &is_signed) {
  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
    case JavaPrimitiveType::eTypeShort:
    case JavaPrimitiveType::eTypeInt:
    case JavaPrimitiveType::eTypeLong:
      is_signed = true;
      return true;
    default:
      break;
    }
  }

  is_signed = false;
  return false;
}

bool JavaASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
                                           CompilerType *target_type,
                                           bool check_cplusplus,
                                           bool check_objc) {
  return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type));
}

bool JavaASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
                                   CompilerType *pointee_type) {
  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool JavaASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
                                     CompilerType *pointee_type,
                                     bool *is_rvalue) {
  if (is_rvalue)
    *is_rvalue = false;

  if (JavaReferenceType *ref =
          llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type))) {
    if (pointee_type)
      *pointee_type = ref->GetPointeeType();
    return true;
  }

  if (pointee_type)
    pointee_type->Clear();
  return false;
}

bool JavaASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
  return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)) ||
         llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type));
}

bool JavaASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
  return false; // TODO: Implement if we introduce the void type
}

bool JavaASTContext::SupportsLanguage(lldb::LanguageType language) {
  return language == lldb::eLanguageTypeJava;
}

bool JavaASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) {
  return true;
}

bool JavaASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
                                              CompilerType *pointee_type) {
  return IsPointerType(type, pointee_type) ||
         IsReferenceType(type, pointee_type);
}

bool JavaASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
                                   uint32_t &length) {
  return false; // TODO: Implement it if we need it for string literals
}

bool JavaASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool JavaASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
                                  CompilerType *element_type, uint64_t *size) {
  if (element_type)
    element_type->Clear();
  if (size)
    *size = 0;
  return false;
}

bool JavaASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
  return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
}

uint32_t
JavaASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                       CompilerType *base_type_ptr) {
  return false;
}

bool JavaASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
  return static_cast<JavaType *>(type)->IsCompleteType();
}

bool JavaASTContext::IsConst(lldb::opaque_compiler_type_t type) {
  return false;
}

bool JavaASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
  return false;
}

bool JavaASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
  return type != nullptr;
}

bool JavaASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
  if (IsCompleteType(type))
    return true;

  if (JavaArrayType *array =
          llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
    return GetCompleteType(array->GetElementType().GetOpaqueQualType());

  if (JavaReferenceType *reference =
          llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
    return GetCompleteType(reference->GetPointeeType().GetOpaqueQualType());

  if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type))) {
    SymbolFile *symbol_file = GetSymbolFile();
    if (!symbol_file)
      return false;

    CompilerType object_type(this, type);
    return symbol_file->CompleteType(object_type);
  }
  return false;
}

ConstString JavaASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
  if (type)
    return static_cast<JavaType *>(type)->GetName();
  return ConstString();
}

uint32_t
JavaASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
                            CompilerType *pointee_or_element_compiler_type) {
  if (pointee_or_element_compiler_type)
    pointee_or_element_compiler_type->Clear();
  if (!type)
    return 0;

  if (IsReferenceType(type, pointee_or_element_compiler_type))
    return eTypeHasChildren | eTypeHasValue | eTypeIsReference;
  if (IsArrayType(type, pointee_or_element_compiler_type, nullptr, nullptr))
    return eTypeHasChildren | eTypeIsArray;
  if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
    return eTypeHasChildren | eTypeIsClass;

  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
    case JavaPrimitiveType::eTypeShort:
    case JavaPrimitiveType::eTypeInt:
    case JavaPrimitiveType::eTypeLong:
      return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger |
             eTypeIsSigned;
    case JavaPrimitiveType::eTypeFloat:
    case JavaPrimitiveType::eTypeDouble:
      return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsFloat |
             eTypeIsSigned;
    case JavaPrimitiveType::eTypeBoolean:
      return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
    case JavaPrimitiveType::eTypeChar:
      return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
    }
  }
  return 0;
}

lldb::TypeClass
JavaASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
  if (!type)
    return eTypeClassInvalid;
  if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
    return eTypeClassReference;
  if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
    return eTypeClassArray;
  if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
    return eTypeClassClass;
  if (llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type)))
    return eTypeClassBuiltin;
  assert(false && "Java type with unhandled type class");
  return eTypeClassInvalid;
}

lldb::LanguageType
JavaASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
  return lldb::eLanguageTypeJava;
}

CompilerType
JavaASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
                                    uint64_t *stride) {
  if (stride)
    *stride = 0;

  CompilerType element_type;
  if (IsArrayType(type, &element_type, nullptr, nullptr))
    return element_type;
  return CompilerType();
}

CompilerType JavaASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
  CompilerType pointee_type;
  if (IsPointerType(type, &pointee_type))
    return pointee_type;
  return CompilerType();
}

CompilerType JavaASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
  return CompilerType(); // No pointer types in java
}

CompilerType
JavaASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

CompilerType
JavaASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

CompilerType
JavaASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
  CompilerType pointee_type;
  if (IsReferenceType(type, &pointee_type))
    return pointee_type;
  return CompilerType(this, type);
}

CompilerType
JavaASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

CompilerType JavaASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
  return CompilerType();
}

CompilerType
JavaASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                    size_t bit_size) {
  return CompilerType();
}

size_t JavaASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
  return 0;
}

lldb::BasicType
JavaASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
      return eBasicTypeOther;
    case JavaPrimitiveType::eTypeShort:
      return eBasicTypeShort;
    case JavaPrimitiveType::eTypeInt:
      return eBasicTypeInt;
    case JavaPrimitiveType::eTypeLong:
      return eBasicTypeLong;
    case JavaPrimitiveType::eTypeFloat:
      return eBasicTypeFloat;
    case JavaPrimitiveType::eTypeDouble:
      return eBasicTypeDouble;
    case JavaPrimitiveType::eTypeBoolean:
      return eBasicTypeBool;
    case JavaPrimitiveType::eTypeChar:
      return eBasicTypeChar;
    }
  }
  return eBasicTypeInvalid;
}

uint64_t JavaASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
                                    ExecutionContextScope *exe_scope) {
  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
      return 8;
    case JavaPrimitiveType::eTypeShort:
      return 16;
    case JavaPrimitiveType::eTypeInt:
      return 32;
    case JavaPrimitiveType::eTypeLong:
      return 64;
    case JavaPrimitiveType::eTypeFloat:
      return 32;
    case JavaPrimitiveType::eTypeDouble:
      return 64;
    case JavaPrimitiveType::eTypeBoolean:
      return 1;
    case JavaPrimitiveType::eTypeChar:
      return 16;
    }
  } else if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type))) {
    return 32; // References are always 4 byte long in java
  } else if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type))) {
    return 64;
  } else if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
                 static_cast<JavaType *>(type))) {
    return obj->GetByteSize() * 8;
  }
  return 0;
}

lldb::Encoding JavaASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
                                           uint64_t &count) {
  count = 1;

  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
    case JavaPrimitiveType::eTypeShort:
    case JavaPrimitiveType::eTypeInt:
    case JavaPrimitiveType::eTypeLong:
      return eEncodingSint;
    case JavaPrimitiveType::eTypeFloat:
    case JavaPrimitiveType::eTypeDouble:
      return eEncodingIEEE754;
    case JavaPrimitiveType::eTypeBoolean:
    case JavaPrimitiveType::eTypeChar:
      return eEncodingUint;
    }
  }
  if (IsReferenceType(type))
    return eEncodingUint;
  return eEncodingInvalid;
}

lldb::Format JavaASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
  if (JavaPrimitiveType *ptype =
          llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type))) {
    switch (ptype->GetTypeKind()) {
    case JavaPrimitiveType::eTypeByte:
    case JavaPrimitiveType::eTypeShort:
    case JavaPrimitiveType::eTypeInt:
    case JavaPrimitiveType::eTypeLong:
      return eFormatDecimal;
    case JavaPrimitiveType::eTypeFloat:
    case JavaPrimitiveType::eTypeDouble:
      return eFormatFloat;
    case JavaPrimitiveType::eTypeBoolean:
      return eFormatBoolean;
    case JavaPrimitiveType::eTypeChar:
      return eFormatUnicode16;
    }
  }
  if (IsReferenceType(type))
    return eFormatHex;
  return eFormatDefault;
}

unsigned JavaASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
  return 0;
}

size_t
JavaASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                          const char *s, uint8_t *dst,
                                          size_t dst_size) {
  assert(false && "Not implemented");
  return 0;
}

size_t
JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
  return 0;
}

CompilerType
JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type,
                                    size_t idx,
                                    lldb::TemplateArgumentKind &kind) {
  return CompilerType();
}

uint32_t JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);
    return obj->GetNumFields();
  }
  return 0;
}

CompilerType JavaASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
                                             size_t idx, std::string &name,
                                             uint64_t *bit_offset_ptr,
                                             uint32_t *bitfield_bit_size_ptr,
                                             bool *is_bitfield_ptr) {
  if (bit_offset_ptr)
    *bit_offset_ptr = 0;
  if (bitfield_bit_size_ptr)
    *bitfield_bit_size_ptr = 0;
  if (is_bitfield_ptr)
    *is_bitfield_ptr = false;

  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);

    JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
    if (!field)
      return CompilerType();
    name = field->m_name.AsCString();
    if (bit_offset_ptr)
      *bit_offset_ptr = field->m_offset * 8;
    return field->m_type;
  }
  return CompilerType();
}

uint32_t JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
                                        bool omit_empty_base_classes) {
  GetCompleteType(type);

  if (JavaReferenceType *ref =
          llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
    return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes);

  if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
    return GetNumFields(type) + GetNumDirectBaseClasses(type);

  return 0;
}

uint32_t
JavaASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);
    return obj->GetNumInterfaces() + (obj->GetBaseClass() ? 1 : 0);
  }
  return 0;
}

uint32_t
JavaASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);
    return obj->GetNumInterfaces();
  }
  return 0;
}

CompilerType JavaASTContext::GetDirectBaseClassAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);

    if (CompilerType base_class = obj->GetBaseClass()) {
      if (idx == 0)
        return base_class;
      else
        --idx;
    }
    return obj->GetInterfaceAtIndex(idx);
  }
  return CompilerType();
}

CompilerType JavaASTContext::GetVirtualBaseClassAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);
    return obj->GetInterfaceAtIndex(idx);
  }
  return CompilerType();
}

void JavaASTContext::DumpValue(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
    lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset,
    size_t data_byte_size, uint32_t bitfield_bit_size,
    uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
    bool verbose, uint32_t depth) {
  assert(false && "Not implemented");
}

bool JavaASTContext::DumpTypeValue(
    lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
    const DataExtractor &data, lldb::offset_t data_offset,
    size_t data_byte_size, uint32_t bitfield_bit_size,
    uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) {
  if (IsScalarType(type)) {
    return DumpDataExtractor(data, s, data_offset, format, data_byte_size,
                             1, // count
                             UINT32_MAX, LLDB_INVALID_ADDRESS,
                             bitfield_bit_size, bitfield_bit_offset, exe_scope);
  }
  return false;
}

void JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
  StreamFile s(stdout, false);
  DumpTypeDescription(type, &s);
}

void JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
                                         Stream *s) {
  static_cast<JavaType *>(type)->Dump(s);
}

void JavaASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
                                 ExecutionContext *exe_ctx, Stream *s,
                                 const DataExtractor &data,
                                 lldb::offset_t data_offset,
                                 size_t data_byte_size) {
  assert(false && "Not implemented");
}

int JavaASTContext::GetFunctionArgumentCount(
    lldb::opaque_compiler_type_t type) {
  return 0;
}

CompilerType JavaASTContext::GetFunctionArgumentTypeAtIndex(
    lldb::opaque_compiler_type_t type, size_t idx) {
  return CompilerType();
}

CompilerType
JavaASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
  return CompilerType();
}

size_t
JavaASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
  return 0;
}

TypeMemberFunctionImpl
JavaASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                                         size_t idx) {
  return TypeMemberFunctionImpl();
}

CompilerType JavaASTContext::GetChildCompilerTypeAtIndex(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
    bool transparent_pointers, bool omit_empty_base_classes,
    bool ignore_array_bounds, std::string &child_name,
    uint32_t &child_byte_size, int32_t &child_byte_offset,
    uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
    bool &child_is_base_class, bool &child_is_deref_of_parent,
    ValueObject *valobj, uint64_t &language_flags) {
  child_name.clear();
  child_byte_size = 0;
  child_byte_offset = 0;
  child_bitfield_bit_size = 0;
  child_bitfield_bit_offset = 0;
  child_is_base_class = false;
  child_is_deref_of_parent = false;
  language_flags = 0;

  ExecutionContextScope *exec_ctx_scope =
      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;

  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);

    if (CompilerType base_class = obj->GetBaseClass()) {
      if (idx == 0) {
        JavaType *base_class_type =
            static_cast<JavaType *>(base_class.GetOpaqueQualType());
        child_name = base_class_type->GetName().GetCString();
        child_byte_size = base_class.GetByteSize(
            exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
        child_byte_offset = obj->GetBaseClassOffset();
        child_is_base_class = true;
        return base_class;
      }
      idx -= 1;
    }

    JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
    if (!field)
      return CompilerType();

    child_name = field->m_name.AsCString();
    child_byte_size = field->m_type.GetByteSize(exec_ctx_scope);
    child_byte_offset = field->m_offset;
    return field->m_type;
  } else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(
                 static_cast<JavaType *>(type))) {
    CompilerType pointee_type = ref->GetPointeeType();

    if (transparent_pointers)
      return pointee_type.GetChildCompilerTypeAtIndex(
          exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
          child_bitfield_bit_size, child_bitfield_bit_offset,
          child_is_base_class, child_is_deref_of_parent, valobj,
          language_flags);

    if (idx != 0)
      return CompilerType();

    if (valobj && valobj->GetName())
      child_name = valobj->GetName().GetCString();
    child_is_deref_of_parent = true;
    child_byte_offset = 0;
    child_byte_size = pointee_type.GetByteSize(exec_ctx_scope);
    return pointee_type;
  }
  return CompilerType();
}

uint32_t
JavaASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                        const char *name,
                                        bool omit_empty_base_classes) {
  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);

    uint32_t index_offset = 0;
    if (CompilerType base_class = obj->GetBaseClass()) {
      if (base_class.GetTypeName() == ConstString(name))
        return 0;
      index_offset = 1;
    }
    for (uint32_t i = 0; i < obj->GetNumFields(); ++i) {
      if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
        return i + index_offset;
    }
  } else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(
                 static_cast<JavaType *>(type))) {
    return GetIndexOfChildWithName(ref->GetPointeeType().GetOpaqueQualType(),
                                   name, omit_empty_base_classes);
  }
  return UINT_MAX;
}

size_t JavaASTContext::GetIndexOfChildMemberWithName(
    lldb::opaque_compiler_type_t type, const char *name,
    bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
  child_indexes.clear();

  if (JavaObjectType *obj =
          llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type))) {
    GetCompleteType(type);

    uint32_t index_offset = 0;
    if (CompilerType base_class = obj->GetBaseClass()) {
      if (GetIndexOfChildMemberWithName(base_class.GetOpaqueQualType(), name,
                                        omit_empty_base_classes,
                                        child_indexes) != 0) {
        child_indexes.insert(child_indexes.begin(), 0);
        return child_indexes.size();
      }
      index_offset = 1;
    }

    for (uint32_t i = 0; i < obj->GetNumFields(); ++i) {
      if (obj->GetFieldAtIndex(i)->m_name == ConstString(name)) {
        child_indexes.push_back(i + index_offset);
        return child_indexes.size();
      }
    }
  } else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(
                 static_cast<JavaType *>(type))) {
    return GetIndexOfChildMemberWithName(
        ref->GetPointeeType().GetOpaqueQualType(), name,
        omit_empty_base_classes, child_indexes);
  }
  return 0;
}

CompilerType
JavaASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) {
  return CreateReferenceType(CompilerType(this, type));
}

ConstString JavaASTContext::DeclContextGetScopeQualifiedName(
    lldb::opaque_compiler_type_t opaque_decl_ctx) {
  return GetTypeName(opaque_decl_ctx);
}

static void AddPrimitiveType(JavaASTContext::JavaTypeMap &type_map,
                             JavaPrimitiveType::TypeKind type_kind) {
  JavaPrimitiveType *type = new JavaPrimitiveType(type_kind);
  type_map.emplace(type->GetName(),
                   std::unique_ptr<JavaASTContext::JavaType>(type));
}

CompilerType JavaASTContext::CreateBaseType(const ConstString &name) {
  if (m_base_type_map.empty()) {
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeByte);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeShort);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeInt);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeLong);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeFloat);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeDouble);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeBoolean);
    AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeChar);
  }
  auto it = m_base_type_map.find(name);
  if (it != m_base_type_map.end())
    return CompilerType(this, it->second.get());
  return CompilerType();
}

CompilerType JavaASTContext::CreateObjectType(const ConstString &name,
                                              const ConstString &linkage_name,
                                              uint32_t byte_size) {
  auto it = m_object_type_map.find(name);
  if (it == m_object_type_map.end()) {
    std::unique_ptr<JavaType> object_type(
        new JavaObjectType(name, linkage_name, byte_size));
    it = m_object_type_map.emplace(name, std::move(object_type)).first;
  }
  return CompilerType(this, it->second.get());
}

CompilerType JavaASTContext::CreateArrayType(
    const ConstString &linkage_name, const CompilerType &element_type,
    const DWARFExpression &length_expression, const lldb::addr_t data_offset) {
  ConstString name = element_type.GetTypeName();
  auto it = m_array_type_map.find(name);
  if (it == m_array_type_map.end()) {
    std::unique_ptr<JavaType> array_type(new JavaArrayType(
        linkage_name, element_type, length_expression, data_offset));
    it = m_array_type_map.emplace(name, std::move(array_type)).first;
  }
  return CompilerType(this, it->second.get());
}

CompilerType
JavaASTContext::CreateReferenceType(const CompilerType &pointee_type) {
  ConstString name = pointee_type.GetTypeName();
  auto it = m_reference_type_map.find(name);
  if (it == m_reference_type_map.end())
    it = m_reference_type_map
             .emplace(name, std::unique_ptr<JavaType>(
                                new JavaReferenceType(pointee_type)))
             .first;
  return CompilerType(this, it->second.get());
}

void JavaASTContext::CompleteObjectType(const CompilerType &object_type) {
  JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
      static_cast<JavaType *>(object_type.GetOpaqueQualType()));
  assert(obj &&
         "JavaASTContext::CompleteObjectType called with not a JavaObjectType");
  obj->SetCompleteType(true);
}

void JavaASTContext::AddBaseClassToObject(const CompilerType &object_type,
                                          const CompilerType &member_type,
                                          uint32_t member_offset) {
  JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
      static_cast<JavaType *>(object_type.GetOpaqueQualType()));
  assert(obj &&
         "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
  obj->AddBaseClass(member_type, member_offset);
}

void JavaASTContext::AddMemberToObject(const CompilerType &object_type,
                                       const ConstString &name,
                                       const CompilerType &member_type,
                                       uint32_t member_offset) {
  JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
      static_cast<JavaType *>(object_type.GetOpaqueQualType()));
  assert(obj &&
         "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
  obj->AddField(name, member_type, member_offset);
}

void JavaASTContext::SetDynamicTypeId(const CompilerType &type,
                                      const DWARFExpression &type_id) {
  JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
      static_cast<JavaType *>(type.GetOpaqueQualType()));
  assert(obj &&
         "JavaASTContext::SetDynamicTypeId called with not a JavaObjectType");
  obj->SetDynamicTypeId(type_id);
}

uint64_t JavaASTContext::CalculateDynamicTypeId(ExecutionContext *exe_ctx,
                                                const CompilerType &type,
                                                ValueObject &in_value) {
  if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
          static_cast<JavaType *>(type.GetOpaqueQualType())))
    return obj->CalculateDynamicTypeId(exe_ctx, in_value);
  if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(
          static_cast<JavaType *>(type.GetOpaqueQualType())))
    return arr->CalculateDynamicTypeId(exe_ctx, in_value);
  return UINT64_MAX;
}

uint32_t JavaASTContext::CalculateArraySize(const CompilerType &type,
                                            ValueObject &in_value) {
  if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(
          static_cast<JavaType *>(type.GetOpaqueQualType())))
    return arr->GetNumElements(&in_value);
  return UINT32_MAX;
}

uint64_t JavaASTContext::CalculateArrayElementOffset(const CompilerType &type,
                                                     size_t index) {
  if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(
          static_cast<JavaType *>(type.GetOpaqueQualType())))
    return arr->GetElementOffset(index);
  return UINT64_MAX;
}

ConstString JavaASTContext::GetLinkageName(const CompilerType &type) {
  if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(
          static_cast<JavaType *>(type.GetOpaqueQualType())))
    return obj->GetLinkageName();
  return ConstString();
}
