//===--- Mirror.swift -----------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// FIXME: ExistentialCollection needs to be supported before this will work
// without the ObjC Runtime.

/// Representation of the sub-structure and optional "display style"
/// of any arbitrary subject instance.
///
/// Describes the parts---such as stored properties, collection
/// elements, tuple elements, or the active enumeration case---that
/// make up a particular instance.  May also supply a "display style"
/// property that suggests how this structure might be rendered.
///
/// Mirrors are used by playgrounds and the debugger.
public struct Mirror {
  /// Representation of descendant classes that don't override
  /// `customMirror`.
  ///
  /// Note that the effect of this setting goes no deeper than the
  /// nearest descendant class that overrides `customMirror`, which
  /// in turn can determine representation of *its* descendants.
  internal enum _DefaultDescendantRepresentation {
    /// Generate a default mirror for descendant classes that don't
    /// override `customMirror`.
    ///
    /// This case is the default.
    case generated

    /// Suppress the representation of descendant classes that don't
    /// override `customMirror`.
    ///
    /// This option may be useful at the root of a class cluster, where
    /// implementation details of descendants should generally not be
    /// visible to clients.
    case suppressed
  }

  /// Representation of ancestor classes.
  ///
  /// A `CustomReflectable` class can control how its mirror will
  /// represent ancestor classes by initializing the mirror with a
  /// `AncestorRepresentation`.  This setting has no effect on mirrors
  /// reflecting value type instances.
  public enum AncestorRepresentation {

    /// Generate a default mirror for all ancestor classes.
    ///
    /// This case is the default.
    ///
    /// - Note: This option generates default mirrors even for
    ///   ancestor classes that may implement `CustomReflectable`'s
    ///   `customMirror` requirement.  To avoid dropping an ancestor class
    ///   customization, an override of `customMirror` should pass
    ///   `ancestorRepresentation: .Customized(super.customMirror)` when
    ///   initializing its `Mirror`.
    case generated

    /// Use the nearest ancestor's implementation of `customMirror` to
    /// create a mirror for that ancestor.  Other classes derived from
    /// such an ancestor are given a default mirror.
    ///
    /// The payload for this option should always be
    /// "`{ super.customMirror }`":
    ///
    ///     var customMirror: Mirror {
    ///       return Mirror(
    ///         self,
    ///         children: ["someProperty": self.someProperty],
    ///         ancestorRepresentation: .Customized({ super.customMirror })) // <==
    ///     }
    case customized(() -> Mirror)

    /// Suppress the representation of all ancestor classes.  The
    /// resulting `Mirror`'s `superclassMirror` is `nil`.
    case suppressed
  }

  /// Reflect upon the given `subject`.
  ///
  /// If the dynamic type of `subject` conforms to `CustomReflectable`,
  /// the resulting mirror is determined by its `customMirror` property.
  /// Otherwise, the result is generated by the language.
  ///
  /// - Note: If the dynamic type of `subject` has value semantics,
  ///   subsequent mutations of `subject` will not observable in
  ///   `Mirror`.  In general, though, the observability of such
  /// mutations is unspecified.
  public init(reflecting subject: Any) {
    if case let customized as CustomReflectable = subject {
      self = customized.customMirror
    } else {
      self = Mirror(
        legacy: _reflect(subject),
        subjectType: type(of: subject))
    }
  }

  /// An element of the reflected instance's structure.  The optional
  /// `label` may be used when appropriate, e.g. to represent the name
  /// of a stored property or of an active `enum` case, and will be
  /// used for lookup when `String`s are passed to the `descendant`
  /// method.
  public typealias Child = (label: String?, value: Any)

  /// The type used to represent sub-structure.
  ///
  /// Depending on your needs, you may find it useful to "upgrade"
  /// instances of this type to `AnyBidirectionalCollection` or
  /// `AnyRandomAccessCollection`.  For example, to display the last
  /// 20 children of a mirror if they can be accessed efficiently, you
  /// might write:
  ///
  ///     if let b = AnyBidirectionalCollection(someMirror.children) {
  ///       var i = xs.index(b.endIndex, offsetBy: -20,
  ///         limitedBy: b.startIndex) ?? b.startIndex
  ///       while i != xs.endIndex {
  ///          print(b[i])
  ///          b.formIndex(after: &i)
  ///       }
  ///     }
  public typealias Children = AnyCollection<Child>

