//===--- SwiftLangSupport.cpp ---------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "SwiftLangSupport.h"
#include "SwiftASTManager.h"
#include "SwiftEditorDiagConsumer.h"
#include "SourceKit/Core/Context.h"
#include "SourceKit/SwiftLang/Factory.h"
#include "SourceKit/Support/FileSystemProvider.h"
#include "SourceKit/Support/UIdent.h"

#include "swift/AST/ASTVisitor.h"
#include "swift/AST/ClangModuleLoader.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/SILOptions.h"
#include "swift/AST/USRGeneration.h"
#include "swift/Config.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/IDE/CodeCompletionCache.h"
#include "swift/IDE/CompletionInstance.h"
#include "swift/IDE/SyntaxModel.h"
#include "swift/IDE/Utils.h"

#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#if !defined(_WIN32)
#include <sys/param.h>
#else
#define WIN32_MEAN_AND_LEAN
#define NOMINMAX
#include <windows.h>
#endif

using namespace SourceKit;
using namespace swift;
using namespace swift::ide;
using swift::index::SymbolKind;
using swift::index::SymbolSubKind;
using swift::index::SymbolProperty;
using swift::index::SymbolPropertySet;
using swift::index::SymbolInfo;
using swift::index::SymbolRole;
using swift::index::SymbolRoleSet;

#define KIND(NAME, CONTENT) static UIdent Kind##NAME(CONTENT);
#include "SourceKit/Core/ProtocolUIDs.def"

#define REFACTORING(KIND, NAME, ID) static UIdent Kind##Refactoring##KIND("source.refactoring.kind."#ID);
#include "swift/IDE/RefactoringKinds.def"

static UIdent Attr_IBAction("source.decl.attribute.ibaction");
static UIdent Attr_IBOutlet("source.decl.attribute.iboutlet");
static UIdent Attr_IBDesignable("source.decl.attribute.ibdesignable");
static UIdent Attr_IBInspectable("source.decl.attribute.ibinspectable");
static UIdent Attr_GKInspectable("source.decl.attribute.gkinspectable");
static UIdent Attr_Objc("source.decl.attribute.objc");
static UIdent Attr_ObjcNamed("source.decl.attribute.objc.name");
static UIdent Attr_Private("source.decl.attribute.private");
static UIdent Attr_FilePrivate("source.decl.attribute.fileprivate");
static UIdent Attr_Internal("source.decl.attribute.internal");
static UIdent Attr_Public("source.decl.attribute.public");
static UIdent Attr_Open("source.decl.attribute.open");
static UIdent Attr_Setter_Private("source.decl.attribute.setter_access.private");
static UIdent Attr_Setter_FilePrivate("source.decl.attribute.setter_access.fileprivate");
static UIdent Attr_Setter_Internal("source.decl.attribute.setter_access.internal");
static UIdent Attr_Setter_Public("source.decl.attribute.setter_access.public");
static UIdent Attr_Setter_Open("source.decl.attribute.setter_access.open");
static UIdent EffectiveAccess_Public("source.decl.effective_access.public");
static UIdent EffectiveAccess_Internal("source.decl.effective_access.internal");
static UIdent EffectiveAccess_FilePrivate("source.decl.effective_access.fileprivate");
static UIdent EffectiveAccess_LessThanFilePrivate("source.decl.effective_access.less_than_fileprivate");

std::unique_ptr<LangSupport>
SourceKit::createSwiftLangSupport(SourceKit::Context &SKCtx) {
  return std::unique_ptr<LangSupport>(new SwiftLangSupport(SKCtx));
}

const std::string LangSupport::SynthesizedUSRSeparator = "::SYNTHESIZED::";

namespace {

class UIdentVisitor : public ASTVisitor<UIdentVisitor,
                                        UIdent, UIdent, UIdent, UIdent > {
  const bool IsRef;

public:
  explicit UIdentVisitor(bool IsRef) : IsRef(IsRef) { }

  /// TODO: reconsider whether having a default case is a good idea.
  UIdent visitDecl(const Decl *D) { return UIdent(); }

  UIdent visitFuncDecl(const FuncDecl *D);
  UIdent visitVarDecl(const VarDecl *D);
  UIdent visitParamDecl(const ParamDecl *D);
  UIdent visitExtensionDecl(const ExtensionDecl *D);

#define UID_FOR(CLASS) \
  UIdent visit##CLASS##Decl(const CLASS##Decl *) { \
    return IsRef ? KindRef##CLASS : KindDecl##CLASS; \
  }
  UID_FOR(Class)
  UID_FOR(Struct)
  UID_FOR(Enum)
  UID_FOR(EnumElement)
  UID_FOR(Protocol)
  UID_FOR(TypeAlias)
  UID_FOR(AssociatedType)
  UID_FOR(GenericTypeParam)
  UID_FOR(Constructor)
  UID_FOR(Destructor)
  UID_FOR(Subscript)
  UID_FOR(OpaqueType)
#undef UID_FOR
};

} // anonymous namespace

