//===--- sourcekitdAPI-Common.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 "DictionaryKeys.h"
#include "sourcekitd/Internal.h"
#include "sourcekitd/Logging.h"
#include "sourcekitd/RequestResponsePrinterBase.h"
#include "SourceKit/Support/Logging.h"
#include "SourceKit/Support/UIdent.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLParser.h"
#include <mutex>

using namespace SourceKit;
using namespace sourcekitd;
using llvm::ArrayRef;
using llvm::StringRef;
using llvm::raw_ostream;


UIdent sourcekitd::KeyVersionMajor("key.version_major");;
UIdent sourcekitd::KeyVersionMinor("key.version_minor");;
UIdent sourcekitd::KeyResults("key.results");
UIdent sourcekitd::KeyRequest("key.request");
UIdent sourcekitd::KeyCompilerArgs("key.compilerargs");
UIdent sourcekitd::KeyOffset("key.offset");
UIdent sourcekitd::KeySourceFile("key.sourcefile");
UIdent sourcekitd::KeySourceText("key.sourcetext");
UIdent sourcekitd::KeyModuleName("key.modulename");
UIdent sourcekitd::KeyGroupName("key.groupname");
UIdent sourcekitd::KeyActionName("key.actionname");
UIdent sourcekitd::KeySynthesizedExtension("key.synthesizedextensions");
UIdent sourcekitd::KeyNotification("key.notification");
UIdent sourcekitd::KeyKeyword("key.keyword");
UIdent sourcekitd::KeyName("key.name");
UIdent sourcekitd::KeyNames("key.names");
UIdent sourcekitd::KeyUIDs("key.uids");
UIdent sourcekitd::KeyEnableSyntaxMap("key.enablesyntaxmap");
UIdent sourcekitd::KeyEnableDiagnostics("key.enablediagnostics");
UIdent sourcekitd::KeySyntacticOnly("key.syntactic_only");
UIdent sourcekitd::KeyLength("key.length");
UIdent sourcekitd::KeyActionable("key.actionable");
UIdent sourcekitd::KeyKind("key.kind");
UIdent sourcekitd::KeyAccessibility("key.accessibility");
UIdent sourcekitd::KeySetterAccessibility("key.setter_accessibility");
UIdent sourcekitd::KeyUSR("key.usr");
UIdent sourcekitd::KeyOriginalUSR("key.original_usr");
UIdent sourcekitd::KeyDefaultImplementationOf("key.default_implementation_of");
UIdent sourcekitd::KeyInterestedUSR("key.interested_usr");
UIdent sourcekitd::KeyLine("key.line");
UIdent sourcekitd::KeyColumn("key.column");
UIdent sourcekitd::KeyReceiverUSR("key.receiver_usr");
UIdent sourcekitd::KeyIsDynamic("key.is_dynamic");
UIdent sourcekitd::KeyIsTestCandidate("key.is_test_candidate");
UIdent sourcekitd::KeyDescription("key.description");
UIdent sourcekitd::KeyTypeName("key.typename");
UIdent sourcekitd::KeyRuntimeName("key.runtime_name");
UIdent sourcekitd::KeySelectorName("key.selector_name");
UIdent sourcekitd::KeyOverrides("key.overrides");
UIdent sourcekitd::KeyDocBrief("key.doc.brief");
UIdent sourcekitd::KeyAssociatedUSRs("key.associated_usrs");
UIdent sourcekitd::KeyDocFullAsXML("key.doc.full_as_xml");
UIdent sourcekitd::KeyGenericParams("key.generic_params");
UIdent sourcekitd::KeyGenericRequirements("key.generic_requirements");
UIdent sourcekitd::KeyAnnotatedDecl("key.annotated_decl");
UIdent sourcekitd::KeyFullyAnnotatedDecl("key.fully_annotated_decl");
UIdent sourcekitd::KeyRelatedDecls("key.related_decls");
UIdent sourcekitd::KeyContext("key.context");
UIdent sourcekitd::KeyModuleImportDepth("key.moduleimportdepth");
UIdent sourcekitd::KeyNumBytesToErase("key.num_bytes_to_erase");
UIdent sourcekitd::KeyNotRecommended("key.not_recommended");
UIdent sourcekitd::KeyFilePath("key.filepath");
UIdent sourcekitd::KeyModuleInterfaceName("key.module_interface_name");
UIdent sourcekitd::KeyHash("key.hash");
UIdent sourcekitd::KeyRelated("key.related");
UIdent sourcekitd::KeyInherits("key.inherits");
UIdent sourcekitd::KeyConforms("key.conforms");
UIdent sourcekitd::KeyExtends("key.extends");
UIdent sourcekitd::KeyDependencies("key.dependencies");
UIdent sourcekitd::KeyEntities("key.entities");
UIdent sourcekitd::KeyDiagnostics("key.diagnostics");
UIdent sourcekitd::KeySeverity("key.severity");
UIdent sourcekitd::KeyRanges("key.ranges");
UIdent sourcekitd::KeyFixits("key.fixits");
UIdent sourcekitd::KeyAnnotations("key.annotations");
UIdent sourcekitd::KeyDiagnosticStage("key.diagnostic_stage");
UIdent sourcekitd::KeySyntaxMap("key.syntaxmap");
UIdent sourcekitd::KeyIsSystem("key.is_system");
UIdent sourcekitd::KeyEnableStructure("key.enablesubstructure");
UIdent sourcekitd::KeySubStructure("key.substructure");
UIdent sourcekitd::KeyElements("key.elements");
UIdent sourcekitd::KeyNameOffset("key.nameoffset");
UIdent sourcekitd::KeyNameLength("key.namelength");
UIdent sourcekitd::KeyBodyOffset("key.bodyoffset");
UIdent sourcekitd::KeyBodyLength("key.bodylength");
UIdent sourcekitd::KeyThrowOffset("key.throwoffset");
UIdent sourcekitd::KeyThrowLength("key.throwlength");
UIdent sourcekitd::KeyIsLocal("key.is_local");
UIdent sourcekitd::KeyAttributes("key.attributes");
UIdent sourcekitd::KeyAttribute("key.attribute");
UIdent sourcekitd::KeyInheritedTypes("key.inheritedtypes");
UIdent sourcekitd::KeyFormatOptions("key.editor.format.options");
UIdent sourcekitd::KeyCodeCompleteOptions("key.codecomplete.options");
UIdent sourcekitd::KeyFilterRules("key.codecomplete.filterrules");
UIdent sourcekitd::KeyNextRequestStart("key.nextrequeststart");
UIdent sourcekitd::KeyPopular("key.popular");
UIdent sourcekitd::KeyUnpopular("key.unpopular");
UIdent sourcekitd::KeyHide("key.hide");
UIdent sourcekitd::KeySimplified("key.simplified");
UIdent sourcekitd::KeyRangeContent("key.rangecontent");