  /// A suggestion of how a `Mirror`'s `subject` is to be interpreted.
  ///
  /// Playgrounds and the debugger will show a representation similar
  /// to the one used for instances of the kind indicated by the
  /// `DisplayStyle` case name when the `Mirror` is used for display.
  public enum DisplayStyle {
    case `struct`, `class`, `enum`, tuple, optional, collection
    case dictionary, `set`
  }

  static func _noSuperclassMirror() -> Mirror? { return nil }

  /// Returns the legacy mirror representing the part of `subject`
  /// corresponding to the superclass of `staticSubclass`.
  internal static func _legacyMirror(
    _ subject: AnyObject, asClass targetSuperclass: AnyClass) -> _Mirror? {
    
    // get a legacy mirror and the most-derived type
    var cls: AnyClass = type(of: subject)
    var clsMirror = _reflect(subject)

    // Walk up the chain of mirrors/classes until we find staticSubclass
    while let superclass: AnyClass = _getSuperclass(cls) {
      guard let superclassMirror = clsMirror._superMirror() else { break }
      
      if superclass == targetSuperclass { return superclassMirror }
      
      clsMirror = superclassMirror
      cls = superclass
    }
    return nil
  }

  @_semantics("optimize.sil.specialize.generic.never")
  @inline(never)
  @_versioned
  internal static func _superclassIterator<Subject>(
    _ subject: Subject, _ ancestorRepresentation: AncestorRepresentation
  ) -> () -> Mirror? {

    if let subjectClass = Subject.self as? AnyClass,
       let superclass = _getSuperclass(subjectClass) {

      switch ancestorRepresentation {
      case .generated:
        return {
          self._legacyMirror(_unsafeDowncastToAnyObject(fromAny: subject), asClass: superclass).map {
            Mirror(legacy: $0, subjectType: superclass)
          }
        }
      case .customized(let makeAncestor):
        return {
          Mirror(_unsafeDowncastToAnyObject(fromAny: subject), subjectClass: superclass,
                 ancestor: makeAncestor())
        }
      case .suppressed:
        break
      }
    }
    return Mirror._noSuperclassMirror
  }
  
  /// Represent `subject` with structure described by `children`,
  /// using an optional `displayStyle`.
  ///
  /// If `subject` is not a class instance, `ancestorRepresentation`
  /// is ignored.  Otherwise, `ancestorRepresentation` determines
  /// whether ancestor classes will be represented and whether their
  /// `customMirror` implementations will be used.  By default, a
  /// representation is automatically generated and any `customMirror`
  /// implementation is bypassed.  To prevent bypassing customized
  /// ancestors, `customMirror` overrides should initialize the
  /// `Mirror` with:
  ///
  ///     ancestorRepresentation: .customized({ super.customMirror })
  ///
  /// - Note: The traversal protocol modeled by `children`'s indices
  ///   (`ForwardIndex`, `BidirectionalIndex`, or
  ///   `RandomAccessIndex`) is captured so that the resulting
  /// `Mirror`'s `children` may be upgraded later.  See the failable
  /// initializers of `AnyBidirectionalCollection` and
  /// `AnyRandomAccessCollection` for details.
  public init<Subject, C : Collection>(
    _ subject: Subject,
    children: C,
    displayStyle: DisplayStyle? = nil,
    ancestorRepresentation: AncestorRepresentation = .generated
  ) where C.Element == Child 
  // FIXME(ABI) (Revert Where Clauses): Remove these 
  , C.SubSequence : Collection, C.SubSequence.Indices : Collection, C.Indices : Collection
  {

    self.subjectType = Subject.self
    self._makeSuperclassMirror = Mirror._superclassIterator(
      subject, ancestorRepresentation)
      
    self.children = Children(children)
    self.displayStyle = displayStyle
    self._defaultDescendantRepresentation
      = subject is CustomLeafReflectable ? .suppressed : .generated
  }