UIdent UIdentVisitor::visitFuncDecl(const FuncDecl *D) {
  if (auto AD = dyn_cast<AccessorDecl>(D)) {
    return SwiftLangSupport::getUIDForAccessor(AD->getStorage(),
                                               AD->getAccessorKind(),
                                               IsRef);
  }

  if (auto *Op = D->getOperatorDecl()) {
    switch (Op->getKind()) {
    case DeclKind::PrefixOperator:
      return IsRef ? KindRefFunctionPrefixOperator : KindDeclFunctionPrefixOperator;
    case DeclKind::PostfixOperator:
      return IsRef ? KindRefFunctionPostfixOperator : KindDeclFunctionPostfixOperator;
    case DeclKind::InfixOperator:
      return IsRef ? KindRefFunctionInfixOperator : KindDeclFunctionInfixOperator;
    default:
      llvm_unreachable("unexpected operator kind");
    }
  }

  const DeclContext *DC = D->getDeclContext();
  if (DC->isTypeContext()) {
    if (D->isStatic()) {
      if (D->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
        return IsRef ? KindRefMethodClass : KindDeclMethodClass;
      else
        return IsRef ? KindRefMethodStatic : KindDeclMethodStatic;
    }
    return IsRef ? KindRefMethodInstance : KindDeclMethodInstance;
  }
  return IsRef ? KindRefFunctionFree : KindDeclFunctionFree;
}

UIdent UIdentVisitor::visitVarDecl(const VarDecl *D) {
  const DeclContext *DC = D->getDeclContext();
  if (DC->isTypeContext()) {
    if (D->isStatic()) {
      if (D->getCorrectStaticSpelling() == StaticSpellingKind::KeywordClass)
        return IsRef ? KindRefVarClass : KindDeclVarClass;
      else
        return IsRef ? KindRefVarStatic : KindDeclVarStatic;
    }
    return IsRef ? KindRefVarInstance : KindDeclVarInstance;
  }
  if (DC->isLocalContext())
    return IsRef ? KindRefVarLocal : KindDeclVarLocal;
  return IsRef ? KindRefVarGlobal : KindDeclVarGlobal;
}

UIdent UIdentVisitor::visitParamDecl(const ParamDecl *D) {
  // There is no KindRefVarParam. It's not usually an interesting difference.
  return IsRef ? KindRefVarLocal : KindDeclVarParam;
}

UIdent UIdentVisitor::visitExtensionDecl(const ExtensionDecl *D) {
  assert(!IsRef && "reference to an extension ?");
  if (NominalTypeDecl *NTD = D->getExtendedNominal()) {
    if (isa<StructDecl>(NTD))
      return KindDeclExtensionStruct;
    if (isa<ClassDecl>(NTD))
      return KindDeclExtensionClass;
    if (isa<EnumDecl>(NTD))
      return KindDeclExtensionEnum;
    if (isa<ProtocolDecl>(NTD))
      return KindDeclExtensionProtocol;
  }
  return UIdent();
}

namespace {
/// A simple FileSystemProvider that creates an InMemoryFileSystem for a given
/// dictionary of file contents and overlays that on top of the real filesystem.
class InMemoryFileSystemProvider: public SourceKit::FileSystemProvider {
  /// Provides the real filesystem, overlayed with an InMemoryFileSystem that
  /// contains specified files at specified locations.
  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
  getFileSystem(OptionsDictionary &options, std::string &error) override {
    auto InMemoryFS = llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem>(
        new llvm::vfs::InMemoryFileSystem());

    static UIdent KeyFiles("key.files");
    static UIdent KeyName("key.name");
    static UIdent KeySourceFile("key.sourcefile");
    static UIdent KeySourceText("key.sourcetext");
    bool failed = options.forEach(KeyFiles, [&](OptionsDictionary &file) {
      StringRef name;
      if (!file.valueForOption(KeyName, name)) {
        error = "missing 'key.name'";
        return true;
      }

      StringRef content;
      if (file.valueForOption(KeySourceText, content)) {
        auto buffer = llvm::MemoryBuffer::getMemBufferCopy(content, name);
        InMemoryFS->addFile(name, 0, std::move(buffer));
        return false;
      }

      StringRef mappedPath;
      if (!file.valueForOption(KeySourceFile, mappedPath)) {
        error = "missing 'key.sourcefile' or 'key.sourcetext'";
        return true;
      }

      auto bufferOrErr = llvm::MemoryBuffer::getFile(mappedPath);
      if (auto err = bufferOrErr.getError()) {
        llvm::raw_string_ostream errStream(error);
        errStream << "error reading target file '" << mappedPath
                  << "': " << err.message() << "\n";
        return true;
      }

      auto renamedBuffer = llvm::MemoryBuffer::getMemBufferCopy(
          bufferOrErr.get()->getBuffer(), name);
      InMemoryFS->addFile(name, 0, std::move(renamedBuffer));
      return false;
    });

    if (failed)
      return nullptr;

    auto OverlayFS = llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>(
        new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
    OverlayFS->pushOverlay(std::move(InMemoryFS));
    return OverlayFS;
  }
};

class DirectlyPassedFileSystemProvider : public SourceKit::FileSystemProvider {
public:
  struct Options : public OptionsDictionary {
    const unsigned FSID;

    Options(unsigned FSID) : FSID(FSID) {}

    bool valueForOption(UIdent Key, unsigned &Val) override {
      static UIdent KeyFSID("key.fsid");
      if (Key != KeyFSID)
        return false;
      Val = FSID;
      return true;
    }
    bool valueForOption(UIdent Key, bool &Val) override { return true; }
    bool valueForOption(UIdent Key, StringRef &Val) override { return false; }
    bool
    forEach(UIdent key,
            llvm::function_ref<bool(OptionsDictionary &)> applier) override {
      return false;
    }
  };

  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
  getFileSystem(OptionsDictionary &options, std::string &error) override {
    llvm::sys::ScopedLock L(mtx);
    static UIdent KeyFSID("key.fsid");
    unsigned FSID;
    if (!options.valueForOption(KeyFSID, FSID)) {
      error = "'key.fsid' not specified";
      return nullptr;
    }

    auto result = FileSystems.find(FSID);
    if (result == FileSystems.end()) {
      error = "filesystem not found";
      return nullptr;
    }

    return result->second;
  }

  Options addFileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs) {
    llvm::sys::ScopedLock L(mtx);
    auto result = FileSystems.try_emplace(NextFSID, std::move(fs));
    assert(result.second && "duplicate key");
    Options ret(NextFSID);
    ++NextFSID;
    return ret;
  }

  void removeFileSystem(Options &options) {
    llvm::sys::ScopedLock L(mtx);
    FileSystems.erase(options.FSID);
  }

private:
  llvm::sys::Mutex mtx;
  unsigned NextFSID = 0;
  llvm::DenseMap<unsigned, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
      FileSystems;
};
}

static void
configureCompletionInstance(std::shared_ptr<CompletionInstance> CompletionInst,
                            std::shared_ptr<GlobalConfig> GlobalConfig) {
  auto Opts = GlobalConfig->getCompletionOpts();
  CompletionInst->setOptions({
    Opts.MaxASTContextReuseCount,
    Opts.CheckDependencyInterval
  });
}

SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
    : NotificationCtr(SKCtx.getNotificationCenter()),
      CCCache(new SwiftCompletionCache) {
  llvm::SmallString<128> LibPath(SKCtx.getRuntimeLibPath());
  llvm::sys::path::append(LibPath, "swift");
  RuntimeResourcePath = std::string(LibPath.str());
  DiagnosticDocumentationPath = SKCtx.getDiagnosticDocumentationPath().str();

  Stats = std::make_shared<SwiftStatistics>();
  EditorDocuments = std::make_shared<SwiftEditorDocumentFileMap>();
  ASTMgr = std::make_shared<SwiftASTManager>(
      EditorDocuments, SKCtx.getGlobalConfiguration(), Stats,
      RuntimeResourcePath, DiagnosticDocumentationPath);

  CompletionInst = std::make_shared<CompletionInstance>();
  configureCompletionInstance(CompletionInst, SKCtx.getGlobalConfiguration());

  // By default, just use the in-memory cache.
  CCCache->inMemory = std::make_unique<ide::CodeCompletionCache>();

  // Provide a default file system provider.
  setFileSystemProvider("in-memory-vfs", std::make_unique<InMemoryFileSystemProvider>());

  // SWIFT_ENABLE_TENSORFLOW
  setFileSystemProvider("directly-passed-vfs",
                        std::make_unique<DirectlyPassedFileSystemProvider>());
}

SwiftLangSupport::~SwiftLangSupport() {
}

// SWIFT_ENABLE_TENSORFLOW
void SwiftLangSupport::setInMemoryOutputFileSystem(
    llvm::IntrusiveRefCntPtr<clang::InMemoryOutputFileSystem> FS) {
  ASTMgr->setInMemoryOutputFileSystem(std::move(FS));
}
// SWIFT_ENABLE_TENSORFLOW END

void SwiftLangSupport::globalConfigurationUpdated(
    std::shared_ptr<GlobalConfig> Config) {
  configureCompletionInstance(CompletionInst, Config);
}

UIdent SwiftLangSupport::getUIDForDecl(const Decl *D, bool IsRef) {
  return UIdentVisitor(IsRef).visit(const_cast<Decl*>(D));
}

UIdent SwiftLangSupport::getUIDForExtensionOfDecl(const Decl *D) {
  switch (D->getKind()) {
    case swift::DeclKind::Struct:
      return KindDeclExtensionStruct;
    case swift::DeclKind::Enum:
      return KindDeclExtensionEnum;
    case swift::DeclKind::Class:
      return KindDeclExtensionClass;
    case swift::DeclKind::Protocol:
      return KindDeclExtensionProtocol;
    default:
      llvm_unreachable("cannot have extension.");
  }
}

UIdent SwiftLangSupport::getUIDForLocalVar(bool IsRef) {
  return IsRef ? KindRefVarLocal : KindDeclVarLocal;
}

UIdent SwiftLangSupport::getUIDForAccessor(const ValueDecl *D,
                                           AccessorKind AccKind,
                                           bool IsRef) {
  switch (AccKind) {
  case AccessorKind::Get:
    return IsRef ? KindRefAccessorGetter : KindDeclAccessorGetter;
  case AccessorKind::Set:
    return IsRef ? KindRefAccessorSetter : KindDeclAccessorSetter;
  case AccessorKind::WillSet:
    return IsRef ? KindRefAccessorWillSet : KindDeclAccessorWillSet;
  case AccessorKind::DidSet:
    return IsRef ? KindRefAccessorDidSet : KindDeclAccessorDidSet;
  case AccessorKind::Address:
    return IsRef ? KindRefAccessorAddress : KindDeclAccessorAddress;
  case AccessorKind::MutableAddress:
    return IsRef ? KindRefAccessorMutableAddress
                 : KindDeclAccessorMutableAddress;
  case AccessorKind::Read:
    return IsRef ? KindRefAccessorRead : KindDeclAccessorRead;
  case AccessorKind::Modify:
    return IsRef ? KindRefAccessorModify : KindDeclAccessorModify;
  }

  llvm_unreachable("Unhandled AccessorKind in switch.");
}

SourceKit::UIdent SwiftLangSupport::getUIDForModuleRef() {
  return KindRefModule;
}

SourceKit::UIdent SwiftLangSupport::getUIDForObjCAttr() {
  return Attr_Objc;
}

UIdent SwiftLangSupport::getUIDForRefactoringKind(ide::RefactoringKind Kind){
  switch(Kind) {
  case ide::RefactoringKind::None: llvm_unreachable("cannot end up here.");
#define REFACTORING(KIND, NAME, ID)                                            \
  case ide::RefactoringKind::KIND: return KindRefactoring##KIND;
#include "swift/IDE/RefactoringKinds.def"
  }
}

UIdent SwiftLangSupport::getUIDForCodeCompletionDeclKind(
    ide::CodeCompletionDeclKind Kind, bool IsRef) {
  if (IsRef) {
    // FIXME: The code-completion kind is also used for semantic annotations.
    // We should either create a new kind or rename the code-completion kind to
    // something more general.
    switch (Kind) {
    case CodeCompletionDeclKind::Module: return KindRefModule;
    case CodeCompletionDeclKind::Class: return KindRefClass;
    case CodeCompletionDeclKind::Struct: return KindRefStruct;
    case CodeCompletionDeclKind::Enum: return KindRefEnum;
    case CodeCompletionDeclKind::EnumElement: return KindRefEnumElement;
    case CodeCompletionDeclKind::Protocol: return KindRefProtocol;
    case CodeCompletionDeclKind::AssociatedType: return KindRefAssociatedType;
    case CodeCompletionDeclKind::TypeAlias: return KindRefTypeAlias;
    case CodeCompletionDeclKind::GenericTypeParam: return KindRefGenericTypeParam;
    case CodeCompletionDeclKind::Constructor: return KindRefConstructor;
    case CodeCompletionDeclKind::Destructor: return KindRefDestructor;
    case CodeCompletionDeclKind::Subscript: return KindRefSubscript;
    case CodeCompletionDeclKind::StaticMethod: return KindRefMethodClass;
    case CodeCompletionDeclKind::InstanceMethod: return KindRefMethodInstance;
    case CodeCompletionDeclKind::PrefixOperatorFunction: return KindRefFunctionPrefixOperator;
    case CodeCompletionDeclKind::PostfixOperatorFunction: return KindRefFunctionPostfixOperator;
    case CodeCompletionDeclKind::InfixOperatorFunction: return KindRefFunctionInfixOperator;
    case CodeCompletionDeclKind::PrecedenceGroup: return KindRefPrecedenceGroup;
    case CodeCompletionDeclKind::FreeFunction: return KindRefFunctionFree;
    case CodeCompletionDeclKind::StaticVar: return KindRefVarClass;
    case CodeCompletionDeclKind::InstanceVar: return KindRefVarInstance;
    case CodeCompletionDeclKind::LocalVar: return KindRefVarLocal;
    case CodeCompletionDeclKind::GlobalVar: return KindRefVarGlobal;
    }
  }

  switch (Kind) {
  case CodeCompletionDeclKind::Module: return KindDeclModule;
  case CodeCompletionDeclKind::Class: return KindDeclClass;
  case CodeCompletionDeclKind::Struct: return KindDeclStruct;
  case CodeCompletionDeclKind::Enum: return KindDeclEnum;
  case CodeCompletionDeclKind::EnumElement: return KindDeclEnumElement;
  case CodeCompletionDeclKind::Protocol: return KindDeclProtocol;
  case CodeCompletionDeclKind::AssociatedType: return KindDeclAssociatedType;
  case CodeCompletionDeclKind::TypeAlias: return KindDeclTypeAlias;
  case CodeCompletionDeclKind::GenericTypeParam: return KindDeclGenericTypeParam;
  case CodeCompletionDeclKind::Constructor: return KindDeclConstructor;
  case CodeCompletionDeclKind::Destructor: return KindDeclDestructor;
  case CodeCompletionDeclKind::Subscript: return KindDeclSubscript;
  case CodeCompletionDeclKind::StaticMethod: return KindDeclMethodClass;
  case CodeCompletionDeclKind::InstanceMethod: return KindDeclMethodInstance;
  case CodeCompletionDeclKind::PrefixOperatorFunction: return KindDeclFunctionPrefixOperator;
  case CodeCompletionDeclKind::PostfixOperatorFunction: return KindDeclFunctionPostfixOperator;
  case CodeCompletionDeclKind::InfixOperatorFunction: return KindDeclFunctionInfixOperator;
  case CodeCompletionDeclKind::PrecedenceGroup: return KindDeclPrecedenceGroup;
  case CodeCompletionDeclKind::FreeFunction: return KindDeclFunctionFree;
  case CodeCompletionDeclKind::StaticVar: return KindDeclVarClass;
  case CodeCompletionDeclKind::InstanceVar: return KindDeclVarInstance;
  case CodeCompletionDeclKind::LocalVar: return KindDeclVarLocal;
  case CodeCompletionDeclKind::GlobalVar: return KindDeclVarGlobal;
  }

  llvm_unreachable("Unhandled CodeCompletionDeclKind in switch.");
}

UIdent SwiftLangSupport::getUIDForSyntaxNodeKind(SyntaxNodeKind SC) {
  switch (SC) {
  case SyntaxNodeKind::Keyword:
    return KindKeyword;
  case SyntaxNodeKind::Identifier:
  case SyntaxNodeKind::DollarIdent:
    return KindIdentifier;
  case SyntaxNodeKind::Integer:
  case SyntaxNodeKind::Floating:
    return KindNumber;
  case SyntaxNodeKind::String:
    return KindString;
  case SyntaxNodeKind::StringInterpolationAnchor:
    return KindStringInterpolation;
  case SyntaxNodeKind::CommentLine:
  case SyntaxNodeKind::CommentBlock:
    return KindComment;
  case SyntaxNodeKind::CommentMarker:
    return KindCommentMarker;
  case SyntaxNodeKind::CommentURL:
    return KindCommentURL;
  case SyntaxNodeKind::DocCommentLine:
  case SyntaxNodeKind::DocCommentBlock:
    return KindDocComment;
  case SyntaxNodeKind::DocCommentField:
    return KindDocCommentField;
  case SyntaxNodeKind::TypeId:
    return KindTypeIdentifier;
  case SyntaxNodeKind::BuildConfigKeyword:
    return KindBuildConfigKeyword;
  case SyntaxNodeKind::BuildConfigId:
    return KindBuildConfigId;
  case SyntaxNodeKind::PoundDirectiveKeyword:
    return KindPoundDirectiveKeyword;
  case SyntaxNodeKind::AttributeId:
    return KindAttributeId;
  case SyntaxNodeKind::AttributeBuiltin:
    return KindAttributeBuiltin;
  case SyntaxNodeKind::EditorPlaceholder:
    return KindPlaceholder;
  case SyntaxNodeKind::ObjectLiteral:
    return KindObjectLiteral;
  }

  // Default to a known kind to prevent crashing in non-asserts builds
  assert(0 && "Unhandled SyntaxNodeKind in switch.");
  return KindIdentifier;
}

UIdent SwiftLangSupport::getUIDForSyntaxStructureKind(
    SyntaxStructureKind Kind) {
  switch (Kind) {
    case SyntaxStructureKind::Class:
      return KindDeclClass;
    case SyntaxStructureKind::Struct:
      return KindDeclStruct;
    case SyntaxStructureKind::Protocol:
      return KindDeclProtocol;
    case SyntaxStructureKind::Enum:
      return KindDeclEnum;
    case SyntaxStructureKind::Extension:
      return KindDeclExtension;
    case SyntaxStructureKind::FreeFunction:
      return KindDeclFunctionFree;
    case SyntaxStructureKind::InstanceFunction:
      return KindDeclMethodInstance;
    case SyntaxStructureKind::StaticFunction:
      return KindDeclMethodStatic;
    case SyntaxStructureKind::ClassFunction:
      return KindDeclMethodClass;
    case SyntaxStructureKind::GlobalVariable:
      return KindDeclVarGlobal;
    case SyntaxStructureKind::InstanceVariable:
      return KindDeclVarInstance;
    case SyntaxStructureKind::StaticVariable:
      return KindDeclVarStatic;
    case SyntaxStructureKind::ClassVariable:
      return KindDeclVarClass;
    case SyntaxStructureKind::LocalVariable:
      return KindDeclVarLocal;
    case SyntaxStructureKind::EnumCase:
      return KindDeclEnumCase;
    case SyntaxStructureKind::EnumElement:
      return KindDeclEnumElement;
    case SyntaxStructureKind::TypeAlias:
      return KindDeclTypeAlias;
    case SyntaxStructureKind::Subscript:
      return KindDeclSubscript;
    case SyntaxStructureKind::AssociatedType:
      return KindDeclAssociatedType;
    case SyntaxStructureKind::GenericTypeParam:
      return KindDeclGenericTypeParam;
    case SyntaxStructureKind::Parameter:
      return KindDeclVarParam;
    case SyntaxStructureKind::ForEachStatement:
      return KindStmtForEach;
    case SyntaxStructureKind::WhileStatement:
      return KindStmtWhile;
    case SyntaxStructureKind::RepeatWhileStatement:
      return KindStmtRepeatWhile;
    case SyntaxStructureKind::IfStatement:
      return KindStmtIf;
    case SyntaxStructureKind::GuardStatement:
      return KindStmtGuard;
    case SyntaxStructureKind::SwitchStatement:
      return KindStmtSwitch;
    case SyntaxStructureKind::CaseStatement:
      return KindStmtCase;
    case SyntaxStructureKind::BraceStatement:
      return KindStmtBrace;
    case SyntaxStructureKind::CallExpression:
      return KindExprCall;
    case SyntaxStructureKind::ArrayExpression:
      return KindExprArray;
    case SyntaxStructureKind::DictionaryExpression:
      return KindExprDictionary;
    case SyntaxStructureKind::ObjectLiteralExpression:
      return KindExprObjectLiteral;
    case SyntaxStructureKind::TupleExpression:
      return KindExprTuple;
    case SyntaxStructureKind::ClosureExpression:
      return KindExprClosure;
    case SyntaxStructureKind::Argument:
      return KindExprArg;
  }

  llvm_unreachable("Unhandled SyntaxStructureKind in switch.");
}

UIdent SwiftLangSupport::getUIDForSyntaxStructureElementKind(
    SyntaxStructureElementKind Kind) {
  switch (Kind) {
    case SyntaxStructureElementKind::Id: return KindStructureElemId;
    case SyntaxStructureElementKind::Expr: return KindStructureElemExpr;
    case SyntaxStructureElementKind::InitExpr: return KindStructureElemInitExpr;
    case SyntaxStructureElementKind::ConditionExpr: return KindStructureElemCondExpr;
    case SyntaxStructureElementKind::Pattern: return KindStructureElemPattern;
    case SyntaxStructureElementKind::TypeRef: return KindStructureElemTypeRef;
  }

  llvm_unreachable("Unhandled SyntaxStructureElementKind in switch.");
}

SourceKit::UIdent SwiftLangSupport::
getUIDForRangeKind(swift::ide::RangeKind Kind) {
  switch (Kind) {
    case swift::ide::RangeKind::SingleExpression: return KindRangeSingleExpression;
    case swift::ide::RangeKind::SingleStatement: return KindRangeSingleStatement;
    case swift::ide::RangeKind::SingleDecl: return KindRangeSingleDeclaration;
    case swift::ide::RangeKind::MultiStatement: return KindRangeMultiStatement;
    case swift::ide::RangeKind::MultiTypeMemberDecl:
      return KindRangeMultiTypeMemberDeclaration;
    case swift::ide::RangeKind::PartOfExpression: return KindRangeInvalid;
    case swift::ide::RangeKind::Invalid: return KindRangeInvalid;
  }

  llvm_unreachable("Unhandled RangeKind in switch.");
}

SourceKit::UIdent SwiftLangSupport::
getUIDForRegionType(swift::ide::RegionType Type) {
  switch (Type) {
    case swift::ide::RegionType::ActiveCode: return KindEditActive;
    case swift::ide::RegionType::InactiveCode: return KindEditInactive;
    case swift::ide::RegionType::Selector: return KindEditSelector;
    case swift::ide::RegionType::String: return KindEditString;
    case swift::ide::RegionType::Comment: return KindEditComment;
    case swift::ide::RegionType::Mismatch: return KindEditMismatch;
    case swift::ide::RegionType::Unmatched: return KindEditUnknown;
  }
}

SourceKit::UIdent SwiftLangSupport::
getUIDForRefactoringRangeKind(ide::RefactoringRangeKind Kind) {
  switch (Kind) {
  case ide::RefactoringRangeKind::BaseName:
    return KindRenameRangeBase;
  case ide::RefactoringRangeKind::KeywordBaseName:
    return KindRenameRangeKeywordBase;
  case ide::RefactoringRangeKind::ParameterName:
    return KindRenameRangeParam;
  case ide::RefactoringRangeKind::NoncollapsibleParameterName:
    return KindRenameRangeNoncollapsibleParam;
  case ide::RefactoringRangeKind::DeclArgumentLabel:
    return KindRenameRangeDeclArgLabel;
  case ide::RefactoringRangeKind::CallArgumentLabel:
    return KindRenameRangeCallArgLabel;
  case ide::RefactoringRangeKind::CallArgumentColon:
    return KindRenameRangeCallArgColon;
  case ide::RefactoringRangeKind::CallArgumentCombined:
    return KindRenameRangeCallArgCombined;
  case ide::RefactoringRangeKind::SelectorArgumentLabel:
    return KindRenameRangeSelectorArgLabel;
  }
}

UIdent SwiftLangSupport::getUIDForSymbol(SymbolInfo sym, bool isRef) {

#define UID_FOR(CLASS) isRef ? KindRef##CLASS : KindDecl##CLASS;

  switch (sym.SubKind) {
  default: break;
  case SymbolSubKind::AccessorGetter: return UID_FOR(AccessorGetter);
  case SymbolSubKind::AccessorSetter: return UID_FOR(AccessorSetter);
  case SymbolSubKind::SwiftAccessorWillSet: return UID_FOR(AccessorWillSet);
  case SymbolSubKind::SwiftAccessorDidSet: return UID_FOR(AccessorDidSet);
  case SymbolSubKind::SwiftAccessorAddressor: return UID_FOR(AccessorAddress);
  case SymbolSubKind::SwiftAccessorMutableAddressor: return UID_FOR(AccessorMutableAddress);
  }

#define SIMPLE_CASE(KIND) \
  case SymbolKind::KIND: \
    return UID_FOR(KIND);

  switch (sym.Kind) {
  SIMPLE_CASE(Enum)
  SIMPLE_CASE(Struct)
  SIMPLE_CASE(Class)
  SIMPLE_CASE(Protocol)
  SIMPLE_CASE(Constructor)
  SIMPLE_CASE(Destructor)

  case SymbolKind::EnumConstant:
    return UID_FOR(EnumElement);

  case SymbolKind::TypeAlias:
    if (sym.SubKind == SymbolSubKind::SwiftAssociatedType)
      return UID_FOR(AssociatedType);
    if (sym.SubKind == SymbolSubKind::SwiftGenericTypeParam)
      return UID_FOR(GenericTypeParam);
    return UID_FOR(TypeAlias);

  case SymbolKind::Function:
  case SymbolKind::StaticMethod:
    if (sym.SubKind == SymbolSubKind::SwiftPrefixOperator)
      return UID_FOR(FunctionPrefixOperator);
    if (sym.SubKind == SymbolSubKind::SwiftPostfixOperator)
      return UID_FOR(FunctionPostfixOperator);
    if (sym.SubKind == SymbolSubKind::SwiftInfixOperator)
      return UID_FOR(FunctionInfixOperator);
    if (sym.Kind == SymbolKind::StaticMethod) {
      return UID_FOR(MethodStatic);
    } else {
      return UID_FOR(FunctionFree);
    }
  case SymbolKind::Variable:
    return UID_FOR(VarGlobal);
  case SymbolKind::InstanceMethod:
    return UID_FOR(MethodInstance);
  case SymbolKind::ClassMethod:
    return UID_FOR(MethodClass);
  case SymbolKind::InstanceProperty:
    if (sym.SubKind == SymbolSubKind::SwiftSubscript)
      return UID_FOR(Subscript);
    return UID_FOR(VarInstance);
  case SymbolKind::ClassProperty:
    return UID_FOR(VarClass);
  case SymbolKind::StaticProperty:
    return UID_FOR(VarStatic);

  case SymbolKind::Extension:
    assert(!isRef && "reference to extension decl?");
    if (sym.SubKind == SymbolSubKind::SwiftExtensionOfStruct) {
      return KindDeclExtensionStruct;
    } else if (sym.SubKind == SymbolSubKind::SwiftExtensionOfClass) {
      return KindDeclExtensionClass;
    } else if (sym.SubKind == SymbolSubKind::SwiftExtensionOfEnum) {
      return KindDeclExtensionEnum;
    } else if (sym.SubKind == SymbolSubKind::SwiftExtensionOfProtocol) {
      return KindDeclExtensionProtocol;
    } else {
      llvm_unreachable("missing extension sub kind");
    }

  case SymbolKind::Module:
    return KindRefModule;

  default:
    // TODO: reconsider whether having a default case is a good idea.
    return UIdent();
  }

#undef SIMPLE_CASE
#undef UID_FOR
}

SourceKit::UIdent SwiftLangSupport::getUIDForNameKind(swift::ide::NameKind Kind) {
  switch(Kind) {
  case swift::ide::NameKind::ObjC: return KindNameObjc;
  case swift::ide::NameKind::Swift: return KindNameSwift;
  }

  llvm_unreachable("Unhandled NameKind in switch.");
}

swift::ide::NameKind SwiftLangSupport::getNameKindForUID(SourceKit::UIdent Id) {
  if (Id == KindNameObjc)
    return swift::ide::NameKind::ObjC;
  assert(Id == KindNameSwift);
  return swift::ide::NameKind::Swift;
}

Optional<UIdent> SwiftLangSupport::getUIDForDeclAttribute(const swift::DeclAttribute *Attr) {
  // Check special-case names first.
  switch (Attr->getKind()) {
    case DAK_IBAction: {
      return Attr_IBAction;
    }
    case DAK_IBSegueAction: {
      static UIdent Attr_IBSegueAction("source.decl.attribute.ibsegueaction");
      return Attr_IBSegueAction;
    }
    case DAK_IBOutlet: {
      return Attr_IBOutlet;
    }
    case DAK_IBDesignable: {
      return Attr_IBDesignable;
    }
    case DAK_IBInspectable: {
      return Attr_IBInspectable;
    }
    case DAK_GKInspectable: {
      return Attr_GKInspectable;
    }
    case DAK_ObjC: {
      if (cast<ObjCAttr>(Attr)->hasName()) {
        return Attr_ObjcNamed;
      } else {
        return Attr_Objc;
      }
    }
    case DAK_AccessControl: {
      switch (cast<AbstractAccessControlAttr>(Attr)->getAccess()) {
        case AccessLevel::Private:
          return Attr_Private;
        case AccessLevel::FilePrivate:
          return Attr_FilePrivate;
        case AccessLevel::Internal:
          return Attr_Internal;
        case AccessLevel::Public:
          return Attr_Public;
        case AccessLevel::Open:
          return Attr_Open;
      }
    }
    case DAK_SetterAccess: {
      switch (cast<AbstractAccessControlAttr>(Attr)->getAccess()) {
        case AccessLevel::Private:
          return Attr_Setter_Private;
        case AccessLevel::FilePrivate:
          return Attr_Setter_FilePrivate;
        case AccessLevel::Internal:
          return Attr_Setter_Internal;
        case AccessLevel::Public:
          return Attr_Setter_Public;
        case AccessLevel::Open:
          return Attr_Setter_Open;
      }
    }

    // Ignore these.
    case DAK_ShowInInterface:
    case DAK_RawDocComment:
    case DAK_HasInitialValue:
    case DAK_HasStorage:
      return None;
    default:
      break;
  }

  switch (Attr->getKind()) {
    case DAK_Count:
      break;
#define DECL_ATTR(X, CLASS, ...)\
    case DAK_##CLASS: {\
      static UIdent Attr_##X("source.decl.attribute."#X); \
      return Attr_##X; \
    }
#include "swift/AST/Attr.def"
  }

  return None;
}

