# 画面設計書 1-LSPサーバー初期化（initialize）

## 概要

本ドキュメントは、serve-d LSPサーバーにおける `initialize` リクエスト処理の画面設計書である。クライアント（エディタ）が起動時にサーバーへ送信する最初のリクエストであり、サーバーのケイパビリティ交換とワークスペース情報の初期化を行う。

### 本画面の処理概要

**業務上の目的・背景**：LSP（Language Server Protocol）では、クライアントとサーバー間で最初に `initialize` ハンドシェイクを行い、互いのケイパビリティ（対応機能）を交換する必要がある。このプロセスがなければ、コード補完、定義ジャンプ、フォーマットなどの全てのエディタ機能が利用できない。serve-dはD言語の開発支援LSPサーバーであり、本画面はその起動の根幹を担う処理である。

**画面へのアクセス方法**：エディタ（VS Code等のLSPクライアント）がserve-dプロセスを起動した直後に、自動的に `initialize` リクエストが送信される。ユーザーが明示的にアクセスする操作は不要であり、エディタの起動プロセスの一部として自動実行される。

**主要な操作・処理内容**：
1. クライアントから `InitializeParams` を受信し、トレースレベルの設定を行う
2. ワークスペースフォルダ情報を取得し、`Workspace` オブジェクトの配列を構築する
3. ワークスペースが存在しない場合は一時ディレクトリにダミーワークスペースを作成する
4. サーバーケイパビリティ（補完、定義ジャンプ、フォーマット、コードアクション等）を構築する
5. `InitializeResult`（ケイパビリティ + サーバー情報）をクライアントに返却する

**画面遷移**：
- 遷移元：クライアント起動（自動送信）
- 遷移先：No.2 グローバルスタートアップ（`ensureStartedUp` 経由、最初の `configChanged` 時にトリガー）

**権限による表示制御**：なし。LSPプロトコルレベルの処理のため、権限制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 初期化 (initialize) | 主機能 | クライアントからのinitializeリクエストを受け取り、サーバーケイパビリティを構築して返却する主処理 |
| 4 | ワークスペースフォルダ変更 | 補助機能 | 初期化時にワークスペースフォルダを取得・設定する処理 |

## 画面種別

LSPプロトコルリクエスト/レスポンス（初期化ハンドシェイク）

## URL/ルーティング

LSPメソッド名: `initialize`（JSON-RPC）

## 入出力項目

### 入力（InitializeParams）

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| trace | string | いいえ | トレースレベル（"verbose" の場合、ログレベルをtraceに設定） |
| capabilities | ClientCapabilities | はい | クライアントのケイパビリティ情報 |
| workspaceFolders | WorkspaceFolder[] | いいえ | ワークスペースフォルダの一覧（URI, 名前） |
| rootUri | string | いいえ | ルートURI（workspaceFoldersが未設定の場合のフォールバック） |

### 出力（InitializeResult）

| 項目名 | 型 | 説明 |
|--------|------|------|
| capabilities | ServerCapabilities | サーバーが対応する機能一覧 |
| serverInfo | ServerInfo | サーバー名（"serve-d"）とバージョン情報 |

## 表示項目

### サーバーケイパビリティ一覧

| ケイパビリティ | 値 | 説明 |
|--------------|------|------|
| textDocumentSync | openClose: true, change: incremental, save: {includeText: false} | ドキュメント同期設定 |
| completionProvider | resolveProvider: true, triggerCharacters: [".", "=", "/", "*", "+", "-"] | コード補完 |
| signatureHelpProvider | triggerCharacters: ["(", "[", ","] | シグネチャヘルプ |
| definitionProvider | true | 定義ジャンプ |
| referencesProvider | true | 参照検索 |
| documentHighlightProvider | true | ドキュメントハイライト |
| documentSymbolProvider | true | ドキュメントシンボル |
| workspaceSymbolProvider | true | ワークスペースシンボル |
| codeActionProvider | resolveProvider: true | コードアクション |
| codeLensProvider | resolveProvider: true | コードレンズ |
| documentFormattingProvider | true | ドキュメントフォーマット |
| documentRangeFormattingProvider | true | 範囲フォーマット |
| renameProvider | prepareProvider: true | リネーム |
| foldingRangeProvider | true | 折りたたみ範囲 |
| hoverProvider | true | ホバー情報 |
| colorProvider | true | カラー情報 |
| inlayHintProvider | true | インレイヒント |
| workspace.workspaceFolders | supported: true, changeNotifications: true | マルチワークスペース対応 |

## イベント仕様

### 1-initializeリクエスト受信

1. クライアントからJSON-RPCで `initialize` メソッドが呼ばれる
2. `params.trace` が "verbose" の場合、`globalLogLevel` を `LogLevel.trace` に設定
3. `params.capabilities` をグローバル変数 `capabilities` に保存
4. `params.getWorkspaceFolders` からワークスペースフォルダを取得し `workspaces` 配列を構築
5. ワークスペースがある場合: 最初のワークスペースを `fallbackWorkspace` に設定
6. ワークスペースがない場合: 一時ディレクトリに `serve-d-dummy-workspace` を作成し `fallbackWorkspace` に設定
7. `ServerCapabilities` オブジェクトを構築（全対応機能を設定）
8. `ServerInfo`（名前: "serve-d", バージョン: VersionSuffix付き）を構築
9. `InitializeResult` を返却

## データベース更新仕様

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