UIdent sourcekitd::KeyIsDeprecated("key.is_deprecated");
UIdent sourcekitd::KeyIsUnavailable("key.is_unavailable");
UIdent sourcekitd::KeyIsOptional("key.is_optional");
UIdent sourcekitd::KeyPlatform("key.platform");
UIdent sourcekitd::KeyMessage("key.message");
UIdent sourcekitd::KeyIntroduced("key.introduced");
UIdent sourcekitd::KeyDeprecated("key.deprecated");
UIdent sourcekitd::KeyObsoleted("key.obsoleted");
UIdent sourcekitd::KeyRemoveCache("key.removecache");
UIdent sourcekitd::KeyTypeInterface("key.typeinterface");
UIdent sourcekitd::KeyTypeUsr("key.typeusr");
UIdent sourcekitd::KeyContainerTypeUsr("key.containertypeusr");
UIdent sourcekitd::KeyModuleGroups("key.modulegroups");

UIdent sourcekitd::KeyBaseName("key.basename");
UIdent sourcekitd::KeyArgNames("key.argnames");
UIdent sourcekitd::KeySelectorPieces("key.selectorpieces");
UIdent sourcekitd::KeyNameKind("key.namekind");
UIdent sourcekitd::KeyLocalizationKey("key.localization_key");

