# 通知設計書 8-SemanticTokensRefresh

## 概要

本ドキュメントは、clangd Language Serverが実装するLSP標準メソッド `workspace/semanticTokens/refresh` の通知仕様を定義する。この通知（実際にはリクエスト）は、セマンティックトークンのキャッシュを無効化し、クライアントに再取得を促すために使用される。

### 本通知の処理概要

SemanticTokensRefresh通知は、ファイルのセマンティクス（型情報、シンボル種別等）が変更された可能性がある場合に、クライアントにセマンティックトークンの再取得を促す機能である。

**業務上の目的・背景**：C/C++コードのシンタックスハイライトは、単純なキーワードマッチングだけでなく、型情報やシンボル解析に基づくセマンティックハイライトを使用することで、より正確な色分けが可能になる。ファイルの内容変更や依存関係の変更により、これらの情報が更新された場合、クライアントに再取得を促す必要がある。

**通知の送信タイミング**：`onSemanticsMaybeChanged`コールバックが呼ばれた時に送信される。これは、ファイルのセマンティクス情報が変更された可能性がある場合に発生する。

**通知の受信者**：SemanticTokensRefresh機能をサポートするLSPクライアントが受信者となる。クライアントはcapabilities.workspace.semanticTokens.refreshSupport=trueを設定することでこの機能を有効化する。

**通知内容の概要**：パラメータなし（NoParams）で送信される。

**期待されるアクション**：クライアントはキャッシュしているセマンティックトークン情報を無効化し、必要に応じてtextDocument/semanticTokensリクエストを再送する。

## 通知種別

LSP Request（サーバーからクライアントへのリクエスト - レスポンスを期待）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期 |
| 優先度 | 低 |
| リトライ | なし |

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

SemanticTokensRefresh機能をサポートするLSPクライアントに送信される。クライアントのcapabilities.workspace.semanticTokens.refreshSupportで有効化が必要。

## 通知テンプレート

### LSP Request形式

| 項目 | 内容 |
|-----|------|
| メソッド名 | `workspace/semanticTokens/refresh` |
| 形式 | JSON-RPC 2.0 Request |

### 本文テンプレート

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "workspace/semanticTokens/refresh",
  "params": {}
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| N/A | パラメータなし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | onSemanticsMaybeChanged | SemanticTokensRefreshがバインド済み | セマンティクス情報変更可能性 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| SemanticTokenRefreshSupport==false | クライアントがSemanticTokensRefreshをサポートしていない場合 |
| SemanticTokensRefreshが未バインド | 条件付きバインドにより機能が無効の場合 |
| サーバー未初期化 | initializeリクエスト完了前は送信されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ファイル変更/AST更新] --> B[onSemanticsMaybeChanged コールバック]
    B --> C{SemanticTokensRefresh有効?}
    C -->|No| D[処理終了]
    C -->|Yes| E[SemanticTokensRefresh送信]
    E --> F{レスポンス}
    F -->|成功| G[正常終了]
    F -->|失敗| H[エラーログ出力]
```

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

### 参照テーブル一覧

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

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| リクエスト失敗 | クライアントがエラーを返した場合 | elog()でエラーログ出力 |
| Transport失敗 | クライアントとの接続断 | ログ出力、再接続待機 |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

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

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

- リクエストにはパラメータがなく、機密データは含まれない
- LSP通信はローカルプロセス間通信が基本であり、外部ネットワークへの送信は想定していない

## 備考

- LSP標準メソッド（workspace/semanticTokens/refresh）
- 厳密には通知ではなくリクエストだが、レスポンスは成功/失敗のみ
- クライアント側でセマンティックトークンのキャッシュ無効化を行う
- 失敗時はエラーログを出力するのみで、特別なリカバリ処理は行わない

---

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

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

### 推奨読解順序

#### Step 1: クライアントCapabilitiesを理解する

SemanticTokenRefreshSupport機能の判定方法を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Protocol.h | `clang-tools-extra/clangd/Protocol.h` | SemanticTokenRefreshSupport定義（行559） |
| 1-2 | Protocol.cpp | `clang-tools-extra/clangd/Protocol.cpp` | refreshSupportのパース（行480-482） |

**読解のコツ**: workspace.semanticTokens.refreshSupportブール値でサポート判定。

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

SemanticTokensRefreshの送信箇所を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangdLSPServer.h | `clang-tools-extra/clangd/ClangdLSPServer.h` | SemanticTokensRefresh宣言（行206） |
| 2-2 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | 条件付きバインド（行1743-1744） |
| 2-3 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | onSemanticsMaybeChanged実装（行1938-1946） |

**主要処理フロー**:
1. **行1743-1744**: `if(Caps.SemanticTokenRefreshSupport)`で条件付きバインド
2. **行1939**: `if (SemanticTokensRefresh)`で有効性確認
3. **行1940-1944**: `SemanticTokensRefresh(NoParams{}, ...)`で送信とコールバック設定
4. **行1942-1943**: 失敗時に`elog("Failed to refresh semantic tokens: {0}")`

#### Step 3: バインディング方式を理解する

OutgoingMethodによるリクエスト送信方式を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ClangdLSPServer.h | `clang-tools-extra/clangd/ClangdLSPServer.h` | LSPBinder::OutgoingMethod型（行206） |
| 3-2 | ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | Bind.outgoingMethod使用（行1744） |

**主要処理フロー**:
- **行206**: `LSPBinder::OutgoingMethod<NoParams, std::nullptr_t>`型
- **行1744**: `Bind.outgoingMethod("workspace/semanticTokens/refresh")`でバインド

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

```
ファイル変更 / AST更新
    │
    └─ ClangdServer::Callbacks::onSemanticsMaybeChanged()
           │
           └─ ClangdLSPServer::onSemanticsMaybeChanged(PathRef File)
                  │
                  └─ [SemanticTokensRefresh有効?]
                         │
                         ├─ [有効] SemanticTokensRefresh(NoParams{}, callback)
                         │              │
                         │              └─ [レスポンス受信]
                         │                     ├─ [成功] return
                         │                     └─ [失敗] elog()
                         │
                         └─ [無効] 何もしない
```

### データフロー図

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

onSemanticsMaybeChanged ──▶ 有効性確認 ──▶ JSON-RPC Request
(PathRef File)                  │                        │
                                ▼                        ▼
                     SemanticTokensRefresh?     workspace/semanticTokens/refresh
                                │                        │
                                ▼                        ▼
                          NoParams{}              [LSPクライアント]
                                                  セマンティックトークン再取得
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Protocol.h | `clang-tools-extra/clangd/Protocol.h` | ヘッダ | ClientCapabilities定義 |
| Protocol.cpp | `clang-tools-extra/clangd/Protocol.cpp` | ソース | Capabilitiesパース実装 |
| ClangdLSPServer.h | `clang-tools-extra/clangd/ClangdLSPServer.h` | ヘッダ | SemanticTokensRefresh宣言 |
| ClangdLSPServer.cpp | `clang-tools-extra/clangd/ClangdLSPServer.cpp` | ソース | 送信ロジック |
| LSPBinder.h | `clang-tools-extra/clangd/LSPBinder.h` | ヘッダ | OutgoingMethod定義 |
| Transport.h | `clang-tools-extra/clangd/Transport.h` | ヘッダ | 通信層インターフェース |