  /// Represent `subject` with child values given by
  /// `unlabeledChildren`, using an optional `displayStyle`.  The
  /// result's child labels will all be `nil`.
  ///
  /// This initializer is especially useful for the mirrors of
  /// collections, e.g.:
  ///
  ///     extension MyArray : CustomReflectable {
  ///       var customMirror: Mirror {
  ///         return Mirror(self, unlabeledChildren: self, displayStyle: .collection)
  ///       }
  ///     }
  ///
  /// If `subject` is not a class instance, `ancestorRepresentation`
  /// is ignored.  Otherwise, `ancestorRepresentation` determines
  /// whether ancestor classes will be represented and whether their
  /// `customMirror` implementations will be used.  By default, a
  /// representation is automatically generated and any `customMirror`
  /// implementation is bypassed.  To prevent bypassing customized
  /// ancestors, `customMirror` overrides should initialize the
  /// `Mirror` with:
  ///
  ///     ancestorRepresentation: .Customized({ super.customMirror })
  ///
  /// - Note: The traversal protocol modeled by `children`'s indices
  ///   (`ForwardIndex`, `BidirectionalIndex`, or
  ///   `RandomAccessIndex`) is captured so that the resulting
  /// `Mirror`'s `children` may be upgraded later.  See the failable
  /// initializers of `AnyBidirectionalCollection` and
  /// `AnyRandomAccessCollection` for details.
  public init<Subject, C : Collection>(
    _ subject: Subject,
    unlabeledChildren: C,
    displayStyle: DisplayStyle? = nil,
    ancestorRepresentation: AncestorRepresentation = .generated
  ) 
  // FIXME(ABI) (Revert Where Clauses): Remove these two clauses
  where C.SubSequence : Collection, C.Indices : Collection
  {

    self.subjectType = Subject.self
    self._makeSuperclassMirror = Mirror._superclassIterator(
      subject, ancestorRepresentation)
      
    let lazyChildren =
      unlabeledChildren.lazy.map { Child(label: nil, value: $0) }
    self.children = Children(lazyChildren)

    self.displayStyle = displayStyle
    self._defaultDescendantRepresentation
      = subject is CustomLeafReflectable ? .suppressed : .generated
  }

  /// Represent `subject` with labeled structure described by
  /// `children`, using an optional `displayStyle`.
  ///
  /// Pass a dictionary literal with `String` keys as `children`.  Be
  /// aware that although an *actual* `Dictionary` is
  /// arbitrarily-ordered, the ordering of the `Mirror`'s `children`
  /// will exactly match that of the literal you pass.
  ///
  /// If `subject` is not a class instance, `ancestorRepresentation`
  /// is ignored.  Otherwise, `ancestorRepresentation` determines
  /// whether ancestor classes will be represented and whether their
  /// `customMirror` implementations will be used.  By default, a
  /// representation is automatically generated and any `customMirror`
  /// implementation is bypassed.  To prevent bypassing customized
  /// ancestors, `customMirror` overrides should initialize the
  /// `Mirror` with:
  ///
  ///     ancestorRepresentation: .customized({ super.customMirror })
  ///
  /// - Note: The resulting `Mirror`'s `children` may be upgraded to
  ///   `AnyRandomAccessCollection` later.  See the failable
  ///   initializers of `AnyBidirectionalCollection` and
  /// `AnyRandomAccessCollection` for details.
  public init<Subject>(
    _ subject: Subject,
    children: DictionaryLiteral<String, Any>,
    displayStyle: DisplayStyle? = nil,
    ancestorRepresentation: AncestorRepresentation = .generated
  ) {
    self.subjectType = Subject.self
    self._makeSuperclassMirror = Mirror._superclassIterator(
      subject, ancestorRepresentation)
      
    let lazyChildren = children.lazy.map { Child(label: $0.0, value: $0.1) }
    self.children = Children(lazyChildren)

    self.displayStyle = displayStyle
    self._defaultDescendantRepresentation
      = subject is CustomLeafReflectable ? .suppressed : .generated
  }

