# BSP Extensions

SourceKit-LSP extends the BSP protocol in the following ways.

## `$/cancelRequest`

Notification sent from SourceKit-LSP to the BSP server to cancel a request. If a BSP server doesn’t support cancellation, it should ignore this notification.

Definition is the same as in LSP.

## `build/initialize`

`InitializeBuildResultDataKind` can be `sourceKit`, in which case `InitializeBuildResultData` contains the following data.

```ts
export interface SourceKitInitializeBuildResponseData {
  /** The path at which SourceKit-LSP can store its index database, aggregating data from `indexStorePath`.
   * This should point to a directory that can be exclusively managed by SourceKit-LSP. Its exact location can be arbitrary. */
  indexDatabasePath?: string;

  /** The directory to which the index store is written during compilation, ie. the path passed to `-index-store-path`
   * for `swiftc` or `clang` invocations **/
  indexStorePath?: string;

  /** Whether the server set the `outputPath` property in the `buildTarget/sources` request */
  outputPathsProvider?: bool;

  /** Whether the build server supports the `buildTarget/prepare` request */
  prepareProvider?: bool;

  /** Whether the server implements the `sourcekit/textDocument/sourceKitOptions` request. */
  sourceKitOptionsProvider?: bool;

  /** The files to watch for changes.
   * Changes to these files are sent to the BSP server using `workspace/didChangeWatchedFiles`.
   * `FileSystemWatcher` is the same as in LSP. */
  watchers: [FileSystemWatcher]?
}
```

## `build/logMessage`

Added fields:

```ts
/**
 * Extends BSPs log message grouping by explicitly starting and ending the log for a specific task ID.
 */
structure?: StructuredLogBegin | StructuredLogReport | StructuredLogEnd;
```

With

```ts
/**
 * Indicates the beginning of a new task that may receive updates with `StructuredLogReport` or `StructuredLogEnd`
 * payloads.
 */
export interface StructuredLogBegin {
  kind: 'begin'

  /**
   * A succinct title that can be used to describe the task that started this structured.
   */
  title: string;
}


/**
 * Adds a new log message to a structured log without ending it.
 */
export interface StructuredLogReport {
  kind: 'report';
}

/**
 * Ends a structured log. No more `StructuredLogReport` updates should be sent for this task ID.
 *
 * The task ID may be re-used for new structured logs by beginning a new structured log for that task.
 */
export interface StructuredLogEnd {
  kind: 'end';
}
```

## `build/taskStart`

If `data` contains a string value for the `workDoneProgressTitle` key, then the task's message will be displayed in the client as a work done progress with that title.

## `buildTarget/didChange`

`changes` can be `null` to indicate that all targets have changed.

## `sourcekit/buildTarget/prepare`

The prepare build target request is sent from the client to the server to prepare the given list of build targets for editor functionality.

To do so, the build server should perform any work that is necessary to typecheck the files in the given target. This includes, but is not limited to: Building Swift modules for all dependencies and running code generation scripts. Compared to a full build, the build server may skip actions that are not necessary for type checking, such as object file generation but the exact steps necessary are dependent on the build system. SwiftPM implements this step using the `swift build --experimental-prepare-for-indexing` command.

The server communicates during the initialize handshake whether this method is supported or not by setting `prepareProvider: true` in `SourceKitInitializeBuildResponseData`.

- method: `sourcekit/buildTarget/prepare`
- params: `BuildTargetPrepareRequest`
- result: `BuildTargetPrepareResponse`

> [!NOTE]
> This request was previously named `buildTarget/prepare`. The old name is still accepted for backward compatibility.

```ts
export interface BuildTargetPrepareRequest {
  /** A list of build targets to prepare. */
  targets: BuildTargetIdentifier[];

  /** A unique identifier generated by the client to identify this request.
   * The server may include this id in triggered notifications or responses. **/
  originId?: OriginId;
}

export interface BuildTargetPrepareResponse {
  /**
   * Targets that were implicitly prepared by the prepare request.
   *
   * For example, a target may be implicitly prepared if one if its dependents gets prepared.
   *
   * When omitted, this is the same as an empty array.
   */
  implicitlyPreparedTargets?: BuildTargetIdentifier[]
}
```

## `buildTarget/sources`

`SourceItemDataKind` can be `sourceKit` in which case `SourceItem.data` contains the following data.