/// \brief Order for the keys to use when emitting the debug description of
/// dictionaries.
static UIdent *OrderedKeys[] = {
  &KeyVersionMajor,
  &KeyVersionMinor,
  &KeyResults,
  &KeyRequest,
  &KeyNotification,
  &KeyKind,
  &KeyAccessibility,
  &KeySetterAccessibility,
  &KeyKeyword,
  &KeyName,
  &KeyUSR,
  &KeyOriginalUSR,
  &KeyDefaultImplementationOf,
  &KeyInterestedUSR,
  &KeyGenericParams,
  &KeyGenericRequirements,
  &KeyDocFullAsXML,
  &KeyLine,
  &KeyColumn,
  &KeyReceiverUSR,
  &KeyIsDynamic,
  &KeyFilePath,
  &KeyModuleInterfaceName,
  &KeyHash,
  &KeyCompilerArgs,
  &KeySeverity,
  &KeyOffset,
  &KeyLength,
  &KeySourceFile,
  &KeySourceText,
  &KeyEnableSyntaxMap,
  &KeyEnableStructure,
  &KeyDescription,
  &KeyTypeName,
  &KeyRuntimeName,
  &KeySelectorName,
  &KeyAnnotatedDecl,
  &KeyFullyAnnotatedDecl,
  &KeyDocBrief,
  &KeyContext,
  &KeyModuleImportDepth,
  &KeyNumBytesToErase,
  &KeyNotRecommended,
  &KeyAnnotations,
  &KeyDiagnosticStage,
  &KeySyntaxMap,
  &KeyIsSystem,
  &KeyRelated,
  &KeyInherits,
  &KeyConforms,
  &KeyExtends,
  &KeyDependencies,
  &KeyEntities,
  &KeyNameOffset,
  &KeyNameLength,
  &KeyBodyOffset,
  &KeyBodyLength,
  &KeyThrowOffset,
  &KeyThrowLength,
  &KeyIsLocal,
  &KeyInheritedTypes,
  &KeyAttributes,
  &KeyAttribute,
  &KeyElements,
  &KeySubStructure,
  &KeyRanges,
  &KeyFixits,
  &KeyDiagnostics,
  &KeyFormatOptions,
  &KeyCodeCompleteOptions,
  &KeyFilterRules,
  &KeyNextRequestStart,
  &KeyPopular,
  &KeyUnpopular,
  &KeyHide,

  &KeyPlatform,
  &KeyIsDeprecated,
  &KeyIsUnavailable,
  &KeyIsOptional,
  &KeyMessage,
  &KeyIntroduced,
  &KeyDeprecated,
  &KeyObsoleted,
  &KeyRemoveCache,

  &KeyTypeInterface,
  &KeyTypeUsr,
  &KeyContainerTypeUsr,
  &KeyModuleGroups,

  &KeyBaseName,
  &KeyArgNames,
  &KeySelectorPieces,
  &KeyNameKind,

};

static unsigned findPrintOrderForDictKey(UIdent Key) {
  unsigned Order = 1;
  for (auto UIDPtr : OrderedKeys) {
    if (*UIDPtr == Key)
      return Order;
    ++Order;
  }
  return 10000;
}

bool sourcekitd::compareDictKeys(UIdent LHS, UIdent RHS) {
  if (LHS == RHS)
    return false;
  unsigned LHSOrder = findPrintOrderForDictKey(LHS);
  unsigned RHSOrder = findPrintOrderForDictKey(RHS);
  if (LHSOrder == RHSOrder)
    return LHS.getName() < RHS.getName();
  return LHSOrder < RHSOrder;
}


namespace {
template <typename ImplClass,
          typename RetTy = void>
class VariantVisitor {
public:
  typedef std::vector<std::pair<UIdent, sourcekitd_variant_t>> DictMap;

  static bool compKeys(const std::pair<UIdent, sourcekitd_variant_t> &LHS,
                       const std::pair<UIdent, sourcekitd_variant_t> &RHS) {
    return sourcekitd::compareDictKeys(LHS.first, RHS.first);
  }

