//===-- ValueObjectDynamicValue.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/ValueObjectDynamicValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"

#include <cstring>
#include <optional>
namespace lldb_private {
class Declaration;
}

using namespace lldb_private;

ValueObjectDynamicValue::ValueObjectDynamicValue(
    ValueObject &parent, lldb::DynamicValueType use_dynamic)
    : ValueObject(parent), m_address(), m_dynamic_type_info(),
      m_use_dynamic(use_dynamic) {
  SetName(parent.GetName());
}

CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasType())
      return m_value.GetCompilerType();
    else
      return m_parent->GetCompilerType();
  }
  return m_parent->GetCompilerType();
}

ConstString ValueObjectDynamicValue::GetTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetTypeName();
}

TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_type_impl.IsValid()) {
    return m_type_impl;
  }
  return m_parent->GetTypeImpl();
}

ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetQualifiedTypeName();
}

ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
  const bool success = UpdateValueIfNeeded(false);
  if (success) {
    if (m_dynamic_type_info.HasType())
      return GetCompilerType().GetDisplayTypeName();
    if (m_dynamic_type_info.HasName())
      return m_dynamic_type_info.GetName();
  }
  return m_parent->GetDisplayTypeName();
}

llvm::Expected<uint32_t>
ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_dynamic_type_info.HasType()) {
    ExecutionContext exe_ctx(GetExecutionContextRef());
    auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
    if (!children_count)
      return children_count;
    return *children_count <= max ? *children_count : max;
  } else
    return m_parent->GetNumChildren(max);
}

std::optional<uint64_t> ValueObjectDynamicValue::GetByteSize() {
  const bool success = UpdateValueIfNeeded(false);
  if (success && m_dynamic_type_info.HasType()) {
    ExecutionContext exe_ctx(GetExecutionContextRef());
    return m_value.GetValueByteSize(nullptr, &exe_ctx);
  } else
    return m_parent->GetByteSize();
}

lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
  return m_parent->GetValueType();
}

bool ValueObjectDynamicValue::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  if (!m_parent->UpdateValueIfNeeded(false)) {
    // The dynamic value failed to get an error, pass the error along
    if (m_error.Success() && m_parent->GetError().Fail())
      m_error = m_parent->GetError().Clone();
    return false;
  }

  // Setting our type_sp to NULL will route everything back through our parent
  // which is equivalent to not using dynamic values.
  if (m_use_dynamic == lldb::eNoDynamicValues) {
    m_dynamic_type_info.Clear();
    return true;
  }

  ExecutionContext exe_ctx(GetExecutionContextRef());
  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
    m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
  }

  // First make sure our Type and/or Address haven't changed:
  Process *process = exe_ctx.GetProcessPtr();
  if (!process)
    return false;

  TypeAndOrName class_type_or_name;
  Address dynamic_address;
  bool found_dynamic_type = false;
  Value::ValueType value_type;

  LanguageRuntime *runtime = nullptr;

  lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
  if (known_type != lldb::eLanguageTypeUnknown &&
      known_type != lldb::eLanguageTypeC) {
    runtime = process->GetLanguageRuntime(known_type);
    if (auto *preferred_runtime =
            runtime->GetPreferredLanguageRuntime(*m_parent)) {
      // Try the preferred runtime first.
      found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);
      if (found_dynamic_type)
        // Set the operative `runtime` for later use in this function.
        runtime = preferred_runtime;
    }
    if (!found_dynamic_type)
      // Fallback to the runtime for `known_type`.
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);
  } else {
    runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
    if (runtime)
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);

    if (!found_dynamic_type) {
      runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
      if (runtime)
        found_dynamic_type = runtime->GetDynamicTypeAndAddress(
            *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
            value_type);
    }
  }

  // Getting the dynamic value may have run the program a bit, and so marked us
  // as needing updating, but we really don't...

  m_update_point.SetUpdated();

  if (runtime && found_dynamic_type) {
    if (class_type_or_name.HasType()) {
      m_type_impl =
          TypeImpl(m_parent->GetCompilerType(),
                   runtime->FixUpDynamicType(class_type_or_name, *m_parent)
                       .GetCompilerType());
    } else {
      m_type_impl.Clear();
    }
  } else {
    m_type_impl.Clear();
  }

  // If we don't have a dynamic type, set ourselves to be invalid and return
  // false.  We used to try to produce a dynamic ValueObject that behaved "like"
  // its parent, but that failed for ValueObjectConstResult, which is too 
  // complex a beast to try to emulate.  If we return an invalid ValueObject,
  // clients will end up getting the static value instead, which behaves
  // correctly.
  if (!found_dynamic_type) {
    if (m_dynamic_type_info)
      SetValueDidChange(true);
    ClearDynamicTypeInformation();
    m_dynamic_type_info.Clear();
    m_error = Status::FromErrorString("no dynamic type found");
    return false;
  }

  Value old_value(m_value);

  Log *log = GetLog(LLDBLog::Types);

  bool has_changed_type = false;

  if (!m_dynamic_type_info) {
    m_dynamic_type_info = class_type_or_name;
    has_changed_type = true;
  } else if (class_type_or_name != m_dynamic_type_info) {
    // We are another type, we need to tear down our children...
    m_dynamic_type_info = class_type_or_name;
    SetValueDidChange(true);
    has_changed_type = true;
  }

  if (has_changed_type)
    ClearDynamicTypeInformation();

  if (!m_address.IsValid() || m_address != dynamic_address) {
    if (m_address.IsValid())
      SetValueDidChange(true);

    // We've moved, so we should be fine...
    m_address = dynamic_address;
    lldb::TargetSP target_sp(GetTargetSP());
    lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
    m_value.GetScalar() = load_address;
  }

  if (runtime)
    m_dynamic_type_info =
        runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);

  m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());

  m_value.SetValueType(value_type);

  if (has_changed_type && log)
    LLDB_LOGF(log, "[%s %p] has a new dynamic type %s", GetName().GetCString(),
              static_cast<void *>(this), GetTypeName().GetCString());

  if (m_address.IsValid() && m_dynamic_type_info) {
    // The variable value is in the Scalar value inside the m_value. We can
    // point our m_data right to it.
    m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
    if (m_error.Success()) {
      if (!CanProvideValue()) {
        // this value object represents an aggregate type whose children have
        // values, but this object does not. So we say we are changed if our
        // location has changed.
        SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
                          m_value.GetScalar() != old_value.GetScalar());
      }

      SetValueIsValid(true);
      return true;
    }
  }

  // We get here if we've failed above...
  SetValueIsValid(false);
  return false;
}

bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }

bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
                                                  Status &error) {
  if (!UpdateValueIfNeeded(false)) {
    error = Status::FromErrorString("unable to read value");
    return false;
  }

  uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
  uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

  if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
    error = Status::FromErrorString("unable to read value");
    return false;
  }

  // if we are at an offset from our parent, in order to set ourselves
  // correctly we would need to change the new value so that it refers to the
  // correct dynamic type. we choose not to deal with that - if anything more
  // than a value overwrite is required, you should be using the expression
  // parser instead of the value editing facility
  if (my_value != parent_value) {
    // but NULL'ing out a value should always be allowed
    if (strcmp(value_str, "0")) {
      error = Status::FromErrorString(
          "unable to modify dynamic value, use 'expression' command");
      return false;
    }
  }

  bool ret_val = m_parent->SetValueFromCString(value_str, error);
  SetNeedsUpdate();
  return ret_val;
}

bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) {
  if (!UpdateValueIfNeeded(false)) {
    error = Status::FromErrorString("unable to read value");
    return false;
  }

  uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
  uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);

  if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
    error = Status::FromErrorString("unable to read value");
    return false;
  }

  // if we are at an offset from our parent, in order to set ourselves
  // correctly we would need to change the new value so that it refers to the
  // correct dynamic type. we choose not to deal with that - if anything more
  // than a value overwrite is required, you should be using the expression
  // parser instead of the value editing facility
  if (my_value != parent_value) {
    // but NULL'ing out a value should always be allowed
    lldb::offset_t offset = 0;

    if (data.GetAddress(&offset) != 0) {
      error = Status::FromErrorString(
          "unable to modify dynamic value, use 'expression' command");
      return false;
    }
  }

  bool ret_val = m_parent->SetData(data, error);
  SetNeedsUpdate();
  return ret_val;
}

void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
    lldb::LanguageType lang) {
  this->ValueObject::SetPreferredDisplayLanguage(lang);
  if (m_parent)
    m_parent->SetPreferredDisplayLanguage(lang);
}

lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
  if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
    if (m_parent)
      return m_parent->GetPreferredDisplayLanguage();
    return lldb::eLanguageTypeUnknown;
  } else
    return m_preferred_display_language;
}

bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
  if (m_parent)
    return m_parent->IsSyntheticChildrenGenerated();
  return false;
}

void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
  if (m_parent)
    m_parent->SetSyntheticChildrenGenerated(b);
  this->ValueObject::SetSyntheticChildrenGenerated(b);
}

bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
  if (m_parent)
    return m_parent->GetDeclaration(decl);

  return ValueObject::GetDeclaration(decl);
}

uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
  if (m_parent)
    return m_parent->GetLanguageFlags();
  return this->ValueObject::GetLanguageFlags();
}

void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
  if (m_parent)
    m_parent->SetLanguageFlags(flags);
  else
    this->ValueObject::SetLanguageFlags(flags);
}