  /// The static type of the subject being reflected.
  ///
  /// This type may differ from the subject's dynamic type when `self`
  /// is the `superclassMirror` of another mirror.
  public let subjectType: Any.Type

  /// A collection of `Child` elements describing the structure of the
  /// reflected subject.
  public let children: Children

  /// Suggests a display style for the reflected subject.
  public let displayStyle: DisplayStyle?

  public var superclassMirror: Mirror? {
    return _makeSuperclassMirror()
  }

  internal let _makeSuperclassMirror: () -> Mirror?
  internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation
}

/// A type that explicitly supplies its own mirror.
///
/// You can create a mirror for any type using the `Mirror(reflect:)`
/// initializer, but if you are not satisfied with the mirror supplied for
/// your type by default, you can make it conform to `CustomReflectable` and
/// return a custom `Mirror` instance.
public protocol CustomReflectable {
  /// The custom mirror for this instance.
  ///
  /// If this type has value semantics, the mirror should be unaffected by
  /// subsequent mutations of the instance.
  var customMirror: Mirror { get }
}

/// A type that explicitly supplies its own mirror, but whose
/// descendant classes are not represented in the mirror unless they
/// also override `customMirror`.
public protocol CustomLeafReflectable : CustomReflectable {}

//===--- Addressing -------------------------------------------------------===//

/// A protocol for legitimate arguments to `Mirror`'s `descendant`
/// method.
///
/// Do not declare new conformances to this protocol; they will not
/// work as expected.
// FIXME(ABI)#49 (Sealed Protocols): this protocol should be "non-open" and you shouldn't be able to
// create conformances.
public protocol MirrorPath {}
extension Int : MirrorPath {}
extension String : MirrorPath {}

extension Mirror {
  internal struct _Dummy : CustomReflectable {
    var mirror: Mirror
    var customMirror: Mirror { return mirror }
  }

  /// Return a specific descendant of the reflected subject, or `nil`
  /// Returns a specific descendant of the reflected subject, or `nil`
  /// if no such descendant exists.
  ///
  /// A `String` argument selects the first `Child` with a matching label.
  /// An integer argument *n* select the *n*th `Child`.  For example:
  ///
  ///     var d = Mirror(reflecting: x).descendant(1, "two", 3)
  ///
  /// is equivalent to:
  ///
  ///     var d = nil
  ///     let children = Mirror(reflecting: x).children
  ///     if let p0 = children.index(children.startIndex,
  ///       offsetBy: 1, limitedBy: children.endIndex) {
  ///       let grandChildren = Mirror(reflecting: children[p0].value).children
  ///       SeekTwo: for g in grandChildren {
  ///         if g.label == "two" {
  ///           let greatGrandChildren = Mirror(reflecting: g.value).children
  ///           if let p1 = greatGrandChildren.index(
  ///             greatGrandChildren.startIndex,
  ///             offsetBy: 3, limitedBy: greatGrandChildren.endIndex) {
  ///             d = greatGrandChildren[p1].value
  ///           }
  ///           break SeekTwo
  ///         }
  ///       }
  ///     }
  ///
  /// As you can see, complexity for each element of the argument list
  /// depends on the argument type and capabilities of the collection
  /// used to initialize the corresponding subject's parent's mirror.
  /// Each `String` argument results in a linear search.  In short,
  /// this function is suitable for exploring the structure of a
  /// `Mirror` in a REPL or playground, but don't expect it to be
  /// efficient.
  public func descendant(
    _ first: MirrorPath, _ rest: MirrorPath...
  ) -> Any? {
    var result: Any = _Dummy(mirror: self)
    for e in [first] + rest {
      let children = Mirror(reflecting: result).children
      let position: Children.Index
      if case let label as String = e {
        position = children.index { $0.label == label } ?? children.endIndex
      }
      else if let offset = (e as? Int).map({ IntMax($0) }) ?? (e as? IntMax) {
        position = children.index(children.startIndex,
          offsetBy: offset,
          limitedBy: children.endIndex) ?? children.endIndex
      }
      else {
        _preconditionFailure(
          "Someone added a conformance to MirrorPath; that privilege is reserved to the standard library")
      }
      if position == children.endIndex { return nil }
      result = children[position].value
    }
    return result
  }
}

