//===--- sourcekitdAPI-XPC.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/CodeCompletionResultsArray.h"
#include "sourcekitd/DocStructureArray.h"
#include "sourcekitd/DocSupportAnnotationArray.h"
#include "sourcekitd/TokenAnnotationsArray.h"
#include "sourcekitd/RequestResponsePrinterBase.h"
#include "SourceKit/Support/UIdent.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
#include <xpc/xpc.h>

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

namespace {

class CustomXPCData {
public:
  enum class Kind : char {
    ErrorRequestInvalid,
    ErrorRequestFailed,
    ErrorRequestInterrupted,
    ErrorRequestCancelled
  };

  explicit CustomXPCData(xpc_object_t xobj) : XObj(xobj) {
    assert(xpc_get_type(XObj) == XPC_TYPE_DATA);
    assert(getLength() > 0);
  }

  xpc_object_t getXObj() const { return XObj; }

  Kind getKind() const { return Kind(getPtr()[0]); }

  const char *getPtr() const {
    return (const char *)xpc_data_get_bytes_ptr(XObj);
  }
  size_t getLength() const {
    return xpc_data_get_length(XObj);
  }

  bool isError() const {
    return true; // No other kind for now.
  }

  const char *getErrorDescription() const {
    assert(isError());
    assert(getLength() > 1);
    return getPtr()+1;
  }

  static CustomXPCData createErrorRequestInvalid(const char *Description) {
    return createKindAndString(Kind::ErrorRequestInvalid, Description);
  }
  static CustomXPCData createErrorRequestFailed(const char *Description) {
    return createKindAndString(Kind::ErrorRequestFailed, Description);
  }
  static CustomXPCData createErrorRequestInterrupted(const char *Description) {
    return createKindAndString(Kind::ErrorRequestInterrupted, Description);
  }
  static CustomXPCData createErrorRequestCancelled(const char *Description) {
    return createKindAndString(Kind::ErrorRequestCancelled, Description);
  }

private:
  static CustomXPCData createKindAndString(Kind K, const char *Str) {
    llvm::SmallVector<char, 128> Buf;
    Buf.push_back((char)K);
    Buf.append(Str, Str+strlen(Str)+1);
    return CustomXPCData(xpc_data_create(Buf.begin(), Buf.size()));
  }

  xpc_object_t XObj;
};

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

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

  RetTy visit(sourcekitd_object_t Obj) {
    xpc_type_t XType = xpc_get_type(Obj);
    if (XType == XPC_TYPE_DICTIONARY) {
      DictMap Dict;
      DictMap &DictRef = Dict;
      xpc_dictionary_apply(Obj, ^(const char *Key, xpc_object_t Value) {
        UIdent UID = UIdent(Key);
        DictRef.push_back({ UID, Value });
        return true;
      });
      std::sort(Dict.begin(), Dict.end(), compKeys);
      return static_cast<ImplClass*>(this)->visitDictionary(Dict);
    }
    if (XType == XPC_TYPE_ARRAY) {
      std::vector<sourcekitd_object_t> Vec;
      for (size_t i = 0, e = xpc_array_get_count(Obj); i != e; ++i)
        Vec.push_back(xpc_array_get_value(Obj, i));
      return static_cast<ImplClass*>(this)->visitArray(Vec);
    }
    if (XType == XPC_TYPE_INT64)
      return static_cast<ImplClass*>(this)->visitInt64(xpc_int64_get_value(Obj));
    if (XType == XPC_TYPE_STRING) {
      size_t Len = xpc_string_get_length(Obj);
      const char *Ptr = xpc_string_get_string_ptr(Obj);
      return static_cast<ImplClass*>(this)->visitString(StringRef(Ptr, Len));
    }
    if (XType == XPC_TYPE_UINT64) {
      sourcekitd_uid_t SKDUID = sourcekitd_uid_t(xpc_uint64_get_value(Obj));
      UIdent UID = UIdentFromSKDUID(SKDUID);
      return static_cast<ImplClass*>(this)->visitUID(UID.getName());
    }

    llvm_unreachable("unknown sourcekitd_object_t");
  }
};