  RetTy visit(sourcekitd_variant_t Obj) {
    switch (sourcekitd_variant_get_type(Obj)) {
    case SOURCEKITD_VARIANT_TYPE_NULL:
      return static_cast<ImplClass*>(this)->visitNull();
    case SOURCEKITD_VARIANT_TYPE_DICTIONARY: {
      DictMap Dict;
      DictMap &DictRef = Dict;
      sourcekitd_variant_dictionary_apply_impl(
          Obj,
          [&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
            DictRef.push_back({UIdentFromSKDUID(key), value});
            return true;
          });
      std::sort(Dict.begin(), Dict.end(), compKeys);
      return static_cast<ImplClass*>(this)->visitDictionary(Dict);
    }
    case SOURCEKITD_VARIANT_TYPE_ARRAY: {
      std::vector<sourcekitd_variant_t> Vec;
      for (size_t i = 0, e = sourcekitd_variant_array_get_count(Obj);
           i != e; ++i)
        Vec.push_back(sourcekitd_variant_array_get_value(Obj, i));
      return static_cast<ImplClass*>(this)->visitArray(Vec);
    }
    case SOURCEKITD_VARIANT_TYPE_INT64:
      return static_cast<ImplClass*>(this)->visitInt64(
                                       sourcekitd_variant_int64_get_value(Obj));
    case SOURCEKITD_VARIANT_TYPE_BOOL:
      return static_cast<ImplClass*>(this)->visitBool(
                                       sourcekitd_variant_bool_get_value(Obj));
    case SOURCEKITD_VARIANT_TYPE_STRING: {
      size_t Len = sourcekitd_variant_string_get_length(Obj);
      const char *Ptr = sourcekitd_variant_string_get_ptr(Obj);
      return static_cast<ImplClass*>(this)->visitString(StringRef(Ptr, Len));
    }
    case SOURCEKITD_VARIANT_TYPE_UID: {
      sourcekitd_uid_t UID = sourcekitd_variant_uid_get_value(Obj);
      size_t Len = sourcekitd_uid_get_length(UID);
      const char *Ptr = sourcekitd_uid_get_string_ptr(UID);
      return static_cast<ImplClass*>(this)->visitUID(StringRef(Ptr, Len));
    }
    }
  }
};

class VariantPrinter : public VariantVisitor<VariantPrinter>,
                       public RequestResponsePrinterBase<VariantPrinter,
                                                         sourcekitd_variant_t> {
public:
  VariantPrinter(raw_ostream &OS, unsigned Indent = 0, bool PrintAsJSON = false)
    : RequestResponsePrinterBase(OS, Indent, PrintAsJSON) { }
};
}

void sourcekitd::writeEscaped(llvm::StringRef Str, llvm::raw_ostream &OS) {
  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
    unsigned char c = Str[i];

    switch (c) {
    case '\\':
      OS << '\\' << '\\';
      break;
    case '\t':
      OS << '\\' << 't';
      break;
    case '\n':
      OS << '\\' << 'n';
      break;
    case '"':
      OS << '\\' << '"';
      break;
    default:
      OS << c;
      break;
    }
  }
}

static void printError(sourcekitd_response_t Err, raw_ostream &OS) {
  OS << "error response (";
  switch (sourcekitd_response_error_get_kind(Err)) {
  case SOURCEKITD_ERROR_CONNECTION_INTERRUPTED:
    OS << "Connection Interrupted"; break;
  case SOURCEKITD_ERROR_REQUEST_INVALID:
    OS << "Request Invalid"; break;
  case SOURCEKITD_ERROR_REQUEST_FAILED:
    OS << "Request Failed"; break;
  case SOURCEKITD_ERROR_REQUEST_CANCELLED:
    OS << "Request Cancelled"; break;
  }
  OS << "): ";
  OS << sourcekitd_response_error_get_description(Err);
}

static void printVariant(sourcekitd_variant_t obj, raw_ostream &OS) {
  VariantPrinter(OS).visit(obj);
}

void sourcekitd::printResponse(sourcekitd_response_t Resp, raw_ostream &OS) {
  if (!Resp) {
    OS << "<<NULL>>";
    return;
  }

  if (sourcekitd_response_is_error(Resp))
    printError(Resp, OS);
  else
    printVariant(sourcekitd_response_get_value(Resp), OS);
}

static void fatal_error_handler(void *user_data, const std::string& reason,
                                bool gen_crash_diag) {
  // Write the result out to stderr avoiding errs() because raw_ostreams can
  // call report_fatal_error.
  // FIXME: Put the error message in the crash report.
  fprintf(stderr, "SOURCEKITD FATAL ERROR: %s\n", reason.c_str());
  ::abort();
}

void sourcekitd::enableLogging(StringRef LoggerName) {
  Logger::Level LogLevel = Logger::Level::Warning;
  const char *EnvOpt = ::getenv("SOURCEKIT_LOGGING");
  if (EnvOpt) {
    int Val;
    bool Err = StringRef(EnvOpt).getAsInteger(10, Val);
    if (!Err) {
      if (Val > 2)
        LogLevel = Logger::Level::InfoLowPrio;
      else if (Val == 2)
        LogLevel = Logger::Level::InfoMediumPrio;
      else if (Val == 1)
        LogLevel = Logger::Level::InfoHighPrio;
    }
  }

  Logger::enableLogging(LoggerName, LogLevel);
}

//===----------------------------------------------------------------------===//
// Public API
//===----------------------------------------------------------------------===//

static llvm::sys::Mutex GlobalInitMtx;
static unsigned gInitRefCount = 0;

