# 通知設計書 31-undoRedoService.warning

## 概要

本ドキュメントは、VS Code エディタにおけるUndo/Redo操作に関する警告通知機能の設計を記載する。UndoRedoServiceは、複数ファイルにまたがるUndo/Redo操作やリソースの競合状態を検出し、ユーザーに適切な警告メッセージを通知する。

### 本通知の処理概要

UndoRedoService警告通知は、複数ファイルにまたがる編集操作のUndo/Redo実行時に、操作が完全には実行できない場合や競合が発生した場合に警告メッセージを表示する機能である。

**業務上の目的・背景**：VSCodeでは、リファクタリングや一括置換など複数ファイルにまたがる編集操作をサポートしている。これらの操作をUndoする際、一部のファイルが変更されていたり、閉じられていたりすると、完全なUndoが不可能になる場合がある。この警告通知により、ユーザーにUndo/Redo操作の制限事項を明確に伝え、データ損失や予期しない動作を防止する。

**通知の送信タイミング**：以下のケースで警告が表示される：(1) ワークスペースUndoで一部ファイルが外部変更された場合、(2) 複数ファイルにまたがるUndoで一部ファイルが互換性のない方法で変更された場合、(3) 他のUndo/Redo操作が進行中で操作がブロックされた場合。

**通知の受信者**：Undo/Redo操作を実行したユーザー本人がNotificationServiceを通じて警告を受け取る。

**通知内容の概要**：警告メッセージには操作名（ラベル）、影響を受けたファイル名、Undoできなかった理由（外部変更、互換性のない変更、別の操作が進行中など）が含まれる。

**期待されるアクション**：ユーザーは警告内容を確認し、必要に応じて手動で変更を確認・修正する。ワークスペースUndoが分割された場合は、個別ファイルのUndoとして継続実行される。

## 通知種別

アプリ内通知（NotificationService.warn）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 中（Warning） |
| リトライ | なし |

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

Undo/Redo操作を実行したユーザーに対して、VSCodeのNotificationServiceを通じてウィンドウ内に警告トーストが表示される。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 重要度 | Warning（黄色アイコン） |
| 表示位置 | 画面右下の通知エリア |
| 自動消去 | なし（ユーザー操作で消去） |

### 本文テンプレート

```
Could not undo '{操作ラベル}' across all files. {詳細メッセージ}
```

または

```
Could not undo '{操作ラベル}' because there is already an undo or redo operation running.
```

### 詳細メッセージパターン

| パターン | メッセージ |
|---------|---------|
| 外部変更 | "The following files have been closed and modified on disk: {ファイルリスト}." |
| 互換性なし | "The following files have been modified in an incompatible way: {ファイルリスト}." |
| 他ファイル変更 | "Could not undo '{操作ラベル}' across all files because changes were made to {ファイルリスト}" |
| 操作進行中 | "Could not undo '{操作ラベル}' because there is already an undo or redo operation running on {ファイルリスト}" |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| element.label | 操作名 | StackElement.label | Yes |
| resourceLabels | 影響ファイル一覧 | RemovedResources.elements | Yes |
| reason | 失敗理由 | RemovedResourceReason | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | Undo/Redoコマンド実行 | ワークスペースUndo失敗 | 複数ファイルのUndoが完全に実行できない場合 |
| 画面操作 | Undo/Redoコマンド実行 | リソースUndo失敗 | 単一ファイルのUndo時に競合が発生した場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Undoが正常完了 | すべてのファイルでUndoが正常に完了した場合 |
| 分割成功かつ継続 | ワークスペースUndoが分割され、個別Undoとして継続できる場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Undo/Redoコマンド実行] --> B{ワークスペース操作?}
    B -->|Yes| C[_checkWorkspaceUndo実行]
    B -->|No| D[_resourceUndo実行]
    C --> E{検証エラー?}
    E -->|Yes| F{分割可能?}
    F -->|Yes| G[_splitPastWorkspaceElement]
    G --> H[NotificationService.warn]
    H --> I[個別Undoとして継続]
    F -->|No| J[全スタック破棄]
    J --> K[NotificationService.warn]
    E -->|No| L[Undo実行]
    D --> M{ロック中?}
    M -->|Yes| N[NotificationService.warn]
    M -->|No| O[Undo実行]
    L --> P[終了]
    I --> P
    K --> P
    N --> P
    O --> P