//===--- Legacy _Mirror Support -------------------------------------------===//
extension Mirror.DisplayStyle {
  /// Construct from a legacy `_MirrorDisposition`
  internal init?(legacy: _MirrorDisposition) {
    switch legacy {
    case .`struct`: self = .`struct`
    case .`class`: self = .`class`
    case .`enum`: self = .`enum`
    case .tuple: self = .tuple
    case .aggregate: return nil
    case .indexContainer: self = .collection
    case .keyContainer: self = .dictionary
    case .membershipContainer: self = .`set`
    case .container: preconditionFailure("unused!")
    case .optional: self = .optional
    case .objCObject: self = .`class`
    }
  }
}

internal func _isClassSuperMirror(_ t: Any.Type) -> Bool {
#if  _runtime(_ObjC)
  return t == _ClassSuperMirror.self || t == _ObjCSuperMirror.self
#else
  return t == _ClassSuperMirror.self
#endif
}

extension _Mirror {
  internal func _superMirror() -> _Mirror? {
    if self.count > 0 {
      let childMirror = self[0].1
      if _isClassSuperMirror(type(of: childMirror)) {
        return childMirror
      }
    }
    return nil
  }
}

/// When constructed using the legacy reflection infrastructure, the
/// resulting `Mirror`'s `children` collection will always be
/// upgradable to `AnyRandomAccessCollection` even if it doesn't
/// exhibit appropriate performance. To avoid this pitfall, convert
/// mirrors to use the new style, which only present forward
/// traversal in general.
internal extension Mirror {
  /// An adapter that represents a legacy `_Mirror`'s children as
  /// a `Collection` with integer `Index`.  Note that the performance
  /// characteristics of the underlying `_Mirror` may not be
  /// appropriate for random access!  To avoid this pitfall, convert
  /// mirrors to use the new style, which only present forward
  /// traversal in general.
  internal struct LegacyChildren : RandomAccessCollection {
    typealias Indices = CountableRange<Int>
    
    init(_ oldMirror: _Mirror) {
      self._oldMirror = oldMirror
    }

    var startIndex: Int {
      return _oldMirror._superMirror() == nil ? 0 : 1
    }

    var endIndex: Int { return _oldMirror.count }

    subscript(position: Int) -> Child {
      let (label, childMirror) = _oldMirror[position]
      return (label: label, value: childMirror.value)
    }

    internal let _oldMirror: _Mirror
  }

  /// Initialize for a view of `subject` as `subjectClass`.
  ///
  /// - parameter ancestor: A Mirror for a (non-strict) ancestor of
  ///   `subjectClass`, to be injected into the resulting hierarchy.
  ///
  /// - parameter legacy: Either `nil`, or a legacy mirror for `subject`
  ///    as `subjectClass`.
  internal init(
    _ subject: AnyObject,
    subjectClass: AnyClass,
    ancestor: Mirror,
    legacy legacyMirror: _Mirror? = nil
  ) {
    if ancestor.subjectType == subjectClass
      || ancestor._defaultDescendantRepresentation == .suppressed {
      self = ancestor
    }
    else {
      let legacyMirror = legacyMirror ?? Mirror._legacyMirror(
        subject, asClass: subjectClass)!
      
      self = Mirror(
        legacy: legacyMirror,
        subjectType: subjectClass,
        makeSuperclassMirror: {
          _getSuperclass(subjectClass).map {
            Mirror(
              subject,
              subjectClass: $0,
              ancestor: ancestor,
              legacy: legacyMirror._superMirror())
          }
        })
    }
  }

