# 機能設計書 1-初期化 (initialize)

## 概要

本ドキュメントは、serve-d LSPサーバーにおける初期化 (initialize) 機能の設計を記述する。LSPクライアントからのinitializeリクエストを処理し、サーバーのケイパビリティを構築して返却する。

### 本機能の処理概要

LSPプロトコルにおけるサーバー起動の最初のハンドシェイクとして、クライアントから送信されるinitializeリクエストを受け取り、serve-dが対応する全機能（補完・定義ジャンプ・フォーマット・コードアクション・コードレンズ等）の一覧をServerCapabilitiesとして返却する処理である。

**業務上の目的・背景**：LSP（Language Server Protocol）では、クライアントとサーバー間で最初に機能交渉（capability negotiation）を行う必要がある。この初期化処理が正しく行われなければ、エディタ側はサーバーがどの機能を提供しているか判断できず、コード補完や定義ジャンプなどの一切の機能を利用できない。serve-dが対応する全てのD言語開発支援機能をクライアントに正確に伝えるために本機能が存在する。

**機能の利用シーン**：エディタ（VSCode等）がserve-dプロセスを起動し、最初のJSON-RPCリクエストとしてinitializeを送信する場面で利用される。サーバーのライフサイクル中で一度だけ実行される。

**主要な処理内容**：
1. クライアントから渡されたInitializeParamsからトレースレベル・ケイパビリティ・ワークスペースフォルダ情報を取得
2. ワークスペースフォルダの一覧をWorkspace構造体の配列として内部に保持
3. ワークスペースが0個の場合は一時フォルダをフォールバックワークスペースとして設定
4. ServerCapabilitiesを構築（テキスト同期・補完・シグネチャヘルプ・定義・ホバー・参照・リネーム・コードアクション・コードレンズ・フォーマット・折りたたみ・インレイヒント・ドキュメントシンボル・ワークスペースシンボル・カラー等）
5. サーバー情報（名前・バージョン）を付加してInitializeResultを返却

**関連システム・外部連携**：LSPクライアント（VSCode拡張等）との標準LSPプロトコルに基づく通信。

**権限による制御**：特に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | LSPサーバー初期化（initialize） | 主機能 | クライアントからのinitializeリクエストを受け取り、サーバーケイパビリティを構築して返却する主処理 |
| 2 | グローバルスタートアップ | 補助機能 | initialize完了後にensureStartedUp経由でグローバルスタートアップが呼び出される |

## 機能種別

データ連携（LSPプロトコル初期化・ケイパビリティ交渉）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| params | InitializeParams | Yes | LSP InitializeParams。クライアント情報・ケイパビリティ・ワークスペースフォルダ等を含む | LSPプロトコル仕様に準拠 |
| params.trace | string | No | トレースレベル。"verbose"の場合にログ詳細化 | "off" / "messages" / "verbose" |
| params.capabilities | ClientCapabilities | Yes | クライアントの対応機能一覧 | なし |
| params.workspaceFolders | WorkspaceFolder[] | No | ワークスペースフォルダの一覧 | Nullable |

### 入力データソース