```

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

### 参照テーブル一覧

VSCodeはデスクトップアプリケーションであり、通常のDBテーブルは使用しない。

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| _editStacks Map | 各リソースの編集履歴スタック | URI文字列をキーとする |
| StackElement | 個別のUndo/Redo操作 | 操作ラベル、リソース情報を保持 |
| RemovedResources | 削除/無効化されたリソース情報 | 警告メッセージ生成に使用 |

### インメモリデータ構造詳細

#### ResourceEditStack

| 項目 | 説明 | 備考 |
|-----|------|------|
| _past | Undo可能な操作スタック | StackElement[] |
| _future | Redo可能な操作スタック | StackElement[] |
| locked | ロック状態 | boolean |
| versionId | バージョンID | 競合検出用 |

#### WorkspaceStackElement

| 項目 | 説明 | 備考 |
|-----|------|------|
| removedResources | 削除されたリソース | RemovedResources | null |
| invalidatedResources | 無効化されたリソース | RemovedResources | null |
| strResources | 関連リソースURI | string[] |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ExternalRemoval | ファイルが閉じられ外部で変更された | 警告表示、可能なら分割して継続 |
| NoParallelUniverses | 互換性のない方法でファイルが変更された | 警告表示、可能なら分割して継続 |
| LockedStack | 他のUndo/Redo操作が進行中 | 警告表示、操作を中断 |
| VersionMismatch | 操作中にスタックが変更された | 警告表示、可能なら分割して継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | なし（即座に警告表示） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | なし（ユーザー操作起点のため） |

### 配信時間帯

ユーザー操作に応じて即座に表示（時間帯制限なし）

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

- ファイルパスがメッセージに含まれるが、ローカルアプリ内での表示のため外部漏洩リスクは低い
- 警告メッセージはローカライズ対応されている

## 備考

- 警告はNotificationService.warnを使用し、ユーザーが明示的に閉じるまで表示される
- ワークスペースUndoの分割機能により、一部ファイルの変更があっても可能な範囲でUndoを継続できる
- Redoについても同様の警告処理が実装されている

---

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

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

### 推奨読解順序

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

まず、Undo/Redoスタックのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | undoRedo.ts | `src/vs/platform/undoRedo/common/undoRedo.ts` | IUndoRedoElementインターフェース、UndoRedoElementTypeの定義 |
| 1-2 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | ResourceStackElement、WorkspaceStackElement、RemovedResourcesクラスの定義（25-193行目） |

**読解のコツ**: ResourceStackElement（単一ファイル操作）とWorkspaceStackElement（複数ファイル操作）の違いを理解することが重要。

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

Undo/Redo操作の起点となるメソッドを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | undo()メソッド（1068-1077行目）とredo()メソッド（1350-1359行目） |

**主要処理フロー**:
1. **1068-1077行目**: undo()メソッドがURI/UndoRedoSourceに応じて_undo()を呼び出し
2. **1079-1116行目**: _undo()メソッドが適切な編集スタックを取得し、要素タイプに応じて処理を分岐

#### Step 3: 警告メッセージ生成を理解する

警告が生成されるロジックを追跡。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | RemovedResources.createMessage()（81-110行目） |
| 3-2 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | _tryToSplitAndUndo()（814-827行目） |
| 3-3 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | _checkWorkspaceUndo()（829-904行目） |

**主要処理フロー**:
- **96-99行目**: 外部削除されたファイルのメッセージ生成
- **103-107行目**: 互換性のない変更があったファイルのメッセージ生成
- **817行目**: NotificationService.warnで警告表示

#### Step 4: リソースUndo時の警告を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | _resourceUndo()（1012-1030行目） |

**主要処理フロー**:
- **1018-1025行目**: editStack.lockedの場合の警告メッセージ生成と表示

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

```
UndoRedoService.undo()
    │
    ├─ _undo(strResource, sourceId, undoConfirmed)
    │      │
    │      ├─ [WorkspaceElement] _workspaceUndo()
    │      │      │
    │      │      ├─ _getAffectedEditStacks()
    │      │      ├─ _checkWorkspaceUndo()
    │      │      │      ├─ [removedResources存在] _tryToSplitAndUndo()
    │      │      │      │      ├─ _splitPastWorkspaceElement()
    │      │      │      │      └─ NotificationService.warn()  ← 警告通知
    │      │      │      └─ [その他エラー] _tryToSplitAndUndo()
    │      │      │
    │      │      └─ _confirmAndExecuteWorkspaceUndo()
    │      │
    │      └─ [ResourceElement] _resourceUndo()
    │             │
    │             ├─ [locked] NotificationService.warn()  ← 警告通知
    │             └─ [unlocked] _safeInvokeWithLocks()
    │
    └─ _onError() → NotificationService.error()
```

### データフロー図

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

Undo/Redoコマンド ──▶ UndoRedoService ──▶ NotificationService
      │                    │                      │
      │                    ▼                      ▼
      │            編集スタック検証          警告トースト表示
      │                    │
      │                    ▼
      │            RemovedResources
      │            .createMessage()
      │                    │
      │                    ▼
      └──────────▶ ローカライズメッセージ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| undoRedo.ts | `src/vs/platform/undoRedo/common/undoRedo.ts` | インターフェース | IUndoRedoService、IUndoRedoElementの定義 |
| undoRedoService.ts | `src/vs/platform/undoRedo/common/undoRedoService.ts` | サービス | Undo/Redo機能の実装、警告通知の生成 |
| notification.ts | `src/vs/platform/notification/common/notification.ts` | インターフェース | INotificationServiceの定義 |
| nls.ts | `src/vs/nls.ts` | ユーティリティ | ローカライズ関数の提供 |