void sourcekitd_initialize(void) {
  llvm::sys::ScopedLock L(GlobalInitMtx);
  ++gInitRefCount;
  if (gInitRefCount > 1)
    return;

  static std::once_flag flag;
  std::call_once(flag, []() {
    llvm::install_fatal_error_handler(fatal_error_handler, 0);
    sourcekitd::enableLogging("sourcekit");
  });

  LOG_INFO_FUNC(High, "initializing");
  sourcekitd::initialize();
}

void sourcekitd_shutdown(void) {
  llvm::sys::ScopedLock L(GlobalInitMtx);
  --gInitRefCount;
  if (gInitRefCount > 0)
    return;

  LOG_INFO_FUNC(High, "shutting down");
  sourcekitd::shutdown();
}

void
sourcekitd_response_description_dump(sourcekitd_response_t resp) {
  // Avoid colors here, we don't properly detect that the debug window inside
  // Xcode doesn't support colors.
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printResponse(resp, OS);
  llvm::errs() << OS.str() << '\n';
}

void
sourcekitd_response_description_dump_filedesc(sourcekitd_response_t resp,
                                              int fd) {
  llvm::raw_fd_ostream OS(fd, /*shouldClose=*/false);
  printResponse(resp, OS);
  OS << '\n';
}

char *
sourcekitd_response_description_copy(sourcekitd_response_t resp) {
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printResponse(resp, OS);
  return strdup(Desc.c_str());
}


sourcekitd_uid_t
sourcekitd_uid_get_from_cstr(const char *string) {
  return SKDUIDFromUIdent(UIdent(string));
}

sourcekitd_uid_t
sourcekitd_uid_get_from_buf(const char *buf, size_t length) {
  return SKDUIDFromUIdent(UIdent(llvm::StringRef(buf, length)));
}

size_t
sourcekitd_uid_get_length(sourcekitd_uid_t uid) {
  UIdent UID = UIdentFromSKDUID(uid);
  return UID.getName().size();
}

const char *
sourcekitd_uid_get_string_ptr(sourcekitd_uid_t uid) {
  UIdent UID = UIdentFromSKDUID(uid);
  return UID.getName().begin();
}

void
sourcekitd_request_description_dump(sourcekitd_object_t obj) {
  // Avoid colors here, we don't properly detect that the debug window inside
  // Xcode doesn't support colors.
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printRequestObject(obj, OS);
  llvm::errs() << OS.str() << '\n';
}

char *
sourcekitd_request_description_copy(sourcekitd_object_t obj) {
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printRequestObject(obj, OS);
  return strdup(Desc.c_str());
}

//===----------------------------------------------------------------------===//
// Variant API
//===----------------------------------------------------------------------===//

#define VAR_FN(var, name) ((var).data[0] ? \
                            ((VariantFunctions*)(var).data[0])->name : nullptr)

sourcekitd_variant_type_t
sourcekitd_variant_get_type(sourcekitd_variant_t var) {
  if (auto fn = VAR_FN(var, get_type))
    return fn(var);

  // Default implementation:
  // Assume the variant encapsulates a basic type.
  static_assert(SOURCEKITD_VARIANT_TYPE_NULL == 0,
                "NULL type does not match null variant");
  return (sourcekitd_variant_type_t)var.data[2];
}

sourcekitd_variant_t
sourcekitd_variant_dictionary_get_value(sourcekitd_variant_t dict,
                                        sourcekitd_uid_t key) {
  if (auto fn = VAR_FN(dict, dictionary_get_value))
    return fn(dict, key);

  // Default implementation:
  // Linear search for the key/value pair via sourcekitd_variant_dictionary_apply.
  sourcekitd_variant_t result = makeNullVariant();
  sourcekitd_variant_dictionary_apply_impl(
      dict, [&](sourcekitd_uid_t curr_key, sourcekitd_variant_t curr_value) {
        if (curr_key == key) {
          result = curr_value;
          return false;
        }
        return true;
      });

  return result;
}

const char *
sourcekitd_variant_dictionary_get_string(sourcekitd_variant_t dict,
                                         sourcekitd_uid_t key) {
  if (auto fn = VAR_FN(dict, dictionary_get_string))
    return fn(dict, key);

  // Default implementation:
  // Get the value via sourcekitd_variant_dictionary_get_value.
  return sourcekitd_variant_string_get_ptr(
             sourcekitd_variant_dictionary_get_value(dict, key));
}

int64_t
sourcekitd_variant_dictionary_get_int64(sourcekitd_variant_t dict,
                                        sourcekitd_uid_t key) {
  if (auto fn = VAR_FN(dict, dictionary_get_int64))
    return fn(dict, key);

  // Default implementation:
  // Get the value via sourcekitd_variant_dictionary_get_value.
  return sourcekitd_variant_int64_get_value(
             sourcekitd_variant_dictionary_get_value(dict, key));
}

