in Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift [189:258]
func parseAndHandleMessages(from bytes: UnsafeBufferPointer<UInt8>) -> UnsafeBufferPointer<UInt8>.SubSequence {
let decoder = JSONDecoder()
// Set message registry to use for model decoding.
decoder.userInfo[.messageRegistryKey] = messageRegistry
// Setup callback for response type.
decoder.userInfo[.responseTypeCallbackKey] = { id in
guard let outstanding = self.outstandingRequests[id] else {
log("Unknown request for \(id)", level: .error)
return nil
}
return outstanding.responseType
} as JSONRPCMessage.ResponseTypeCallback
var bytes = bytes[...]
MESSAGE_LOOP: while true {
do {
guard let ((messageBytes, _), rest) = try bytes.jsonrpcSplitMessage() else {
return bytes
}
bytes = rest
let pointer = UnsafeMutableRawPointer(mutating: UnsafeBufferPointer(rebasing: messageBytes).baseAddress!)
let message = try decoder.decode(JSONRPCMessage.self, from: Data(bytesNoCopy: pointer, count: messageBytes.count, deallocator: .none))
handle(message)
} catch let error as MessageDecodingError {
switch error.messageKind {
case .request:
if let id = error.id {
_send(.errorResponse(ResponseError(error), id: id))
continue MESSAGE_LOOP
}
case .response:
if let id = error.id {
if let outstanding = self.outstandingRequests.removeValue(forKey: id) {
outstanding.replyHandler(.failure(ResponseError(error)))
} else {
log("error in response to unknown request \(id) \(error)", level: .error)
}
continue MESSAGE_LOOP
}
case .notification:
if error.code == .methodNotFound {
log("ignoring unknown notification \(error)")
continue MESSAGE_LOOP
}
case .unknown:
_send(.errorResponse(ResponseError(error), id: nil),
async: false) // synchronous because the following fatalError
break
}
// FIXME: graceful shutdown?
fatalError("fatal error encountered decoding message \(error)")
} catch {
let responseError = ResponseError(code: .parseError,
message: "Failed to decode message. \(error.localizedDescription)")
_send(.errorResponse(responseError, id: nil),
async: false) // synchronous because the following fatalError
// FIXME: graceful shutdown?
fatalError("fatal error encountered decoding message \(error)")
}
}
}