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

#include "lldb/DataFormatters/LanguageCategory.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/DataFormatters/TypeCategory.h"
#include "lldb/DataFormatters/TypeFormat.h"
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/Target/Language.h"

using namespace lldb;
using namespace lldb_private;

LanguageCategory::LanguageCategory(lldb::LanguageType lang_type)
    : m_category_sp(), m_hardcoded_formats(), m_hardcoded_summaries(),
      m_hardcoded_synthetics(), m_hardcoded_validators(), m_format_cache(),
      m_enabled(false) {
  if (Language *language_plugin = Language::FindPlugin(lang_type)) {
    m_category_sp = language_plugin->GetFormatters();
    m_hardcoded_formats = language_plugin->GetHardcodedFormats();
    m_hardcoded_summaries = language_plugin->GetHardcodedSummaries();
    m_hardcoded_synthetics = language_plugin->GetHardcodedSynthetics();
    m_hardcoded_validators = language_plugin->GetHardcodedValidators();
  }
  Enable();
}

bool LanguageCategory::Get(FormattersMatchData &match_data,
                           lldb::TypeFormatImplSP &format_sp) {
  if (!m_category_sp)
    return false;

  if (!IsEnabled())
    return false;

  if (match_data.GetTypeForCache()) {
    if (m_format_cache.GetFormat(match_data.GetTypeForCache(), format_sp))
      return format_sp.get() != nullptr;
  }

  ValueObject &valobj(match_data.GetValueObject());
  bool result =
      m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetFormat(match_data.GetTypeForCache(), format_sp);
  }
  return result;
}

bool LanguageCategory::Get(FormattersMatchData &match_data,
                           lldb::TypeSummaryImplSP &format_sp) {
  if (!m_category_sp)
    return false;

  if (!IsEnabled())
    return false;

  if (match_data.GetTypeForCache()) {
    if (m_format_cache.GetSummary(match_data.GetTypeForCache(), format_sp))
      return format_sp.get() != nullptr;
  }

  ValueObject &valobj(match_data.GetValueObject());
  bool result =
      m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetSummary(match_data.GetTypeForCache(), format_sp);
  }
  return result;
}

bool LanguageCategory::Get(FormattersMatchData &match_data,
                           lldb::SyntheticChildrenSP &format_sp) {
  if (!m_category_sp)
    return false;

  if (!IsEnabled())
    return false;

  if (match_data.GetTypeForCache()) {
    if (m_format_cache.GetSynthetic(match_data.GetTypeForCache(), format_sp))
      return format_sp.get() != nullptr;
  }

  ValueObject &valobj(match_data.GetValueObject());
  bool result =
      m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetSynthetic(match_data.GetTypeForCache(), format_sp);
  }
  return result;
}

bool LanguageCategory::Get(FormattersMatchData &match_data,
                           lldb::TypeValidatorImplSP &format_sp) {
  if (!m_category_sp)
    return false;

  if (!IsEnabled())
    return false;

  if (match_data.GetTypeForCache()) {
    if (m_format_cache.GetValidator(match_data.GetTypeForCache(), format_sp))
      return format_sp.get() != nullptr;
  }

  ValueObject &valobj(match_data.GetValueObject());
  bool result =
      m_category_sp->Get(valobj, match_data.GetMatchesVector(), format_sp);
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetValidator(match_data.GetTypeForCache(), format_sp);
  }
  return result;
}

bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
                                    FormattersMatchData &match_data,
                                    lldb::TypeFormatImplSP &format_sp) {
  if (!IsEnabled())
    return false;

  ValueObject &valobj(match_data.GetValueObject());
  lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());

  for (auto &candidate : m_hardcoded_formats) {
    if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
      break;
  }
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetFormat(match_data.GetTypeForCache(), format_sp);
  }
  return format_sp.get() != nullptr;
}

bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
                                    FormattersMatchData &match_data,
                                    lldb::TypeSummaryImplSP &format_sp) {
  if (!IsEnabled())
    return false;

  ValueObject &valobj(match_data.GetValueObject());
  lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());

  for (auto &candidate : m_hardcoded_summaries) {
    if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
      break;
  }
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetSummary(match_data.GetTypeForCache(), format_sp);
  }
  return format_sp.get() != nullptr;
}

bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
                                    FormattersMatchData &match_data,
                                    lldb::SyntheticChildrenSP &format_sp) {
  if (!IsEnabled())
    return false;

  ValueObject &valobj(match_data.GetValueObject());
  lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());

  for (auto &candidate : m_hardcoded_synthetics) {
    if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
      break;
  }
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetSynthetic(match_data.GetTypeForCache(), format_sp);
  }
  return format_sp.get() != nullptr;
}

bool LanguageCategory::GetHardcoded(FormatManager &fmt_mgr,
                                    FormattersMatchData &match_data,
                                    lldb::TypeValidatorImplSP &format_sp) {
  if (!IsEnabled())
    return false;

  ValueObject &valobj(match_data.GetValueObject());
  lldb::DynamicValueType use_dynamic(match_data.GetDynamicValueType());

  for (auto &candidate : m_hardcoded_validators) {
    if ((format_sp = candidate(valobj, use_dynamic, fmt_mgr)))
      break;
  }
  if (match_data.GetTypeForCache() &&
      (!format_sp || !format_sp->NonCacheable())) {
    m_format_cache.SetValidator(match_data.GetTypeForCache(), format_sp);
  }
  return format_sp.get() != nullptr;
}

lldb::TypeCategoryImplSP LanguageCategory::GetCategory() const {
  return m_category_sp;
}

FormatCache &LanguageCategory::GetFormatCache() { return m_format_cache; }

void LanguageCategory::Enable() {
  if (m_category_sp)
    m_category_sp->Enable(true, TypeCategoryMap::Default);
  m_enabled = true;
}

void LanguageCategory::Disable() {
  if (m_category_sp)
    m_category_sp->Disable();
  m_enabled = false;
}

bool LanguageCategory::IsEnabled() { return m_enabled; }