本画面ではデータベースへのアクセスは発生しない。全データはインメモリで管理される。

| 操作（イベント） | 対象データ | 操作種別 | 概要 |
|----------------|-----------|---------|------|
| initialize受信 | workspaces（グローバル変数） | 初期化 | ワークスペースフォルダ情報をメモリ上に構築 |
| initialize受信 | fallbackWorkspace（グローバル変数） | 初期化 | フォールバックワークスペースの設定 |
| initialize受信 | capabilities（グローバル変数） | 初期化 | クライアントケイパビリティの保存 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|----------|
| - | - | （本画面ではクライアントへのメッセージ表示は発生しない） | - |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ワークスペースフォルダなし | 一時ディレクトリにダミーワークスペースを作成し、処理を継続する |
| 一時ディレクトリの作成失敗 | 標準的な例外がスローされ、初期化が失敗する |

## 備考

- `initialize` はLSPプロトコルで定義された最初のリクエストであり、この完了前に他のリクエストは受け付けられない
- `completionItem.labelDetailsSupport` が `true` の場合、補完アイテムのラベル詳細がサポートされる
- `doCompleteSnippets` フラグに基づき、スニペット補完の `resolveProvider` が設定される
- サーバー情報（バージョン等）はユニットテストビルド時には含まれない（`served.info` が除外されるため）

---

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

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

### 推奨読解順序

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

まず、initializeリクエスト/レスポンスに関わるデータ構造と設定型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | `Workspace` 構造体（272行目）、`Configuration` 構造体（74行目）、`ManyProjectsAction` / `DubUpgradeAction` 列挙型を確認 |
| 1-2 | protocol（LSP型定義） | `source/served/lsp/protocol.d` | `InitializeParams`, `InitializeResult`, `ServerCapabilities` 等のLSPプロトコル型を確認 |

**読解のコツ**: D言語では `public import` によりモジュールの再エクスポートが行われる。`types.d` の冒頭の `public import` で多数の型が利用可能になっている。

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

処理の起点である `initialize` 関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extension.d | `source/served/extension.d` | `initialize` 関数（231行目〜332行目）がエントリーポイント。`@protocolMethod` アノテーションは不要（LSP標準メソッドのため自動ディスパッチ） |

**主要処理フロー**:
1. **233行目**: `params.trace == "verbose"` でログレベル設定
2. **236-237行目**: `capabilities` にクライアントケイパビリティを保存
3. **241-243行目**: ワークスペースフォルダ取得 → `Workspace` 配列構築
4. **245-262行目**: fallbackWorkspaceの初期化（ワークスペース有無で分岐）
5. **264-321行目**: `ServerCapabilities` の構築（全LSP機能のフラグ設定）
6. **322行目**: `result.capabilities` にセット
7. **328行目**: `makeServerInfo` でサーバー情報をセット
8. **331行目**: `InitializeResult` を返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extension.d | `source/served/extension.d` | `makeServerInfo` 関数（334行目〜349行目）でサーバー名とバージョンを生成 |

**主要処理フロー**:
- **342-346行目**: `ServerInfo` に名前 "serve-d" とバージョン文字列を設定

#### Step 4: 初期化後の起動フローへの接続を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | extension.d | `source/served/extension.d` | `ensureStartedUp` 関数（354行目〜361行目）- 最初の設定変更通知時にグローバルスタートアップをトリガー |
| 4-2 | extension.d | `source/served/extension.d` | `changedConfig` 関数（60行目〜203行目）- 設定変更ハンドラ内で `ensureStartedUp` を呼び出す（69行目） |

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

```
[クライアント] ── initialize リクエスト ──▶ initialize(InitializeParams)
    │
    ├─ globalLogLevel設定（trace指定時）
    │
    ├─ params.getWorkspaceFolders → Workspace[]構築
    │      ├─ ワークスペースあり → fallbackWorkspace = workspaces[0]
    │      └─ ワークスペースなし → tmpDir/serve-d-dummy-workspace
    │
    ├─ ServerCapabilities構築
    │      ├─ TextDocumentSyncOptions
    │      ├─ CompletionOptions
    │      ├─ SignatureHelpOptions
    │      ├─ CodeLensOptions
    │      ├─ CodeActionOptions
    │      ├─ RenameOptions
    │      └─ WorkspaceFoldersServerCapabilities
    │
    ├─ makeServerInfo()
    │      └─ ServerInfo { name: "serve-d", version: "vX.Y.Z" }
    │
    └─ return InitializeResult
```

### データフロー図

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

InitializeParams ──────▶ initialize() ─────────────────▶ InitializeResult
  .trace                    │                               .capabilities
  .capabilities             ├─ ログレベル設定                  .serverInfo
  .workspaceFolders         ├─ Workspace[]構築
                            ├─ fallbackWorkspace設定
                            └─ ServerCapabilities構築
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extension.d | `source/served/extension.d` | ソース | initialize関数の実装、ensureStartedUp、changedConfig |
| types.d | `source/served/types.d` | ソース | Workspace構造体、Configuration構造体、グローバル変数定義 |
| progress.d | `source/served/utils/progress.d` | ソース | ProgressType列挙型、reportProgress関数 |
| translate.d | `source/served/utils/translate.d` | ソース | 翻訳機能（initialize自体では未使用だが後続処理で使用） |
| en.txt | `views/en.txt` | リソース | 英語翻訳リソース |
