//===--- ProtocolInfo.h - Abstract protocol witness layout ------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines types for representing the abstract layout of a
// protocol.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_PROTOCOLINFO_H
#define SWIFT_IRGEN_PROTOCOLINFO_H

#include "swift/AST/Decl.h"

#include "ValueWitness.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"

namespace swift {
  class CanType;
  class Decl;
  class ProtocolConformance;
  class ProtocolDecl;

namespace irgen {
  class ConformanceInfo; // private to GenProto.cpp
  class IRGenModule;
  class TypeInfo;

/// A class which encapsulates an index into a witness table.
class WitnessIndex {
  unsigned Value : 31;
  unsigned IsPrefix : 1;
public:
  WitnessIndex() = default;
  WitnessIndex(ValueWitness index) : Value(unsigned(index)) {}
  explicit WitnessIndex(unsigned index, bool isPrefix)
    : Value(index), IsPrefix(isPrefix) {}

  unsigned getValue() const { return Value; }

  bool isPrefix() const { return IsPrefix; }
};

/// A witness to a specific element of a protocol.  Every
/// ProtocolTypeInfo stores one of these for each declaration in the
/// protocol.
/// 
/// The structure of a witness varies by the type of declaration:
///   - a function requires a single witness, the function;
///   - a variable requires two witnesses, a getter and a setter;
///   - a subscript requires two witnesses, a getter and a setter;
///   - a type requires a pointer to the metadata for that type and
///     to witness tables for each of the protocols it obeys.
class WitnessTableEntry {
  Decl *Member;
  WitnessIndex BeginIndex;

 WitnessTableEntry(Decl *member, WitnessIndex begin)
   : Member(member), BeginIndex(begin) {}

public:
  WitnessTableEntry() = default;

  Decl *getMember() const {
    return Member;
  }

  static WitnessTableEntry forPrefixBase(ProtocolDecl *proto) {
    return WitnessTableEntry(proto, WitnessIndex(0, /*isPrefix=*/ true));
  }

  static WitnessTableEntry forOutOfLineBase(ProtocolDecl *proto,
                                            WitnessIndex index) {
    return WitnessTableEntry(proto, index);
  }

  /// Is this a base-protocol entry?
  bool isBase() const { return isa<ProtocolDecl>(Member); }

  /// Is the table for this base-protocol entry "out of line",
  /// i.e. there is a witness which indirectly points to it, or is
  /// it a prefix of the layout of this protocol?
  bool isOutOfLineBase() const {
    assert(isBase());
    return !BeginIndex.isPrefix();
  }

  /// Return the index at which to find the table for this
  /// base-protocol entry.
  WitnessIndex getOutOfLineBaseIndex() const {
    assert(isOutOfLineBase());
    return BeginIndex;
  }

  static WitnessTableEntry forFunction(AbstractFunctionDecl *func,
                                       WitnessIndex index) {
    return WitnessTableEntry(func, index);
  }
  
  bool isFunction() const { return isa<AbstractFunctionDecl>(Member); }

  WitnessIndex getFunctionIndex() const {
    assert(isFunction());
    return BeginIndex;
  }
  
  static WitnessTableEntry forAssociatedType(AssociatedTypeDecl *ty,
                                             WitnessIndex index) {
    return WitnessTableEntry(ty, index);
  }
  
  bool isAssociatedType() const { return isa<AssociatedTypeDecl>(Member); }
  
  WitnessIndex getAssociatedTypeIndex() const {
    assert(isAssociatedType());
    return BeginIndex;
  }

  WitnessIndex
  getAssociatedTypeWitnessTableIndex(ProtocolDecl *target) const {
    assert(!BeginIndex.isPrefix());
    auto index = BeginIndex.getValue() + 1;
    for (auto protocol :
           cast<AssociatedTypeDecl>(Member)->getConformingProtocols()) {
      if (protocol == target) {
        return WitnessIndex(index, false);
      }
      index++;
    }
    llvm_unreachable("protocol not in direct conformance list?");
  }
};

/// An abstract description of a protocol.
class ProtocolInfo final :
    private llvm::TrailingObjects<ProtocolInfo, WitnessTableEntry> {
  friend TrailingObjects;

  /// A singly-linked-list of all the protocols that have been laid out.
  const ProtocolInfo *NextConverted;
  friend class TypeConverter;

  /// The number of witnesses in the protocol.
  unsigned NumWitnesses;

  /// The number of table entries in this protocol layout.
  unsigned NumTableEntries;

  /// A table of all the conformances we've needed so far for this
  /// protocol.  We expect this to be quite small for most protocols.
  mutable llvm::SmallDenseMap<const ProtocolConformance*, ConformanceInfo*, 2>
    Conformances;

  ProtocolInfo(unsigned numWitnesses, ArrayRef<WitnessTableEntry> table)
    : NumWitnesses(numWitnesses), NumTableEntries(table.size()) {
    std::uninitialized_copy(table.begin(), table.end(),
                            getTrailingObjects<WitnessTableEntry>());
  }

  static ProtocolInfo *create(unsigned numWitnesses,
                              ArrayRef<WitnessTableEntry> table);

public:
  const ConformanceInfo &getConformance(IRGenModule &IGM,
                                        ProtocolDecl *protocol,
                                        const ProtocolConformance *conf) const;

  /// The number of witness slots in a conformance to this protocol;
  /// in other words, the size of the table in words.
  unsigned getNumWitnesses() const {
    return NumWitnesses;
  }

  ArrayRef<WitnessTableEntry> getWitnessEntries() const {
    return {getTrailingObjects<WitnessTableEntry>(), NumTableEntries};
  }

  const WitnessTableEntry &getWitnessEntry(Decl *member) const {
    // FIXME: do a binary search if the number of witnesses is large
    // enough.
    for (auto &witness : getWitnessEntries())
      if (witness.getMember() == member)
        return witness;
    llvm_unreachable("didn't find entry for member!");
  }

  ~ProtocolInfo();
};

} // end namespace irgen
} // end namespace swift

#endif