class SKDObjectPrinter : public SKDObjectVisitor<SKDObjectPrinter>,
                         public RequestResponsePrinterBase<SKDObjectPrinter,
                                                           sourcekitd_object_t> {
public:
  SKDObjectPrinter(raw_ostream &OS, unsigned Indent = 0)
    : RequestResponsePrinterBase(OS, Indent) { }
};

} // anonymous namespace

void sourcekitd::printRequestObject(sourcekitd_object_t Obj, raw_ostream &OS) {
  if (!Obj) {
    OS << "<<NULL>>";
    return;
  }

  SKDObjectPrinter(OS).visit(Obj);
}

//===----------------------------------------------------------------------===//
// Internal API
//===----------------------------------------------------------------------===//

ResponseBuilder::ResponseBuilder() {
  Impl = xpc_dictionary_create(nullptr, nullptr, 0);
}

ResponseBuilder::~ResponseBuilder() {
  xpc_release(Impl);
}

ResponseBuilder::ResponseBuilder(const ResponseBuilder &Other) {
  Impl = xpc_retain(Other.Impl);
}

ResponseBuilder &ResponseBuilder::operator =(const ResponseBuilder &Other) {
  xpc_object_t Tmp = xpc_retain(Other.Impl);
  xpc_release(Impl);
  Impl = Tmp;
  return *this;
}

ResponseBuilder::Dictionary ResponseBuilder::getDictionary() {
  return Dictionary(Impl);
}

sourcekitd_response_t ResponseBuilder::createResponse() {
  return xpc_retain(Impl);
}

void ResponseBuilder::Dictionary::set(UIdent Key, SourceKit::UIdent UID) {
  set(Key, SKDUIDFromUIdent(UID));
}

void ResponseBuilder::Dictionary::set(UIdent Key, sourcekitd_uid_t UID) {
  xpc_dictionary_set_uint64(Impl, Key.c_str(), uintptr_t(UID));
}

void ResponseBuilder::Dictionary::set(UIdent Key, const char *Str) {
  xpc_dictionary_set_string(Impl, Key.c_str(), Str);
}

void ResponseBuilder::Dictionary::set(UIdent Key, llvm::StringRef Str) {
  llvm::SmallString<512> Buf(Str);
  xpc_dictionary_set_string(Impl, Key.c_str(), Buf.c_str());
}

void ResponseBuilder::Dictionary::set(UIdent Key, int64_t val) {
  xpc_dictionary_set_int64(Impl, Key.c_str(), val);
}

void ResponseBuilder::Dictionary::set(SourceKit::UIdent Key,
                                      ArrayRef<StringRef> Strs) {
  llvm::SmallString<128> Buf;
  xpc_object_t arr = xpc_array_create(nullptr, 0);
  for (auto Str : Strs) {
    Buf = Str;
    xpc_array_set_string(arr, XPC_ARRAY_APPEND, Buf.c_str());
  }
  xpc_dictionary_set_value(Impl, Key.c_str(), arr);
  xpc_release(arr);
}

void ResponseBuilder::Dictionary::setBool(UIdent Key, bool val) {
  xpc_dictionary_set_bool(Impl, Key.c_str(), val);
}

ResponseBuilder::Array
ResponseBuilder::Dictionary::setArray(UIdent Key) {
  xpc_object_t arr = xpc_array_create(nullptr, 0);
  xpc_dictionary_set_value(Impl, Key.c_str(), arr);
  xpc_release(arr);
  return Array(arr);
}

ResponseBuilder::Dictionary
ResponseBuilder::Dictionary::setDictionary(UIdent Key) {
  xpc_object_t dict = xpc_dictionary_create(nullptr, nullptr, 0);
  xpc_dictionary_set_value(Impl, Key.c_str(), dict);
  xpc_release(dict);
  return Dictionary(dict);
}