UIdent SwiftLangSupport::getUIDForFormalAccessScope(const swift::AccessScope Scope) {
  if (Scope.isPublic()) {
    return EffectiveAccess_Public;
  } else if (Scope.isInternal()) {
    return EffectiveAccess_Internal;
  } else if (Scope.isFileScope()) {
    return EffectiveAccess_FilePrivate;
  } else if (Scope.isPrivate()) {
    return EffectiveAccess_LessThanFilePrivate;
  } else {
    llvm_unreachable("Unsupported access scope");
  }
}

std::vector<UIdent> SwiftLangSupport::UIDsFromDeclAttributes(const DeclAttributes &Attrs) {
  std::vector<UIdent> AttrUIDs;

  for (auto Attr : Attrs) {
    if (auto AttrUID = getUIDForDeclAttribute(Attr)) {
      AttrUIDs.push_back(AttrUID.getValue());
    }
  }

  return AttrUIDs;
}

bool SwiftLangSupport::printDisplayName(const swift::ValueDecl *D,
                                        llvm::raw_ostream &OS) {
  if (!D->hasName())
    return true;

  OS << D->getName();
  return false;
}

bool SwiftLangSupport::printUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
  return ide::printValueDeclUSR(D, OS);
}

bool SwiftLangSupport::printDeclTypeUSR(const ValueDecl *D, llvm::raw_ostream &OS) {
  return ide::printDeclTypeUSR(D, OS);
}

