// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_

#include "src/developer/debug/zxdb/expr/found_member.h"
#include "src/developer/debug/zxdb/expr/parsed_identifier.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/variable.h"

namespace zxdb {

// This class represents the result of looking up a variable by name. It could be a local or global
// variable (simple Variable* object), or it could be a member of the current implicit object
// ("this" in C++). This class represents either state.
class FoundName {
 public:
  // Since identifiers with template parameters at the end are assumed to be a type, we don't need
  // to check that "std::vector<int>" is a type. This will need to be revisited if we support
  // templatized function names in expressions ("auto a = &MyClass::MyFunc<int>;");
  enum Kind {
    kNone,            // Nothing with this name found.
    kVariable,        // Local and global variables.
    kMemberVariable,  // Class and struct member vars that require an object.
    kNamespace,       // Namespace name like "std".
    kTemplate,        // Template name without parameters like "std::vector".
    kType,            // Full type name like "std::string" or "int".
    kFunction,        // Normal DWARF functions, including inlines.
    kOtherSymbol,     // Any other symbol, including ELF symbols.
  };

  // Default constructor for a "not found" name.
  FoundName();

  // Constructor for templates and namespaces that have no extra data.
  FoundName(Kind kind, ParsedIdentifier name);

  // Takes a reference to the object.
  explicit FoundName(const Variable* variable);
  explicit FoundName(const Function* function);

  // Takes a reference to the object. This will forward to variable/function if the Symbol is of
  // that type, otherwise it will be an "other symbol".
  explicit FoundName(const Symbol* symbol);

  // Constructor for data member variables. The object_ptr may be null if this represents a query on
  // a type with no corresponding variable).
  FoundName(const Variable* object_ptr, FoundMember member);
  FoundName(const Variable* object_ptr, InheritancePath path, const DataMember* data_member);

  // Constructor for types.
  explicit FoundName(fxl::RefPtr<Type> type);

  ~FoundName();

  Kind kind() const { return kind_; }

  // Implicit conversion to bool to test for a found value.
  bool is_found() const { return kind_ != kNone; }
  operator bool() const { return kind_ != kNone; }

  // Abstracts away the kind and returns the full name of the match.
  ParsedIdentifier GetName() const;

  // Use when kind == kVariable and kMemberVariable. The variable may be null for member pointers if
  // the call is just looking up the
  const Variable* variable() const { return variable_.get(); }
  fxl::RefPtr<Variable> variable_ref() { return variable_; }

  // Used when kind == kMemberVariable. The object_ptr() will be valid if there's a variable
  // associated with the member, and will be null otherwise. This won't necessarily be a collection,
  // it could be a "const pointer to a const collection" or some other complex type.
  //
  // See FoundMember for how to resolve the value as there are some subtleties.
  const Variable* object_ptr() const { return object_ptr_.get(); }
  fxl::RefPtr<Variable> object_ptr_ref() const { return object_ptr_; }
  const FoundMember& member() const { return member_; }

  // Valid when kind == kType.
  fxl::RefPtr<Type>& type() { return type_; }
  const fxl::RefPtr<Type>& type() const { return type_; }

  // Valid when kind == kFunction.
  fxl::RefPtr<Function>& function() { return function_; }
  const fxl::RefPtr<Function>& function() const { return function_; }

  // Valid when kind == kOtherSymbol.
  fxl::RefPtr<Symbol>& other_symbol() { return other_symbol_; }
  const fxl::RefPtr<Symbol>& other_symbol() const { return other_symbol_; }

 private:
  Kind kind_ = kNone;

  // Represents the found variable when it's not a class member. When null, the result will be in
  // object_member/data_member.
  fxl::RefPtr<Variable> variable_;

  // Represents the "this" object the data member is associated with it. Non-null when the found
  // variable is a collection member. In this case, data_member and data_member_offset will be
  // valid.
  //
  // This is the outermost object which one would evaluate to get the value of the object pointer
  // rather than the class the data member is declared in (it could be a base class).
  fxl::RefPtr<Variable> object_ptr_;

  // Valid when object_ptr_ is non-null. This indicates the location of the data inside the object.
  FoundMember member_;

  fxl::RefPtr<Type> type_;
  fxl::RefPtr<Function> function_;
  fxl::RefPtr<Symbol> other_symbol_;

  // Valid only when there's no object to hold the intrinsic name. This is for templates and
  // namespaces.
  ParsedIdentifier name_;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_FOUND_NAME_H_