void ResponseBuilder::Dictionary::setCustomBuffer(
      SourceKit::UIdent Key,
      CustomBufferKind Kind, std::unique_ptr<llvm::MemoryBuffer> MemBuf) {

  std::unique_ptr<llvm::MemoryBuffer> CustomBuf;
  CustomBuf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
      sizeof(uint64_t) + MemBuf->getBufferSize());
  char *BufPtr = (char*)CustomBuf->getBufferStart();
  *reinterpret_cast<uint64_t*>(BufPtr) = (uint64_t)Kind;
  BufPtr += sizeof(uint64_t);
  memcpy(BufPtr, MemBuf->getBufferStart(), MemBuf->getBufferSize());

  xpc_object_t xdata = xpc_data_create(CustomBuf->getBufferStart(),
                                       CustomBuf->getBufferSize());
  xpc_dictionary_set_value(Impl, Key.c_str(), xdata);
  xpc_release(xdata);
}

ResponseBuilder::Dictionary ResponseBuilder::Array::appendDictionary() {
  xpc_object_t dict = xpc_dictionary_create(nullptr, nullptr, 0);
  xpc_array_append_value(Impl, dict);
  xpc_release(dict);
  return Dictionary(dict);
}

sourcekitd_uid_t RequestDict::getUID(UIdent Key) {
  return sourcekitd_uid_t(xpc_dictionary_get_uint64(Dict, Key.c_str()));
}

Optional<StringRef> RequestDict::getString(UIdent Key) {
  xpc_object_t xobj = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xobj)
    return None;
  if (xpc_get_type(xobj) != XPC_TYPE_STRING)
    return None;
  return StringRef(xpc_string_get_string_ptr(xobj),
                   xpc_string_get_length(xobj));
}

Optional<RequestDict> RequestDict::getDictionary(SourceKit::UIdent Key) {
  xpc_object_t xobj = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xobj)
    return None;
  if (xpc_get_type(xobj) != XPC_TYPE_DICTIONARY)
    return None;
  return RequestDict(xobj);
}

bool RequestDict::getStringArray(SourceKit::UIdent Key,
                                 llvm::SmallVectorImpl<const char *> &Arr,
                                 bool isOptional) {
  xpc_object_t xarr = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xarr)
    return !isOptional;
  if (xpc_get_type(xarr) != XPC_TYPE_ARRAY)
    return true;
  size_t count = xpc_array_get_count(xarr);
  Arr.reserve(count);
  for (size_t i = 0; i != count; ++i) {
    const char *Str = xpc_array_get_string(xarr, i);
    if (!Str)
      return true;
    Arr.push_back(Str);
  }
  return false;
}

bool RequestDict::getUIDArray(SourceKit::UIdent Key,
                              llvm::SmallVectorImpl<sourcekitd_uid_t> &Arr,
                              bool isOptional) {
  xpc_object_t xarr = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xarr)
    return !isOptional;
  if (xpc_get_type(xarr) != XPC_TYPE_ARRAY)
    return true;
  size_t count = xpc_array_get_count(xarr);
  Arr.reserve(count);
  for (size_t i = 0; i != count; ++i) {
    auto UID = sourcekitd_uid_t(xpc_array_get_uint64(xarr, i));
    if (!UID)
      return true;
    Arr.push_back(UID);
  }
  return false;
}

bool RequestDict::dictionaryArrayApply(
    SourceKit::UIdent key, llvm::function_ref<bool(RequestDict)> applier) {
  xpc_object_t xarr = xpc_dictionary_get_value(Dict, key.c_str());
  if (!xarr || xpc_get_type(xarr) != XPC_TYPE_ARRAY)
    return true;
  size_t count = xpc_array_get_count(xarr);
  for (size_t i = 0; i != count; ++i) {
    auto xdict = xpc_array_get_value(xarr, i);
    if (!xdict || xpc_get_type(xdict) != XPC_TYPE_DICTIONARY)
      return true;
    if (applier(RequestDict(xdict)))
      return true;
  }
  return false;
}