bool
sourcekitd_variant_dictionary_get_bool(sourcekitd_variant_t dict,
                                       sourcekitd_uid_t key) {
  if (auto fn = VAR_FN(dict, dictionary_get_bool))
    return fn(dict, key);

  // Default implementation:
  // Get the value via sourcekitd_variant_dictionary_get_value.
  return sourcekitd_variant_bool_get_value(
             sourcekitd_variant_dictionary_get_value(dict, key));
}

sourcekitd_uid_t
sourcekitd_variant_dictionary_get_uid(sourcekitd_variant_t dict,
                                      sourcekitd_uid_t key) {
  if (auto fn = VAR_FN(dict, dictionary_get_uid))
    return fn(dict, key);

  // Default implementation:
  // Get the value via sourcekitd_variant_dictionary_get_value.
  return sourcekitd_variant_uid_get_value(
             sourcekitd_variant_dictionary_get_value(dict, key));
}

#if SOURCEKITD_HAS_BLOCKS
bool
sourcekitd_variant_dictionary_apply(sourcekitd_variant_t dict,
                              sourcekitd_variant_dictionary_applier_t applier) {
  return sourcekitd_variant_dictionary_apply_impl(dict, applier);
}
#endif

bool
sourcekitd_variant_dictionary_apply_impl(
  sourcekitd_variant_t dict,
  llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
  if (auto fn = VAR_FN(dict, dictionary_apply))
    return fn(dict, applier);

  // Default implementation:
  // Treat as empty container.
  return true;
}

bool
sourcekitd_variant_dictionary_apply_f(sourcekitd_variant_t dict,
                              sourcekitd_variant_dictionary_applier_f_t applier,
                              void *context) {
  return sourcekitd_variant_dictionary_apply_impl(
      dict,
      [&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
          return applier(key, value, context);
  });
}

size_t
sourcekitd_variant_array_get_count(sourcekitd_variant_t array) {
  if (auto fn = VAR_FN(array, array_get_count))
    return fn(array);

  // Default implementation:
  // Treat as empty container.
  return 0;
}

sourcekitd_variant_t
sourcekitd_variant_array_get_value(sourcekitd_variant_t array, size_t index) {
  if (auto fn = VAR_FN(array, array_get_value))
    return fn(array, index);

  llvm::report_fatal_error("Trying to index an empty array.");
}

const char *
sourcekitd_variant_array_get_string(sourcekitd_variant_t array, size_t index) {
  if (auto fn = VAR_FN(array, array_get_string))
    return fn(array, index);

  // Default implementation:
  // Get the value via sourcekitd_variant_array_get_value.
  return sourcekitd_variant_string_get_ptr(
             sourcekitd_variant_array_get_value(array, index));
}

int64_t
sourcekitd_variant_array_get_int64(sourcekitd_variant_t array, size_t index) {
  if (auto fn = VAR_FN(array, array_get_int64))
    return fn(array, index);

  // Default implementation:
  // Get the value via sourcekitd_variant_array_get_value.
  return sourcekitd_variant_int64_get_value(
             sourcekitd_variant_array_get_value(array, index));
}

bool
sourcekitd_variant_array_get_bool(sourcekitd_variant_t array, size_t index) {
  if (auto fn = VAR_FN(array, array_get_bool))
    return fn(array, index);

  // Default implementation:
  // Get the value via sourcekitd_variant_array_get_value.
  return sourcekitd_variant_bool_get_value(
             sourcekitd_variant_array_get_value(array, index));
}

sourcekitd_uid_t
sourcekitd_variant_array_get_uid(sourcekitd_variant_t array, size_t index) {
  if (auto fn = VAR_FN(array, array_get_uid))
    return fn(array, index);

  // Default implementation:
  // Get the value via sourcekitd_variant_array_get_value.
  return sourcekitd_variant_uid_get_value(
             sourcekitd_variant_array_get_value(array, index));
}

#if SOURCEKITD_HAS_BLOCKS
bool
sourcekitd_variant_array_apply(sourcekitd_variant_t array,
                               sourcekitd_variant_array_applier_t applier) {
  return sourcekitd_variant_array_apply_impl(array, applier);
}
#endif