```ts
export interface SourceKitSourceItemData {
  /** The language of the source file. If `nil`, the language is inferred from the file extension. */
  language?: LanguageId;

  /**
   * The kind of source file that this source item represents. If omitted, the item is assumed to be a normal source
   * file, ie. omitting this key is equivalent to specifying it as `source`.
   */
  kind?: "source" | "header" | "doccCatalog";

  /**
   * The output path that is a string that uniquely identifies the index output of this file in this target. If an index
   * store should be re-used between build and background indexing, it must match the `-o` path or
   * `-index-unit-output-path` used during the build.
   *
   * The index unit output path historically matched the path used for `-o` during compilation but has since evolved to
   * be an opaque string. In particular, it does not have to match to any file on disk.
   *
   * This allows SourceKit-LSP to remove index entries for source files that are removed from a target but remain
   * present on disk and to index a file that is part of multiple targets in the context of each target.
   *
   * The server communicates during the initialize handshake whether it populates this property by setting
   * `outputPathsProvider: true` in `SourceKitInitializeBuildResponseData`.
   */
  outputPath?: string;

  /**
   * If this source item gets copied to a different destination during preparation, the destinations it will be copied
   * to.
   *
   * If a user action would jump to one of these copied files, this allows SourceKit-LSP to redirect the navigation to
   * the original source file instead of jumping to a file in the build directory.
   */
  copyDestinations?: DocumentURI[];
}
```

## `sourcekit/textDocument/sourceKitOptions`

The `TextDocumentSourceKitOptionsRequest` request is sent from the client to the server to query for the list of compiler options necessary to compile this file in the given target.

The build settings are considered up-to-date and can be cached by SourceKit-LSP until a `buildTarget/didChange` is sent for the requested target.

The request may return `nil` if it doesn't have any build settings for this file in the given target.

- method: `sourcekit/textDocument/sourceKitOptions`
- params: `TextDocumentSourceKitOptionsParams`
- result: `TextDocumentSourceKitOptionsResult`

> [!NOTE]
> This request was previously named `textDocument/sourceKitOptions`. The old name is still accepted for backward compatibility.

Also note that the `data` field in `TextDocumentSourceKitOptionsResult` is exposed to LSP clients via `sourcekit/workspace/sourceKitOptions` (previously `workspace/_sourceKitOptions`).

```ts
export interface TextDocumentSourceKitOptionsRequest {
  /** The URI of the document to get options for */
  textDocument: TextDocumentIdentifier;

  /** The target for which the build setting should be returned.
   *
   * A source file might be part of multiple targets and might have different compiler arguments in those two targets,
   * thus the target is necessary in this request. **/
  target: BuildTargetIdentifier;

  /** The language with which the document was opened in the editor. */
  language: LanguageId;
}

export interface TextDocumentSourceKitOptionsResult {
  /** The compiler options required for the requested file. */
  compilerArguments: string[];

  /** The working directory for the compile command. */
  workingDirectory?: string;

  /** Additional data that will not be interpreted by SourceKit-LSP but made available to clients in the
   * `workspace/_sourceKitOptions` LSP requests. */
  data?: LSPAny;
}
```

## `workspace/buildTargets`

`BuildTargetTag` can have the following additional values

```ts
export interface BuildTargetTag {
  // ...

  /** This is a target of a dependency from the project the user opened, eg. a target that builds a SwiftPM dependency. */
  export const Dependency = "dependency";

  /** This target only exists to provide compiler arguments for SourceKit-LSP can't be built standalone.
   *
   * For example, a SwiftPM package manifest is in a non-buildable target. **/
  export const NotBuildable = "not-buildable";
}
```

`BuildTargetDataKind` can be `sourceKit` in which case `BuildTarget.data` contains the following data.


```ts
export interface SourceKitBuildTarget {
  /** The toolchain that should be used to build this target. The URI should point to the directory that contains the
   * `usr` directory. On macOS, this is typically a bundle ending in `.xctoolchain`. If the toolchain is installed to
   * `/` on Linux, the toolchain URI would point to `/`.
   *
   * If no toolchain is given, SourceKit-LSP will pick a toolchain to use for this target. **/
  toolchain?: URI;
}
```

## `workspace/didChangeWatchedFiles`

Notification sent from SourceKit-LSP to the build server to indicate that files within the project have been modified.

SourceKit-LSP may send file change notifications for a superset of the files that the BSP server requested to watch in `watchers`. It is the BSP server’s responsibility to filter the file watch notifications for the ones it is actually interested in.

Definition is the same as in LSP.

## `sourcekit/workspace/waitForBuildSystemUpdates`

This request is a no-op and doesn't have any effects.

If the build server is currently updating the build graph, this request should return after those updates have finished processing.

- method: `sourcekit/workspace/waitForBuildSystemUpdates`

> [!NOTE]
> This request was previously named `workspace/waitForBuildSystemUpdates`. The old name is still accepted for backward compatibility.