bool RequestDict::getInt64(SourceKit::UIdent Key, int64_t &Val,
                           bool isOptional) {
  xpc_object_t xobj = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xobj)
    return !isOptional;
  Val = xpc_int64_get_value(xobj);
  return false;
}

Optional<int64_t> RequestDict::getOptionalInt64(SourceKit::UIdent Key) {
  xpc_object_t xobj = xpc_dictionary_get_value(Dict, Key.c_str());
  if (!xobj)
    return None;
  return xpc_int64_get_value(xobj);
}

sourcekitd_response_t
sourcekitd::createErrorRequestInvalid(const char *Description) {
  return CustomXPCData::createErrorRequestInvalid(Description).getXObj();
}
sourcekitd_response_t
sourcekitd::createErrorRequestFailed(const char *Description) {
  return CustomXPCData::createErrorRequestFailed(Description).getXObj();
}
sourcekitd_response_t
sourcekitd::createErrorRequestInterrupted(const char *Description) {
  return CustomXPCData::createErrorRequestInterrupted(Description).getXObj();
}
sourcekitd_response_t
sourcekitd::createErrorRequestCancelled() {
  return CustomXPCData::createErrorRequestCancelled("").getXObj();
}

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

static inline const char *strFromUID(sourcekitd_uid_t uid) {
  return UIdentFromSKDUID(uid).c_str();
}

sourcekitd_object_t
sourcekitd_request_retain(sourcekitd_object_t object) {
  return xpc_retain(object);
}

void sourcekitd_request_release(sourcekitd_object_t object) {
  xpc_release(object);
}

sourcekitd_object_t
sourcekitd_request_dictionary_create(const sourcekitd_uid_t *keys,
                                     const sourcekitd_object_t *values,
                                     size_t count) {
  llvm::SmallVector<const char *, 8> Keys;
  Keys.reserve(count);
  for (size_t i = 0; i < count; ++i)
    Keys.push_back(strFromUID(keys[i]));
  return xpc_dictionary_create(Keys.data(), values, count);
}

void
sourcekitd_request_dictionary_set_value(sourcekitd_object_t dict,
                                        sourcekitd_uid_t key,
                                        sourcekitd_object_t value) {
  xpc_dictionary_set_value(dict, strFromUID(key), value);
}

void sourcekitd_request_dictionary_set_string(sourcekitd_object_t dict,
                                              sourcekitd_uid_t key,
                                              const char *string) {
  xpc_dictionary_set_string(dict, strFromUID(key), string);
}

void
sourcekitd_request_dictionary_set_stringbuf(sourcekitd_object_t dict,
                                            sourcekitd_uid_t key,
                                            const char *buf, size_t length) {
  llvm::SmallString<512> SS;
  SS += StringRef(buf, length);
  sourcekitd_request_dictionary_set_string(dict, key, SS.c_str());
}

void sourcekitd_request_dictionary_set_int64(sourcekitd_object_t dict,
                                             sourcekitd_uid_t key,
                                             int64_t val) {
  xpc_dictionary_set_int64(dict, strFromUID(key), val);
}

void
sourcekitd_request_dictionary_set_uid(sourcekitd_object_t dict,
                                      sourcekitd_uid_t key,
                                      sourcekitd_uid_t uid) {
  xpc_dictionary_set_uint64(dict, strFromUID(key), uintptr_t(uid));
}

sourcekitd_object_t
sourcekitd_request_array_create(const sourcekitd_object_t *objects,
                                size_t count) {
  return xpc_array_create(objects, count);
}

void
sourcekitd_request_array_set_value(sourcekitd_object_t array, size_t index,
                                   sourcekitd_object_t value) {
  xpc_array_set_value(array, index, value);
}

void
sourcekitd_request_array_set_string(sourcekitd_object_t array, size_t index,
                                    const char *string) {
  xpc_array_set_string(array, index, string);
}