bool sourcekitd_variant_array_apply_impl(
    sourcekitd_variant_t array,
    llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
  if (auto fn = VAR_FN(array, array_apply))
    return fn(array, applier);

  // Default implementation:
  // Iterate over elements via a for-loop.
  for (size_t i = 0, e = sourcekitd_variant_array_get_count(array); i != e; ++i) {
    bool Continue = applier(i, sourcekitd_variant_array_get_value(array, i));
    if (!Continue)
      return false;
  }
  return true;
}

bool sourcekitd_variant_array_apply_f(
    sourcekitd_variant_t array, sourcekitd_variant_array_applier_f_t applier,
    void *context) {
  return sourcekitd_variant_array_apply_impl(
      array, [&](size_t index, sourcekitd_variant_t value) {
        return applier(index, value, context);
      });
}

int64_t
sourcekitd_variant_int64_get_value(sourcekitd_variant_t obj) {
  if (auto fn = VAR_FN(obj, int64_get_value))
    return fn(obj);

  // Default implementation:
  // Assume this is a variant encapsulating the basic type.
  return obj.data[1];
}

bool
sourcekitd_variant_bool_get_value(sourcekitd_variant_t obj) {
  if (auto fn = VAR_FN(obj, bool_get_value))
    return fn(obj);

  // Default implementation:
  // Assume this is a variant encapsulating the basic type.
  return obj.data[1];
}

size_t
sourcekitd_variant_string_get_length(sourcekitd_variant_t obj) {
  if (auto fn = VAR_FN(obj, string_get_length))
    return fn(obj);

  // Default implementation:
  // Use strlen.
  return strlen(sourcekitd_variant_string_get_ptr(obj));
}

const char *
sourcekitd_variant_string_get_ptr(sourcekitd_variant_t obj) {
  if (auto fn = VAR_FN(obj, string_get_ptr))
    return fn(obj);

  // Default implementation:
  // Assume this is a variant encapsulating the basic type.
  return (const char *)obj.data[1];
}

sourcekitd_uid_t
sourcekitd_variant_uid_get_value(sourcekitd_variant_t obj) {
  if (auto fn = VAR_FN(obj, uid_get_value))
    return fn(obj);

  // Default implementation:
  // Assume this is a variant encapsulating the basic type.
  return (sourcekitd_uid_t)obj.data[1];
}

void
sourcekitd_variant_description_dump(sourcekitd_variant_t obj) {
  // Avoid colors here, we don't properly detect that the debug window inside
  // Xcode doesn't support colors.
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printVariant(obj, OS);
  llvm::errs() << OS.str() << '\n';
}

void
sourcekitd_variant_description_dump_filedesc(sourcekitd_variant_t obj, int fd) {
  llvm::raw_fd_ostream OS(fd, /*shouldClose=*/false);
  printVariant(obj, OS);
  OS << '\n';
}

char *
sourcekitd_variant_description_copy(sourcekitd_variant_t obj) {
  llvm::SmallString<128> Desc;
  llvm::raw_svector_ostream OS(Desc);
  printVariant(obj, OS);
  return strdup(Desc.c_str());
}

char *
sourcekitd_variant_json_description_copy(sourcekitd_variant_t obj) {
  llvm::SmallString<128> Desc;
  {
    llvm::raw_svector_ostream OS(Desc);
    VariantPrinter(OS, /*Indent=*/0, /*PrintAsJSON=*/true).visit(obj);
  }
  return strdup(Desc.c_str());
}

namespace {
class YAMLRequestParser {
public:
  sourcekitd_object_t parse(StringRef YAMLStr, std::string &Error);

private:
  sourcekitd_object_t createObjFromNode(llvm::yaml::Node *Value,
                                        std::string &Error);
  bool parseDict(sourcekitd_object_t Dict, llvm::yaml::MappingNode *Node,
                  std::string &Error);
  bool parseArray(sourcekitd_object_t Array, llvm::yaml::SequenceNode *Node,
                   std::string &Error);
  void initError(StringRef Desc, llvm::yaml::Node *Node, std::string &Error);
  sourcekitd_object_t withError(StringRef Desc, llvm::yaml::Node *Node,
                                std::string &Error) {
    initError(Desc, Node, Error);
    return nullptr;
  }
  bool withBoolError(StringRef Desc, llvm::yaml::Node *Node,
                     std::string &Error) {
    initError(Desc, Node, Error);
    return true;
  }
};
} // anonymous namespace