bool SwiftLangSupport::printTypeUSR(Type Ty, llvm::raw_ostream &OS) {
  return ide::printTypeUSR(Ty, OS);
}

bool SwiftLangSupport::printAccessorUSR(const AbstractStorageDecl *D,
                                        AccessorKind AccKind,
                                        llvm::raw_ostream &OS) {
  return ide::printAccessorUSR(D, AccKind, OS);
}

void SwiftLangSupport::printMemberDeclDescription(const swift::ValueDecl *VD,
                                                  swift::Type baseTy,
                                                  bool usePlaceholder,
                                                  llvm::raw_ostream &OS) {
  // Base name.
  OS << VD->getBaseName().userFacingName();

  // Parameters.
  auto *M = VD->getModuleContext();
  auto substMap = baseTy->getMemberSubstitutionMap(M, VD);
  auto printSingleParam = [&](ParamDecl *param) {
    auto paramTy = param->getInterfaceType();

    // Label.
    if (!param->getArgumentName().empty())
      OS << param->getArgumentName() << ": ";

    // InOut.
    if (param->isInOut()) {
      OS << "&";
      paramTy = paramTy->getInOutObjectType();
    }

    // Type.
    if (usePlaceholder)
      OS << "<#T##";

    paramTy = paramTy.subst(substMap);
    if (paramTy->hasError() && param->getTypeRepr()) {
      // Fallback to 'TypeRepr' printing.
      param->getTypeRepr()->print(OS);
    } else {
      paramTy.print(OS);
    }

    if (usePlaceholder)
      OS << "#>";
  };
  auto printParams = [&](const ParameterList *params) {
    OS << '(';
    bool isFirst = true;
    for (auto param : params->getArray()) {
      if (isFirst)
        isFirst = false;
      else
        OS << ", ";
      printSingleParam(param);
    }
    OS << ')';
  };
  if (isa<EnumElementDecl>(VD) || isa<FuncDecl>(VD)) {
    if (const auto ParamList = getParameterList(const_cast<ValueDecl *>(VD))) {
      printParams(ParamList);
    }
  } else if (isa<VarDecl>(VD)) {
    // Var decl doesn't have parameters.
  } else {
    llvm_unreachable("Unsupported Decl kind for printMemberDeclDescription()");
  }
}

