//===--- MetadataSource.h - Swift Metadata Sources for Reflection ---------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implements a description of a "metadata source": at runtime, emission of
// metadata pointers that you can directly follow may be omitted as an
// optimization, because the compiler knows you can get to metadata by some
// other means. For example, all heap objects have a pointer to some metadata
// describing it, so pointers to class instances can eventually lead to their
// metadata. These nodes describe those kinds of paths to metadata at runtime.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_REFLECTION_METADATASOURCE_H
#define SWIFT_REFLECTION_METADATASOURCE_H

#include "llvm/ADT/Optional.h"
#include "llvm/Support/Casting.h"

using llvm::cast;

#include <climits>
#include <iostream>

namespace swift {
namespace reflection {

enum class MetadataSourceKind {
#define METADATA_SOURCE(Id, Parent) Id,
#include "swift/Reflection/MetadataSources.def"
#undef METADATA_SOURCE
};

class MetadataSource {
  MetadataSourceKind Kind;

  static bool decodeNatural(std::string::const_iterator &it,
                            const std::string::const_iterator &end,
                            unsigned &result) {
    auto begin = it;
    for (; it < end && *it >= '0' && *it <= '9'; ++it)
      ;

    if (std::distance(begin, it) == 0)
      return false;

    long int decoded = std::strtol(&*begin, nullptr, 10);
    if ((decoded == LONG_MAX || decoded == LONG_MIN) && errno == ERANGE)
      return false;

    result = static_cast<unsigned>(decoded);
    return true;
  }

  template <typename Allocator>
  static const MetadataSource *
  decodeClosureBinding(Allocator &A,
                       std::string::const_iterator &it,
                       const std::string::const_iterator &end) {
    if (it == end)
      return nullptr;

    if (*it == 'B')
      ++it;
    else
      return nullptr;

    unsigned Index;
    if (!decodeNatural(it, end, Index))
      return nullptr;
    return A.createClosureBinding(Index);
  }

  template <typename Allocator>
  static const MetadataSource *
  decodeReferenceCapture(Allocator &A,
                         std::string::const_iterator &it,
                         const std::string::const_iterator &end) {
    if (it == end)
      return nullptr;

    if (*it == 'R')
      ++it;
    else
      return nullptr;

    unsigned Index;
    if (!decodeNatural(it, end, Index))
      return nullptr;
    return A.createReferenceCapture(Index);
  }

  template <typename Allocator>
  static const MetadataSource *
  decodeMetadataCapture(Allocator &A,
                        std::string::const_iterator &it,
                        const std::string::const_iterator &end) {
    if (it == end)
      return nullptr;

    if (*it == 'M')
      ++it;
    else
      return nullptr;

    unsigned Index;
    if (!decodeNatural(it, end, Index))
      return nullptr;
    return A.createMetadataCapture(Index);
  }

  template <typename Allocator>
  static const MetadataSource *
  decodeGenericArgument(Allocator &A,
                        std::string::const_iterator &it,
                        const std::string::const_iterator &end) {
    if (it == end)
      return nullptr;

    if (*it == 'G')
      ++it;
    else
      return nullptr;

    unsigned Index;
    if (!decodeNatural(it, end, Index))
      return nullptr;

    auto Source = decode(A, it, end);
    if (!Source)
      return nullptr;

    if (it == end || *it != '_')
      return nullptr;

    ++it;

    return A.createGenericArgument(Index, Source);
  }

  template <typename Allocator>
  static const MetadataSource *decode(Allocator &A,
                                      std::string::const_iterator &it,
                                      const std::string::const_iterator &end) {
    if (it == end) return nullptr;

    switch (*it) {
      case 'B':
        return decodeClosureBinding(A, it, end);
      case 'R':
        return decodeReferenceCapture(A, it, end);
      case 'M':
        return decodeMetadataCapture(A, it, end);
      case 'G':
        return decodeGenericArgument(A, it, end);
      case 'S':
        ++it;
        return A.createSelf();
      default:
        return nullptr;
    }
  }

public:
  MetadataSource(MetadataSourceKind Kind) : Kind(Kind) {}

  MetadataSourceKind getKind() const {
    return Kind;
  }

  void dump() const;
  void dump(std::ostream &OS, unsigned Indent = 0) const;
  template <typename Allocator>
  static const MetadataSource *decode(Allocator &A, const std::string &str) {
    auto begin = str.begin();
    return MetadataSource::decode<Allocator>(A, begin, str.end());
  }