void
sourcekitd_request_array_set_stringbuf(sourcekitd_object_t array, size_t index,
                                       const char *buf, size_t length) {
  llvm::SmallString<512> SS;
  SS += StringRef(buf, length);
  sourcekitd_request_array_set_string(array, index, SS.c_str());
}

void
sourcekitd_request_array_set_int64(sourcekitd_object_t array, size_t index,
                                   int64_t val) {
  xpc_array_set_int64(array, index, val);
}

void
sourcekitd_request_array_set_uid(sourcekitd_object_t array, size_t index,
                                 sourcekitd_uid_t uid) {
  xpc_array_set_uint64(array, index, uintptr_t(uid));
}

sourcekitd_object_t
sourcekitd_request_int64_create(int64_t val) {
  return xpc_int64_create(val);
}

sourcekitd_object_t
sourcekitd_request_string_create(const char *string) {
  return xpc_string_create(string);
}

sourcekitd_object_t
sourcekitd_request_uid_create(sourcekitd_uid_t uid) {
  return xpc_uint64_create(uintptr_t(uid));
}

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

void
sourcekitd_response_dispose(sourcekitd_response_t obj) {
  xpc_release(obj);
}

bool
sourcekitd_response_is_error(sourcekitd_response_t obj) {
  xpc_type_t type = xpc_get_type(obj);
  if (type == XPC_TYPE_ERROR)
    return true;
  if (type == XPC_TYPE_DATA) {
    CustomXPCData Dat(obj);
    return Dat.isError();
  }
  return false;
}

sourcekitd_error_t
sourcekitd_response_error_get_kind(sourcekitd_response_t obj) {
  xpc_type_t type = xpc_get_type(obj);
  if (type == XPC_TYPE_ERROR) {
    if (obj == XPC_ERROR_CONNECTION_INTERRUPTED)
      return SOURCEKITD_ERROR_CONNECTION_INTERRUPTED;
    // This can originate if the client initiated shutdown.
    if (obj == XPC_ERROR_CONNECTION_INVALID)
      return SOURCEKITD_ERROR_REQUEST_CANCELLED;
  }
  if (type == XPC_TYPE_DATA) {
    CustomXPCData Dat(obj);
    switch (Dat.getKind()) {
      case CustomXPCData::Kind::ErrorRequestInvalid:
        return SOURCEKITD_ERROR_REQUEST_INVALID;
      case CustomXPCData::Kind::ErrorRequestFailed:
        return SOURCEKITD_ERROR_REQUEST_FAILED;
      case CustomXPCData::Kind::ErrorRequestInterrupted:
        return SOURCEKITD_ERROR_CONNECTION_INTERRUPTED;
      case CustomXPCData::Kind::ErrorRequestCancelled:
        return SOURCEKITD_ERROR_REQUEST_CANCELLED;
    }
  }
  
  llvm::report_fatal_error("sourcekitd error did not resolve to a known kind");
}

const char *
sourcekitd_response_error_get_description(sourcekitd_response_t obj) {
  xpc_type_t type = xpc_get_type(obj);
  if (type == XPC_TYPE_ERROR)
    return xpc_dictionary_get_string(obj, XPC_ERROR_KEY_DESCRIPTION);
  if (type == XPC_TYPE_DATA) {
    CustomXPCData Dat(obj);
    if (Dat.isError())
      return Dat.getErrorDescription();
  }
  
  llvm::report_fatal_error("invalid sourcekitd error object");
}

static sourcekitd_variant_t variantFromXPCObject(xpc_object_t obj);

sourcekitd_variant_t
sourcekitd_response_get_value(sourcekitd_response_t resp) {
  if (sourcekitd_response_is_error(resp))
    return makeNullVariant();
  return variantFromXPCObject(resp);
}

//===----------------------------------------------------------------------===//
// Variant functions
//===----------------------------------------------------------------------===//

#define XPC_OBJ(var) ((xpc_object_t)(var).data[1])