std::string SwiftLangSupport::resolvePathSymlinks(StringRef FilePath) {
  std::string InputPath = FilePath.str();
  llvm::SmallString<256> output;
  if (llvm::sys::fs::real_path(InputPath, output))
    return InputPath;
  return std::string(output.str());
}

void SwiftLangSupport::getStatistics(StatisticsReceiver receiver) {
  std::vector<Statistic *> stats = {
#define SWIFT_STATISTIC(VAR, UID, DESC) &Stats->VAR,
#include "SwiftStatistics.def"
  };
  receiver(stats);
}

// SWIFT_ENABLE_TENSORFLOW
void SwiftLangSupport::codeComplete(
    llvm::MemoryBuffer *InputBuf, unsigned Offset,
    CodeCompletionConsumer &Consumer, ArrayRef<const char *> Args,
    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
  VFSOptions vfsOptions;
  vfsOptions.name = "directly-passed-vfs";
  auto *provider = static_cast<DirectlyPassedFileSystemProvider *>(
      getFileSystemProvider(vfsOptions.name));
  assert(provider);
  auto options = provider->addFileSystem(FS);
  vfsOptions.options =
      std::make_unique<DirectlyPassedFileSystemProvider::Options>(options);
  codeComplete(InputBuf, Offset, vfsOptions.options.get(), Consumer, Args,
               std::move(vfsOptions));
  provider->removeFileSystem(options);
}
// SWIFT_ENABLE_TENSORFLOW END