  virtual ~MetadataSource() = default;
};

/// Represents a metadata pointer stashed in the "necessary bindings"
/// structure at the head of a heap closure. These can be followed
/// directly to some instantiated metadata.
class ClosureBindingMetadataSource final : public MetadataSource {
  unsigned Index;

public:

  ClosureBindingMetadataSource(unsigned Index)
    : MetadataSource(MetadataSourceKind::ClosureBinding), Index(Index) {}

  template <typename Allocator>
  static const ClosureBindingMetadataSource *
  create(Allocator &A, unsigned Index) {
    return A.template make_source<ClosureBindingMetadataSource>(Index);
  }

  unsigned getIndex() const {
    return Index;
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::ClosureBinding;
  }
};

/// Represents a capture of a reference to heap object. These can
/// be followed to the heap instance's data, then its metadata pointer.
class ReferenceCaptureMetadataSource final : public MetadataSource {
  unsigned Index;

public:
  ReferenceCaptureMetadataSource(unsigned Index)
    : MetadataSource(MetadataSourceKind::ReferenceCapture), Index(Index) {}

  template <typename Allocator>
  static const ReferenceCaptureMetadataSource *
  create(Allocator &A, unsigned Index) {
    return A.template make_source<ReferenceCaptureMetadataSource>(Index);
  }

  unsigned getIndex() const {
    return Index;
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::ReferenceCapture;
  }
};

/// Represents a capture of a metadata pointer as an argument to a polymorphic function. These are direct sources of metadata.
class MetadataCaptureMetadataSource final : public MetadataSource {
  unsigned Index;

public:
  MetadataCaptureMetadataSource(unsigned Index)
  : MetadataSource(MetadataSourceKind::MetadataCapture), Index(Index) {}

  template <typename Allocator>
  static const MetadataCaptureMetadataSource *
  create(Allocator &A, unsigned Index) {
    return A.template make_source<MetadataCaptureMetadataSource>(Index);
  }

  unsigned getIndex() const {
    return Index;
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::MetadataCapture;
  }
};

/// Represents the nth generic argument in some other source of instantiated
/// metadata.
///
/// If you have a pointer to a class MyClass<T, U>, and you need the metadata
/// for its `T`, you can follow the pointer to the instance data, then its
/// metadata pointer at the start of the instance, and fetch its first
/// generic argument.
class GenericArgumentMetadataSource final : public MetadataSource {
  unsigned Index;
  const MetadataSource *Source;

public:
  GenericArgumentMetadataSource(unsigned Index,
                                const MetadataSource *Source)
    : MetadataSource(MetadataSourceKind::GenericArgument),
      Index(Index),
      Source(Source) {}

  template <typename Allocator>
  static const GenericArgumentMetadataSource *
  create(Allocator &A, unsigned Index, const MetadataSource *Source) {
    return A.template make_source<GenericArgumentMetadataSource>(Index, Source);
  }

  unsigned getIndex() const {
    return Index;
  }

  const MetadataSource *getSource() const {
    return Source;
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::GenericArgument;
  }
};

/// A source of metadata from the Self metadata parameter passed via
/// a witness_method convention function.
class SelfMetadataSource final : public MetadataSource {
public:
  SelfMetadataSource() : MetadataSource(MetadataSourceKind::Self) {}

  template <typename Allocator>
  static const SelfMetadataSource*
  create(Allocator &A) {
    return A.template make_source<SelfMetadataSource>();
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::Self;
  }
};

/// A source of metadata from the Self witness table parameter passed via
/// a witness_method convention function.
class SelfWitnessTableMetadataSource final : public MetadataSource {
public:
  SelfWitnessTableMetadataSource()
    : MetadataSource(MetadataSourceKind::SelfWitnessTable) {}

  template <typename Allocator>
  static const SelfWitnessTableMetadataSource*
  create(Allocator &A) {
    return A.template make_source<SelfWitnessTableMetadataSource>();
  }

  static bool classof(const MetadataSource *MS) {
    return MS->getKind() == MetadataSourceKind::SelfWitnessTable;
  }
};

template <typename ImplClass, typename RetTy = void, typename... Args>
class MetadataSourceVisitor {
public:

  RetTy visit(const MetadataSource *MS, Args... args) {
    switch (MS->getKind()) {
#define METADATA_SOURCE(Id, Parent) \
    case MetadataSourceKind::Id: \
      return static_cast<ImplClass*>(this) \
        ->visit##Id##MetadataSource(cast<Id##MetadataSource>(MS), \
                           ::std::forward<Args>(args)...);
#include "swift/Reflection/MetadataSources.def"
    }
  }
};

} // end namespace reflection
} // end namespace swift

#endif // SWIFT_REFLECTION_METADATASOURCE_H
