# 通知設計書 2-ShowMessage

## 概要

本ドキュメントは、clangd Language Serverが実装するLSP標準メソッド `window/showMessage` の通知仕様を定義する。この通知は、サーバーからクライアントに対してメッセージ（エラー、警告、情報、ログ）を表示するよう要求するために使用される。

### 本通知の処理概要

ShowMessage通知は、Language Serverがユーザーに対して重要な情報を伝える必要がある場合に使用される。診断情報とは異なり、ドキュメント固有ではなく、サーバー全体の状態やアクション結果をユーザーに通知する。

**業務上の目的・背景**：開発者がLanguage Serverの状態や処理結果を把握するために、エディタのUIを通じてメッセージを表示する必要がある。例えば、Tweak（コードリファクタリング機能）の適用結果、設定エラー、サーバーの状態変化などをユーザーに通知する。この通知により、開発者はLanguage Serverの動作状況を把握し、必要なアクションを取ることができる。

**通知の送信タイミング**：主に以下のケースで送信される。(1) Tweakコマンドの実行結果としてShowMessageが指定された場合、(2) サーバー内部でユーザーに通知すべき状況が発生した場合。clangdでは主にTweak機能（ApplyTweak）でShowMessageオプションが設定された場合に使用される。

**通知の受信者**：LSPクライアント（VSCode、Vim、Emacs等のエディタ/IDE）が受信者となる。クライアントはメッセージタイプに応じて適切なUI（ダイアログ、通知バナー、ステータスバー等）でメッセージを表示する。

**通知内容の概要**：メッセージタイプ（Error=1, Warning=2, Info=3, Log=4）とメッセージ文字列が含まれる。メッセージタイプに応じて、クライアントは表示方法を変える（エラーは目立つダイアログ、ログは控えめな表示など）。

**期待されるアクション**：クライアントは受信したメッセージをUIに表示する。表示方法はメッセージタイプとクライアントの実装に依存する。ユーザーはメッセージを確認し、必要に応じて対応を取る。

## 通知種別

LSP Notification（サーバーからクライアントへの一方向通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期 |
| 優先度 | 中 |
| リトライ | なし（通知は一方向のため） |

### 送信先決定ロジック

接続中のLSPクライアントに送信される。特定のドキュメントやユーザーに紐づかない、セッション全体への通知。

## 通知テンプレート

### LSP Notification形式

| 項目 | 内容 |
|-----|------|
| メソッド名 | `window/showMessage` |
| 形式 | JSON-RPC 2.0 Notification |

### 本文テンプレート