void SwiftLangSupport::editorOpen(
    StringRef Name, llvm::MemoryBuffer *Buf, EditorConsumer &Consumer,
    ArrayRef<const char *> Args,
    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
  VFSOptions vfsOptions;
  vfsOptions.name = "directly-passed-vfs";
  auto *provider = static_cast<DirectlyPassedFileSystemProvider *>(
      getFileSystemProvider(vfsOptions.name));
  assert(provider);
  auto options = provider->addFileSystem(FS);
  vfsOptions.options =
      std::make_unique<DirectlyPassedFileSystemProvider::Options>(options);
  editorOpen(Name, Buf, Consumer, Args, std::move(vfsOptions));
  provider->removeFileSystem(options);
}


FileSystemProvider *SwiftLangSupport::getFileSystemProvider(StringRef Name) {
  auto It = FileSystemProviders.find(Name);
  if (It == FileSystemProviders.end())
    return nullptr;
  return It->second.get();
}

void SwiftLangSupport::setFileSystemProvider(
     StringRef Name, std::unique_ptr<FileSystemProvider> FileSystemProvider) {
  assert(FileSystemProvider);
  auto Result = FileSystemProviders.try_emplace(Name, std::move(FileSystemProvider));
  assert(Result.second && "tried to set existing FileSystemProvider");
}

llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
SwiftLangSupport::getFileSystem(const Optional<VFSOptions> &vfsOptions,
                                Optional<StringRef> primaryFile,
                                std::string &error) {
  // First, try the specified vfsOptions.
  if (vfsOptions) {
    auto provider = getFileSystemProvider(vfsOptions->name);
    if (!provider) {
      error = "unknown virtual filesystem '" + vfsOptions->name + "'";
      return nullptr;
    }

    return provider->getFileSystem(*vfsOptions->options, error);
  }

  // Otherwise, try to find an open document with a filesystem.
  if (primaryFile) {
    if (auto doc = EditorDocuments->getByUnresolvedName(*primaryFile)) {
      return doc->getFileSystem();
    }
  }

  // Fallback to the real filesystem.
  return llvm::vfs::getRealFileSystem();
}

bool SwiftLangSupport::performCompletionLikeOperation(
    llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
    ArrayRef<const char *> Args,
    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
    std::string &Error,
    llvm::function_ref<void(CompilerInstance &, bool)> Callback) {
  assert(FileSystem);

  // Resolve symlinks for the input file; we resolve them for the input files
  // in the arguments as well.
  // FIXME: We need the Swift equivalent of Clang's FileEntry.
  llvm::SmallString<128> bufferIdentifier;
  if (auto err = FileSystem->getRealPath(
          UnresolvedInputFile->getBufferIdentifier(), bufferIdentifier))
    bufferIdentifier = UnresolvedInputFile->getBufferIdentifier();

  // Create a buffer for code completion. This contains '\0' at 'Offset'
  // position of 'UnresolvedInputFile' buffer.
  auto origOffset = Offset;
  auto newBuffer = ide::makeCodeCompletionMemoryBuffer(
      UnresolvedInputFile, Offset, bufferIdentifier);

  SourceManager SM;
  DiagnosticEngine Diags(SM);
  PrintingDiagnosticConsumer PrintDiags;
  EditorDiagConsumer TraceDiags;
  trace::TracedOperation TracedOp{trace::OperationKind::CodeCompletion};

  Diags.addConsumer(PrintDiags);
  if (TracedOp.enabled()) {
    Diags.addConsumer(TraceDiags);
    trace::SwiftInvocation SwiftArgs;
    trace::initTraceInfo(SwiftArgs, bufferIdentifier, Args);
    TracedOp.setDiagnosticProvider(
        [&](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
          TraceDiags.getAllDiagnostics(diags);
        });
    TracedOp.start(
        SwiftArgs,
        {std::make_pair("OriginalOffset", std::to_string(origOffset)),
         std::make_pair("Offset", std::to_string(Offset))});
  }
  ForwardingDiagnosticConsumer CIDiags(Diags);

  CompilerInvocation Invocation;
  bool Failed = getASTManager()->initCompilerInvocation(
      Invocation, Args, Diags, newBuffer->getBufferIdentifier(), FileSystem,
      Error);
  if (Failed)
    return false;
  if (!Invocation.getFrontendOptions().InputsAndOutputs.hasInputs()) {
    Error = "no input filenames specified";
    return false;
  }

  // Pin completion instance.
  auto CompletionInst = getCompletionInstance();

  return CompletionInst->performOperation(Invocation, Args, FileSystem,
                                          newBuffer.get(), Offset,
                                          Error, &CIDiags, Callback);
}

CloseClangModuleFiles::~CloseClangModuleFiles() {
  clang::Preprocessor &PP = loader.getClangPreprocessor();
  clang::ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
  for (auto I = ModMap.module_begin(), E = ModMap.module_end(); I != E; ++I) {
    clang::Module *M = I->second;
    if (!M->isSubModule() && M->getASTFile())
      M->getASTFile()->closeFile();
  }
}

void SourceKit::disableExpensiveSILOptions(SILOptions &Opts) {
  // Disable the sanitizers.
  Opts.Sanitizers = {};

  // Disable PGO and code coverage.
  Opts.GenerateProfile = false;
  Opts.EmitProfileCoverageMapping = false;
  Opts.UseProfile = "";
}