#define CUSTOM_BUF_KIND(xobj) \
  ((CustomBufferKind)*(uint64_t*)xpc_data_get_bytes_ptr(xobj))
#define CUSTOM_BUF_START(xobj) \
  ((void*)(((uint64_t*)xpc_data_get_bytes_ptr(xobj))+1))

static sourcekitd_variant_type_t XPCVar_get_type(sourcekitd_variant_t var) {
  xpc_object_t obj = XPC_OBJ(var);
  
  xpc_type_t type = xpc_get_type(obj);
  if (type == XPC_TYPE_DICTIONARY)
    return SOURCEKITD_VARIANT_TYPE_DICTIONARY;
  if (type == XPC_TYPE_ARRAY)
    return SOURCEKITD_VARIANT_TYPE_ARRAY;
  if (type == XPC_TYPE_INT64)
    return SOURCEKITD_VARIANT_TYPE_INT64;
  if (type == XPC_TYPE_BOOL)
    return SOURCEKITD_VARIANT_TYPE_BOOL;
  if (type == XPC_TYPE_STRING)
    return SOURCEKITD_VARIANT_TYPE_STRING;
  // Take over XPC's UINT64 to mean SourceKitD's UID.
  // This means that UINT64 will not be available to be constructed in a
  // sourcekitd message.
  if (type == XPC_TYPE_UINT64)
    return SOURCEKITD_VARIANT_TYPE_UID;

  if (type == XPC_TYPE_DATA) {
    switch(CUSTOM_BUF_KIND(obj)) {
    case CustomBufferKind::TokenAnnotationsArray:
      return SOURCEKITD_VARIANT_TYPE_ARRAY;
    case CustomBufferKind::DocSupportAnnotationArray:
      return SOURCEKITD_VARIANT_TYPE_ARRAY;
    case CustomBufferKind::CodeCompletionResultsArray:
      return SOURCEKITD_VARIANT_TYPE_ARRAY;
    case CustomBufferKind::DocStructureArray:
    case CustomBufferKind::InheritedTypesArray:
    case CustomBufferKind::DocStructureElementArray:
    case CustomBufferKind::AttributesArray:
      return SOURCEKITD_VARIANT_TYPE_ARRAY;
    }
  }

  llvm::report_fatal_error("sourcekitd object did not resolve to a known type");
}

static bool XPCVar_array_apply(
    sourcekitd_variant_t array,
    llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
  return xpc_array_apply(XPC_OBJ(array),
                         ^(size_t index, xpc_object_t obj) {
    return applier(index, variantFromXPCObject(obj));
  });
}

static bool XPCVar_array_get_bool(sourcekitd_variant_t array, size_t index) {
  return xpc_array_get_bool(XPC_OBJ(array), index);
}

static size_t XPCVar_array_get_count(sourcekitd_variant_t array) {
  return xpc_array_get_count(XPC_OBJ(array));
}

static int64_t XPCVar_array_get_int64(sourcekitd_variant_t array, size_t index) {
  return xpc_array_get_int64(XPC_OBJ(array), index);
}

static const char *
XPCVar_array_get_string(sourcekitd_variant_t array, size_t index) {
  return xpc_array_get_string(XPC_OBJ(array), index);
}

static sourcekitd_uid_t XPCVar_array_get_uid(sourcekitd_variant_t array, size_t index) {
  return sourcekitd_uid_t(xpc_array_get_uint64(XPC_OBJ(array), index));
}

static sourcekitd_variant_t
XPCVar_array_get_value(sourcekitd_variant_t array, size_t index) {
  return variantFromXPCObject(xpc_array_get_value(XPC_OBJ(array), index));
}

static bool XPCVar_bool_get_value(sourcekitd_variant_t obj) {
  return xpc_bool_get_value(XPC_OBJ(obj));
}

static bool XPCVar_dictionary_apply(
    sourcekitd_variant_t dict,
    llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
  return xpc_dictionary_apply(XPC_OBJ(dict),
                              ^(const char *key, xpc_object_t obj) {
    return applier(sourcekitd_uid_get_from_cstr(key),variantFromXPCObject(obj));
  });
}