  internal init(
    legacy legacyMirror: _Mirror,
    subjectType: Any.Type,
    makeSuperclassMirror: (() -> Mirror?)? = nil
  ) {
    if let makeSuperclassMirror = makeSuperclassMirror {
      self._makeSuperclassMirror = makeSuperclassMirror
    }
    else if let subjectSuperclass = _getSuperclass(subjectType) {
      self._makeSuperclassMirror = {
        legacyMirror._superMirror().map {
          Mirror(legacy: $0, subjectType: subjectSuperclass) }
      }
    }
    else {
      self._makeSuperclassMirror = Mirror._noSuperclassMirror
    }
    self.subjectType = subjectType
    self.children = Children(LegacyChildren(legacyMirror))
    self.displayStyle = DisplayStyle(legacy: legacyMirror.disposition)
    self._defaultDescendantRepresentation = .generated
  }
}

//===--- QuickLooks -------------------------------------------------------===//

/// The sum of types that can be used as a Quick Look representation.
public enum PlaygroundQuickLook {
  /// Plain text.
  case text(String)

  /// An integer numeric value.
  case int(Int64)

  /// An unsigned integer numeric value.
  case uInt(UInt64)

  /// A single precision floating-point numeric value.
  case float(Float32)

  /// A double precision floating-point numeric value.
  case double(Float64)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// An image.
  case image(Any)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// A sound.
  case sound(Any)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// A color.
  case color(Any)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// A bezier path.
  case bezierPath(Any)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// An attributed string.
  case attributedString(Any)

  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
  /// A rectangle.
  case rectangle(Float64, Float64, Float64, Float64)

  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
  /// A point.
  case point(Float64, Float64)

  // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type.
  /// A size.
  case size(Float64, Float64)

  /// A boolean value.
  case bool(Bool)

  // FIXME: Uses explicit values to avoid coupling a particular Cocoa type.
  /// A range.
  case range(Int64, Int64)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// A GUI view.
  case view(Any)

  // FIXME: Uses an Any to avoid coupling a particular Cocoa type.
  /// A graphical sprite.
  case sprite(Any)

  /// A Uniform Resource Locator.
  case url(String)

  /// Raw data that has already been encoded in a format the IDE understands.
  case _raw([UInt8], String)
}

extension PlaygroundQuickLook {
  /// Initialize for the given `subject`.
  ///
  /// If the dynamic type of `subject` conforms to
  /// `CustomPlaygroundQuickLookable`, returns the result of calling
  /// its `customPlaygroundQuickLook` property.  Otherwise, returns
  /// a `PlaygroundQuickLook` synthesized for `subject` by the
  /// language.  Note that in some cases the result may be
  /// `.Text(String(reflecting: subject))`.
  ///
  /// - Note: If the dynamic type of `subject` has value semantics,
  ///   subsequent mutations of `subject` will not observable in
  ///   `Mirror`.  In general, though, the observability of such
  ///   mutations is unspecified.
  public init(reflecting subject: Any) {
    if let customized = subject as? CustomPlaygroundQuickLookable {
      self = customized.customPlaygroundQuickLook
    }
    else if let customized = subject as? _DefaultCustomPlaygroundQuickLookable {
      self = customized._defaultCustomPlaygroundQuickLook
    }
    else {
      if let q = _reflect(subject).quickLookObject {
        self = q
      }
      else {
        self = .text(String(reflecting: subject))
      }
    }
  }
}

/// A type that explicitly supplies its own playground Quick Look.
///
/// A Quick Look can be created for an instance of any type by using the
/// `PlaygroundQuickLook(reflecting:)` initializer. If you are not satisfied
/// with the representation supplied for your type by default, you can make it
/// conform to the `CustomPlaygroundQuickLookable` protocol and provide a
/// custom `PlaygroundQuickLook` instance.
public protocol CustomPlaygroundQuickLookable {
  /// A custom playground Quick Look for this instance.
  ///
  /// If this type has value semantics, the `PlaygroundQuickLook` instance
  /// should be unaffected by subsequent mutations.
  var customPlaygroundQuickLook: PlaygroundQuickLook { get }
}


// A workaround for <rdar://problem/26182650>
// FIXME(ABI)#50 (Dynamic Dispatch for Class Extensions) though not if it moves out of stdlib.
public protocol _DefaultCustomPlaygroundQuickLookable {
  var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { get }
}

//===--- General Utilities ------------------------------------------------===//
// This component could stand alone, but is used in Mirror's public interface.