LSPクライアントからのJSON-RPCリクエスト（メソッド名: "initialize"）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| capabilities | ServerCapabilities | サーバーが対応する全機能一覧 |
| capabilities.textDocumentSync | TextDocumentSyncOptions | テキスト同期方式（openClose: true, change: incremental, save: テキスト含まず） |
| capabilities.completionProvider | CompletionOptions | 補完プロバイダ設定（resolveProvider, triggerCharacters: . = / * + -） |
| capabilities.signatureHelpProvider | SignatureHelpOptions | シグネチャヘルプ設定（triggerCharacters: ( [ ,） |
| capabilities.definitionProvider | bool | 定義ジャンプ対応（true） |
| capabilities.hoverProvider | bool | ホバー情報対応（true） |
| capabilities.referencesProvider | bool | 参照検索対応（true） |
| capabilities.renameProvider | RenameOptions | リネーム対応（prepareProvider: true） |
| capabilities.codeActionProvider | CodeActionOptions | コードアクション対応（resolveProvider: true） |
| capabilities.codeLensProvider | CodeLensOptions | コードレンズ対応（resolveProvider: true） |
| capabilities.documentFormattingProvider | bool | ドキュメントフォーマット対応（true） |
| capabilities.documentRangeFormattingProvider | bool | 範囲フォーマット対応（true） |
| capabilities.documentSymbolProvider | bool | ドキュメントシンボル対応（true） |
| capabilities.workspaceSymbolProvider | bool | ワークスペースシンボル対応（true） |
| capabilities.foldingRangeProvider | FoldingRangeOptions | 折りたたみ対応 |
| capabilities.inlayHintProvider | bool | インレイヒント対応（true） |
| capabilities.documentHighlightProvider | bool | ドキュメントハイライト対応（true） |
| capabilities.colorProvider | DocumentColorOptions | カラープロバイダ対応 |
| capabilities.workspace | ServerWorkspaceCapabilities | ワークスペース機能（workspaceFolders: supported, changeNotifications: true） |
| serverInfo | ServerInfo | サーバー名("serve-d")とバージョン情報 |

### 出力先

LSPクライアントへのJSON-RPCレスポンス

## 処理フロー

### 処理シーケンス

```
1. トレースレベル設定
   └─ params.traceが"verbose"の場合、globalLogLevelをLogLevel.traceに設定
2. クライアントケイパビリティの保存
   └─ グローバル変数capabilitiesにparams.capabilitiesを格納
3. ワークスペースフォルダの取得と設定
   └─ params.getWorkspaceFoldersからWorkspace配列を構築
4. フォールバックワークスペースの設定
   └─ ワークスペースが1つ以上あれば最初のフォルダをフォールバックに設定
   └─ 0個の場合は一時ディレクトリにダミーワークスペースを作成
5. ServerCapabilitiesの構築
   └─ textDocumentSync, completionProvider, signatureHelpProvider等の全オプションを設定
6. サーバー情報の付加
   └─ makeServerInfo()でサーバー名"serve-d"とバージョン文字列を設定
7. InitializeResultを返却
```

### フローチャート

```mermaid
flowchart TD
    A[initializeリクエスト受信] --> B{trace == verbose?}
    B -->|Yes| C[LogLevelをtraceに設定]
    B -->|No| D[既定LogLevel維持]
    C --> E[capabilities保存]
    D --> E
    E --> F[ワークスペースフォルダ取得]
    F --> G{ワークスペース >= 1?}
    G -->|Yes| H[最初のフォルダをフォールバックに設定]
    G -->|No| I[一時ディレクトリにダミーワークスペース作成]
    H --> J[ServerCapabilities構築]
    I --> J
    J --> K[ServerInfo付加]
    K --> L[InitializeResult返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | フォールバックワークスペース | ワークスペースフォルダが0個の場合、一時ディレクトリ（serve-d-dummy-workspace）をフォールバックとして使用する | ワークスペースフォルダが空のInitializeParams受信時 |
| BR-02 | スニペット補完連動 | completionOptionsのresolveProviderはdoCompleteSnippetsフラグの値に連動する | 常時 |
| BR-03 | 補完トリガー文字 | 補完のトリガー文字は `. = / * + -` の6文字 | 常時 |
| BR-04 | シグネチャヘルプトリガー | シグネチャヘルプのトリガー文字は `( [ ,` の3文字 | 常時 |

### 計算ロジック

特になし。

## データベース操作仕様

### 操作別データベース影響一覧

本機能ではデータベース操作は発生しない。インメモリのグローバル変数（workspaces, capabilities, fallbackWorkspace）への書き込みのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | 一時ディレクトリ作成失敗 | ワークスペース0個かつ一時フォルダ作成に失敗した場合 | std.file.mkdir例外がスローされる |

### リトライ仕様

リトライは行わない。初期化はサーバーライフサイクル中に一度のみ実行される。

## トランザクション仕様

トランザクションは存在しない。

## パフォーマンス要件

初期化処理は同期的に実行され、即座にレスポンスを返す必要がある。グローバルスタートアップ（コンポーネント登録やDCD起動）は後続のconfigLoad通知で非同期に実行されるため、initialize自体は軽量である。

## セキュリティ考慮事項

ファイルシステム上のワークスペースパスを受け取るが、特別なセキュリティ制御は行わない。

## 備考

- initialize完了後、クライアントがinitializedNotificationを送信し、それをトリガーにconfigLoadが実行される。configLoad内でensureStartedUpが呼ばれ、グローバルスタートアップ（全コンポーネント登録・DCD起動判定等）が初回のみ実行される。
- doCompleteSnippetsの値はコマンドライン引数 `--provide context-snippets` によって設定される。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、initializeで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | Workspace構造体（270-327行目）: ワークスペースの状態管理。folder, initialized, disabled, config等のフィールド |
| 1-2 | types.d | `source/served/types.d` | Configuration構造体（74-268行目）: ユーザー設定の全項目。D, DFmt, DScanner, SDL, Editor, Gitの各セクション |
| 1-3 | types.d | `source/served/types.d` | グローバル変数群（352-354行目）: fallbackWorkspace, workspaces配列, capabilities |

**読解のコツ**: D言語の`@serdeOptional`と`@serdeIgnoreUnexpectedKeys`はmir.serdeライブラリのアトリビュートで、JSONデシリアライズ時に未知のキーや欠損フィールドを許容する指定。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.d | `source/served/extension.d` | initialize関数（231-332行目）: メインのinitializeハンドラ |

**主要処理フロー**:
1. **233-234行目**: トレースレベルの設定。"verbose"ならLogLevel.traceに切り替え
2. **236行目**: クライアントケイパビリティをグローバル変数に保存
3. **241-243行目**: ワークスペースフォルダを取得しWorkspace配列に変換
4. **245-262行目**: フォールバックワークスペースの設定。0個なら一時ディレクトリ作成
5. **264-321行目**: ServerCapabilitiesの構築。各種プロバイダオプションの設定
6. **324-329行目**: サーバー情報の付加（非テストビルドのみ）

#### Step 3: サーバー情報生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extension.d | `source/served/extension.d` | makeServerInfo関数（334-349行目）: サーバー名"serve-d"とバージョン文字列を構築 |

#### Step 4: 後続処理の流れを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | extension.d | `source/served/extension.d` | ensureStartedUp関数（354-361行目）: 一度だけdoGlobalStartupを呼び出すゲート |
| 4-2 | extension.d | `source/served/extension.d` | doGlobalStartup関数（363-484行目）: 全コンポーネントの登録とDCD更新判定 |

**読解のコツ**: initializeは直接doGlobalStartupを呼ばない。後続のconfigLoad（changedConfig）内でensureStartedUpが呼ばれ、初回のみグローバルスタートアップが実行される仕組みになっている。

### プログラム呼び出し階層図

```
initialize(InitializeParams)
    |
    +-- params.getWorkspaceFolders  ... ワークスペースフォルダ取得
    |
    +-- Workspace(toAdd)            ... 各フォルダをWorkspace構造体に変換
    |
    +-- makeServerInfo()            ... サーバー情報生成（非テストビルド）
    |       |
    |       +-- served.info.Version / VersionSuffix
    |
    +-- [返却] InitializeResult
```

### データフロー図

```
[入力]                       [処理]                         [出力]

InitializeParams  ───────> initialize()
  .trace          ───────>   globalLogLevel設定
  .capabilities   ───────>   capabilities (global)
  .workspaceFolders ─────>   workspaces[] 構築
                             fallbackWorkspace 設定
                             ServerCapabilities 構築  ───> InitializeResult
                             makeServerInfo()         ───>   .serverInfo
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.d | `source/served/extension.d` | ソース | initialize関数、makeServerInfo関数、ensureStartedUp関数、doGlobalStartup関数の実装 |
| types.d | `source/served/types.d` | ソース | Workspace構造体、Configuration構造体、グローバル変数の定義 |
| progress.d | `source/served/utils/progress.d` | ソース | ProgressType列挙体と進捗レポート関数（doGlobalStartupで使用） |
| translate.d | `source/served/utils/translate.d` | ソース | 多言語翻訳（doGlobalStartup内のDCD更新ダイアログで使用） |