sourcekitd_object_t
sourcekitd_request_create_from_yaml(const char *yaml, char **error) {
  std::string Error;
  sourcekitd_object_t Result = YAMLRequestParser().parse(yaml, Error);
  if (Result)
    return Result;
  if (error)
    *error = strdup(Error.c_str());
  return nullptr;
}

sourcekitd_object_t YAMLRequestParser::parse(StringRef YAMLStr,
                                             std::string &Error) {
  llvm::SourceMgr SM;
  llvm::yaml::Stream YAMLStream(YAMLStr, SM);
  llvm::yaml::document_iterator I = YAMLStream.begin();
  if (I == YAMLStream.end()) {
    Error = "Error while parsing";
    return nullptr;
  }
  llvm::yaml::Node *Root = I->getRoot();
  if (Root == nullptr) {
    Error = "Error while parsing";
    return nullptr;
  }

  return createObjFromNode(Root, Error);
}

sourcekitd_object_t YAMLRequestParser::createObjFromNode(
                                  llvm::yaml::Node *Value, std::string &Error) {
  if (auto Array = dyn_cast<llvm::yaml::SequenceNode>(Value)) {
    sourcekitd_object_t Val = sourcekitd_request_array_create(nullptr, 0);
    if (parseArray(Val, Array, Error)) {
      sourcekitd_request_release(Val);
      return nullptr;
    }
    return Val;
  }

  if (auto Map = dyn_cast<llvm::yaml::MappingNode>(Value)) {
    sourcekitd_object_t Val =
        sourcekitd_request_dictionary_create(nullptr, nullptr, 0);
    if (parseDict(Val, Map, Error)) {
      sourcekitd_request_release(Val);
      return nullptr;
    }
    return Val;
  }

  if (auto ValueString = dyn_cast<llvm::yaml::ScalarNode>(Value)) {
    StringRef Raw = ValueString->getRawValue().trim();
    SmallString<32> ValueStorage;
    if (Raw[0] == '\"') {
      SmallString<32> Str(ValueString->getValue(ValueStorage));
      return sourcekitd_request_string_create(Str.c_str());
    }

    long long val;
    if (!Raw.getAsInteger(10, val))
      return sourcekitd_request_int64_create(val);

    if (Raw.find(' ') != StringRef::npos)
      return withError("Found space in non-string value", Value, Error);

    return sourcekitd_request_uid_create(
        sourcekitd_uid_get_from_buf(Raw.data(), Raw.size()));
  }

  return withError("Expected value as array, dictionary, or scalar", Value,
                   Error);
}


bool YAMLRequestParser::parseDict(sourcekitd_object_t Dict,
                                  llvm::yaml::MappingNode *Node,
                                  std::string &Error) {

  for (llvm::yaml::MappingNode::iterator KVI = Node->begin(),
                                         KVE = Node->end();
       KVI != KVE; ++KVI) {
    llvm::yaml::Node *Value = (*KVI).getValue();
    if (Value == nullptr || isa<llvm::yaml::NullNode>(Value))
      return withBoolError("Expected value", (*KVI).getKey(), Error);

    sourcekitd_object_t Val = createObjFromNode(Value, Error);
    if (!Val)
      return true;

    auto KeyString = dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
    if (KeyString == nullptr) {
      sourcekitd_request_release(Val);
      return withBoolError("Expected string as key", (*KVI).getKey(), Error);
    }

    SmallString<32> KeyStorage;
    StringRef Key = KeyString->getValue(KeyStorage);
    sourcekitd_uid_t uid_key =
        sourcekitd_uid_get_from_buf(Key.data(), Key.size());

    sourcekitd_request_dictionary_set_value(Dict, uid_key, Val);
  }

  return false;
}

bool YAMLRequestParser::parseArray(sourcekitd_object_t Array,
                                   llvm::yaml::SequenceNode *Node,
                                   std::string &Error) {
  for (llvm::yaml::SequenceNode::iterator AI = Node->begin(),
                                          AE = Node->end();
       AI != AE; ++AI) {
    sourcekitd_object_t Val = createObjFromNode(&*AI, Error);
    if (!Val)
      return true;

    sourcekitd_request_array_set_value(Array, SOURCEKITD_ARRAY_APPEND, Val);
  }

  return false;
}

void YAMLRequestParser::initError(StringRef Desc, llvm::yaml::Node *Node,
                                  std::string &Error) {
  Error = Desc;
  Error += " at: ";
  llvm::SMRange Range = Node->getSourceRange();
  StringRef Text(Range.Start.getPointer(),
                 Range.End.getPointer() - Range.Start.getPointer());
  Error.append(Text.begin(), Text.end());
}