/// A lightweight collection of key-value pairs.
///
/// Use a `DictionaryLiteral` instance when you need an ordered collection of
/// key-value pairs and don't require the fast key lookup that the
/// `Dictionary` type provides. Unlike key-value pairs in a true dictionary,
/// neither the key nor the value of a `DictionaryLiteral` instance must
/// conform to the `Hashable` protocol.
///
/// You initialize a `DictionaryLiteral` instance using a Swift dictionary
/// literal. Besides maintaining the order of the original dictionary literal,
/// `DictionaryLiteral` also allows duplicates keys. For example:
///
///     let recordTimes: DictionaryLiteral = ["Florence Griffith-Joyner": 10.49,
///                                           "Evelyn Ashford": 10.76,
///                                           "Evelyn Ashford": 10.79,
///                                           "Marlies Gohr": 10.81]
///     print(recordTimes.first!)
///     // Prints "("Florence Griffith-Joyner", 10.49)"
///
/// Some operations that are efficient on a dictionary are slower when using
/// `DictionaryLiteral`. In particular, to find the value matching a key, you
/// must search through every element of the collection. The call to
/// `index(where:)` in the following example must traverse the whole
/// collection to find the element that matches the predicate:
///
///     let runner = "Marlies Gohr"
///     if let index = recordTimes.index(where: { $0.0 == runner }) {
///         let time = recordTimes[index].1
///         print("\(runner) set a 100m record of \(time) seconds.")
///     } else {
///         print("\(runner) couldn't be found in the records.")
///     }
///     // Prints "Marlies Gohr set a 100m record of 10.81 seconds."
///
/// Dictionary Literals as Function Parameters
/// ------------------------------------------
///
/// When calling a function with a `DictionaryLiteral` parameter, you can pass
/// a Swift dictionary literal without causing a `Dictionary` to be created.
/// This capability can be especially important when the order of elements in
/// the literal is significant.
///
/// For example, you could create an `IntPairs` structure that holds a list of
/// two-integer tuples and use an initializer that accepts a
/// `DictionaryLiteral` instance.
///
///     struct IntPairs {
///         var elements: [(Int, Int)]
///
///         init(_ elements: DictionaryLiteral<Int, Int>) {
///             self.elements = Array(elements)
///         }
///     }
///
/// When you're ready to create a new `IntPairs` instance, use a dictionary
/// literal as the parameter to the `IntPairs` initializer. The
/// `DictionaryLiteral` instance preserves the order of the elements as
/// passed.
///
///     let pairs = IntPairs([1: 2, 1: 1, 3: 4, 2: 1])
///     print(pairs.elements)
///     // Prints "[(1, 2), (1, 1), (3, 4), (2, 1)]"
public struct DictionaryLiteral<Key, Value> : ExpressibleByDictionaryLiteral {
  /// Creates a new `DictionaryLiteral` instance from the given dictionary
  /// literal.
  ///
  /// The order of the key-value pairs is kept intact in the resulting
  /// `DictionaryLiteral` instance.
  public init(dictionaryLiteral elements: (Key, Value)...) {
    self._elements = elements
  }
  internal let _elements: [(Key, Value)]
}

/// `Collection` conformance that allows `DictionaryLiteral` to
/// interoperate with the rest of the standard library.
extension DictionaryLiteral : RandomAccessCollection {
  public typealias Indices = CountableRange<Int>
  
  /// The position of the first element in a nonempty collection.
  ///
  /// If the `DictionaryLiteral` instance is empty, `startIndex` is equal to
  /// `endIndex`.
  public var startIndex: Int { return 0 }

  /// The collection's "past the end" position---that is, the position one
  /// greater than the last valid subscript argument.
  ///
  /// If the `DictionaryLiteral` instance is empty, `endIndex` is equal to
  /// `startIndex`.
  public var endIndex: Int { return _elements.endIndex }

  // FIXME(ABI)#174 (Type checker): a typealias is needed to prevent <rdar://20248032>
  /// The element type of a `DictionaryLiteral`: a tuple containing an
  /// individual key-value pair.
  public typealias Element = (key: Key, value: Value)