static bool
XPCVar_dictionary_get_bool(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
  return xpc_dictionary_get_bool(XPC_OBJ(dict), strFromUID(key));
}

static int64_t
XPCVar_dictionary_get_int64(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
  return xpc_dictionary_get_int64(XPC_OBJ(dict), strFromUID(key));
}

static const char *
XPCVar_dictionary_get_string(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
  return xpc_dictionary_get_string(XPC_OBJ(dict), strFromUID(key));
}

static sourcekitd_variant_t
XPCVar_dictionary_get_value(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
  return variantFromXPCObject(
                xpc_dictionary_get_value(XPC_OBJ(dict), strFromUID(key)));
}

static sourcekitd_uid_t
XPCVar_dictionary_get_uid(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
  return sourcekitd_uid_t(
               xpc_dictionary_get_uint64(XPC_OBJ(dict), strFromUID(key)));
}

static size_t XPCVar_string_get_length(sourcekitd_variant_t obj) {
  return xpc_string_get_length(XPC_OBJ(obj));
}

static const char *XPCVar_string_get_ptr(sourcekitd_variant_t obj) {
  return xpc_string_get_string_ptr(XPC_OBJ(obj));
}

static int64_t XPCVar_int64_get_value(sourcekitd_variant_t obj) {
  return xpc_int64_get_value(XPC_OBJ(obj));
}

static sourcekitd_uid_t XPCVar_uid_get_value(sourcekitd_variant_t obj) {
  return sourcekitd_uid_t(xpc_uint64_get_value(XPC_OBJ(obj)));
}


static VariantFunctions XPCVariantFuncs = {
  XPCVar_get_type,
  XPCVar_array_apply,
  XPCVar_array_get_bool,
  XPCVar_array_get_count,
  XPCVar_array_get_int64,
  XPCVar_array_get_string,
  XPCVar_array_get_uid,
  XPCVar_array_get_value,
  XPCVar_bool_get_value,
  XPCVar_dictionary_apply,
  XPCVar_dictionary_get_bool,
  XPCVar_dictionary_get_int64,
  XPCVar_dictionary_get_string,
  XPCVar_dictionary_get_value,
  XPCVar_dictionary_get_uid,
  XPCVar_string_get_length,
  XPCVar_string_get_ptr,
  XPCVar_int64_get_value,
  XPCVar_uid_get_value
};

static sourcekitd_variant_t variantFromXPCObject(xpc_object_t obj) {
  if (!obj)
    return makeNullVariant();

  if (xpc_get_type(obj) == XPC_TYPE_DATA) {
    switch(CUSTOM_BUF_KIND(obj)) {
    case CustomBufferKind::TokenAnnotationsArray:
      return {{ (uintptr_t)getVariantFunctionsForTokenAnnotationsArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    case CustomBufferKind::DocSupportAnnotationArray:
      return {{ (uintptr_t)getVariantFunctionsForDocSupportAnnotationArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    case CustomBufferKind::CodeCompletionResultsArray:
      return {{ (uintptr_t)getVariantFunctionsForCodeCompletionResultsArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    case CustomBufferKind::DocStructureArray:
      return {{ (uintptr_t)getVariantFunctionsForDocStructureArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), ~size_t(0) }};
    case CustomBufferKind::InheritedTypesArray:
      return {{ (uintptr_t)getVariantFunctionsForInheritedTypesArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    case CustomBufferKind::DocStructureElementArray:
      return {{ (uintptr_t)getVariantFunctionsForDocStructureElementArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    case CustomBufferKind::AttributesArray:
      return {{ (uintptr_t)getVariantFunctionsForAttributesArray(),
                (uintptr_t)CUSTOM_BUF_START(obj), 0 }};
    }
  }

  return {{ (uintptr_t)&XPCVariantFuncs, (uintptr_t)obj, 0 }};
}