```json
{
  "jsonrpc": "2.0",
  "method": "window/showMessage",
  "params": {
    "type": 3,
    "message": "Tweak applied."
  }
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | メッセージタイプ（1:Error, 2:Warning, 3:Info, 4:Log） | MessageType enum | Yes |
| message | 表示するメッセージ文字列 | 処理結果/状態メッセージ | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コマンド実行 | ApplyTweak完了 | Tweak::Effect::ShowMessageが設定されている | Tweakの適用結果をユーザーに通知 |
| 内部処理 | サーバー状態変化 | 通知が必要な状態変化が発生 | 設定エラー等のシステムメッセージ |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ShowMessageが未設定 | Tweak実行時にShowMessageオプションが指定されていない場合 |
| サーバー未初期化 | initializeリクエスト完了前は送信されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Tweakコマンド実行] --> B[Server::applyTweak]
    B --> C[Tweak::apply]
    C --> D{Effect::ShowMessage設定?}
    D -->|Yes| E[ShowMessageParams構築]
    D -->|No| F[処理終了]
    E --> G[ShowMessage通知送信]
    G --> H[クライアントでUI表示]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（LSPサーバーはインメモリで動作）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Transport失敗 | クライアントとの接続断 | ログ出力、再接続待機 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし（イベント駆動） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（リアルタイム配信）

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

- メッセージ内容にファイルパスや内部情報が含まれる可能性がある
- LSP通信はローカルプロセス間通信が基本であり、外部ネットワークへの送信は想定していない

## 備考

- MessageTypeの値：Error=1, Warning=2, Info=3, Log=4
- clangdでは主にTweak機能で使用される
- クライアントによって表示方法が異なる（ダイアログ、トースト通知、ステータスバー等）

---

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

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

### 推奨読解順序

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

ShowMessageParamsとMessageType enumの定義を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Protocol.h | `clang-tools-extra/clangd/Protocol.h` | MessageType enum定義（行732-741） |
| 1-2 | Protocol.h | `clang-tools-extra/clangd/Protocol.h` | ShowMessageParams構造体定義（行744-752） |
| 1-3 | Protocol.cpp | `clang-tools-extra/clangd/Protocol.cpp` | toJSON(ShowMessageParams)実装（行624-626） |

**読解のコツ**: MessageTypeは整数値としてシリアライズされる。Error=1が最も重大。

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

ShowMessage通知の送信箇所を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangdLSPServer.h | `clang-tools-extra/clangd/ClangdLSPServer.h` | ShowMessage通知のバインド宣言（行194） |
| 2-2 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | ShowMessageバインド（行1737） |
| 2-3 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | onCommandApplyTweak内でのShowMessage使用（行819-824） |

**主要処理フロー**:
1. **行1737**: `Bind.outgoingNotification("window/showMessage")`でバインド
2. **行819-824**: Tweak適用結果にShowMessageが設定されている場合に送信
3. **行821-823**: ShowMessageParams構築（message, type=Info）

#### Step 3: Tweak機能との連携を理解する

Tweakの実行結果としてShowMessageが使用されるフローを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Tweak.h | `clang-tools-extra/clangd/refactor/Tweak.h` | Tweak::Effect構造体のShowMessageフィールド |
| 3-2 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | ApplyTweak処理全体（行810-844） |

**主要処理フロー**:
- **行817-818**: Tweak適用結果のEffect確認
- **行819**: `R->ShowMessage`の存在確認
- **行820-824**: ShowMessageParams構築と送信

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

```
workspace/executeCommand (ApplyTweak)
    │
    └─ ClangdLSPServer::onCommandApplyTweak()
           │
           ├─ Server::applyTweak()
           │      └─ Tweak::apply() → Effect
           │
           └─ [Effect::ShowMessage存在時]
                  ├─ ShowMessageParams構築
                  └─ ShowMessage() [LSPBinder経由]
                         └─ ClangdLSPServer::notify()
                                └─ Transport::notify()
```

### データフロー図

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

Tweak::Effect  ───▶ ShowMessage存在確認 ───▶ ShowMessageParams
    │                      │                        │
    │                      ▼                        ▼
    │               type = MessageType::Info   toJSON()
    │               message = *R->ShowMessage       │
    │                                               ▼
    └──────────────────────────────────────▶ JSON-RPC通知
                                                    │
                                                    ▼
                                              [LSPクライアント]
                                              UI表示（ダイアログ等）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Protocol.h | `clang-tools-extra/clangd/Protocol.h` | ヘッダ | MessageType, ShowMessageParams定義 |
| Protocol.cpp | `clang-tools-extra/clangd/Protocol.cpp` | ソース | JSON変換実装 |
| ClangdLSPServer.h | `clang-tools-extra/clangd/ClangdLSPServer.h` | ヘッダ | ShowMessage通知宣言 |
| ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | ソース | ShowMessage送信ロジック |
| Tweak.h | `clang-tools-extra/clangd/refactor/Tweak.h` | ヘッダ | Tweak::Effect定義 |
| LSPBinder.h | `clang-tools-extra/clangd/LSPBinder.h` | ヘッダ | LSPメソッドバインディング |
| Transport.h | `clang-tools-extra/clangd/Transport.h` | ヘッダ | 通信層インターフェース |