  /// Accesses the element at the specified position.
  ///
  /// - Parameter position: The position of the element to access. `position`
  ///   must be a valid index of the collection that is not equal to the
  ///   `endIndex` property.
  /// - Returns: The key-value pair at position `position`.
  public subscript(position: Int) -> Element {
    return _elements[position]
  }
}

extension String {
  /// Creates a string representing the given value.
  ///
  /// Use this initializer to convert an instance of any type to its preferred
  /// representation as a `String` instance. The initializer creates the
  /// string representation of `instance` in one of the following ways,
  /// depending on its protocol conformance:
  ///
  /// - If `instance` conforms to the `TextOutputStreamable` protocol, the
  ///   result is obtained by calling `instance.write(to: s)` on an empty
  ///   string `s`.
  /// - If `instance` conforms to the `CustomStringConvertible` protocol, the
  ///   result is `instance.description`.
  /// - If `instance` conforms to the `CustomDebugStringConvertible` protocol,
  ///   the result is `instance.debugDescription`.
  /// - An unspecified result is supplied automatically by the Swift standard
  ///   library.
  ///
  /// For example, this custom `Point` struct uses the default representation
  /// supplied by the standard library.
  ///
  ///     struct Point {
  ///         let x: Int, y: Int
  ///     }
  ///
  ///     let p = Point(x: 21, y: 30)
  ///     print(String(describing: p))
  ///     // Prints "Point(x: 21, y: 30)"
  ///
  /// After adding `CustomStringConvertible` conformance by implementing the
  /// `description` property, `Point` provides its own custom representation.
  ///
  ///     extension Point: CustomStringConvertible {
  ///         var description: String {
  ///             return "(\(x), \(y))"
  ///         }
  ///     }
  ///
  ///     print(String(describing: p))
  ///     // Prints "(21, 30)"
  public init<Subject>(describing instance: Subject) {
    self.init()
    _print_unlocked(instance, &self)
  }

  /// Creates a string with a detailed representation of the given value,
  /// suitable for debugging.
  ///
  /// Use this initializer to convert an instance of any type to its custom
  /// debugging representation. The initializer creates the string
  /// representation of `instance` in one of the following ways, depending on
  /// its protocol conformance:
  ///
  /// - If `subject` conforms to the `CustomDebugStringConvertible` protocol,
  ///   the result is `subject.debugDescription`.
  /// - If `subject` conforms to the `CustomStringConvertible` protocol, the
  ///   result is `subject.description`.
  /// - If `subject` conforms to the `TextOutputStreamable` protocol, the
  ///   result is obtained by calling `subject.write(to: s)` on an empty
  ///   string `s`.
  /// - An unspecified result is supplied automatically by the Swift standard
  ///   library.
  ///
  /// For example, this custom `Point` struct uses the default representation
  /// supplied by the standard library.
  ///
  ///     struct Point {
  ///         let x: Int, y: Int
  ///     }
  ///
  ///     let p = Point(x: 21, y: 30)
  ///     print(String(reflecting: p))
  ///     // Prints "p: Point = {
  ///     //           x = 21
  ///     //           y = 30
  ///     //         }"
  ///
  /// After adding `CustomDebugStringConvertible` conformance by implementing
  /// the `debugDescription` property, `Point` provides its own custom
  /// debugging representation.
  ///
  ///     extension Point: CustomDebugStringConvertible {
  ///         var debugDescription: String {
  ///             return "Point(x: \(x), y: \(y))"
  ///         }
  ///     }
  ///
  ///     print(String(reflecting: p))
  ///     // Prints "Point(x: 21, y: 30)"
  public init<Subject>(reflecting subject: Subject) {
    self.init()
    _debugPrint_unlocked(subject, &self)
  }
}

/// Reflection for `Mirror` itself.
extension Mirror : CustomStringConvertible {
  public var description: String {
    return "Mirror for \(self.subjectType)"
  }
}

extension Mirror : CustomReflectable {
  public var customMirror: Mirror {
    return Mirror(self, children: [:])
  }
}

@available(*, unavailable, renamed: "MirrorPath")
public typealias MirrorPathType = MirrorPath
