# 機能設計書 89-PDBソースドキュメント

## 概要

本ドキュメントは、Roslyn IDEにおけるPDBソースドキュメント機能の設計を記載する。この機能は、PDB（Program Database）ファイルに埋め込まれたソースコードやSource Link情報を使用して、オリジナルのソースコードを取得・表示する。

### 本機能の処理概要

PDBソースドキュメント機能は、コンパイル時にPDBに埋め込まれたソースコード、またはSource Link情報を使用してリモートリポジトリからソースコードを取得する。これにより、外部ライブラリであってもオリジナルのソースコードを表示できる。

**業務上の目的・背景**：多くのオープンソースプロジェクトやNuGetパッケージは、Source Linkを有効にしてビルドされている。これにより、デバッグ時やコード探索時に、逆コンパイルではなくオリジナルのソースコードを確認できる。本機能は、このSource Link機能をIDEに統合し、開発者がオリジナルのソースコードに直接アクセスできるようにする。

**機能の利用シーン**：
- Source Link対応のNuGetパッケージを使用している場合
- .NET Framework/Core自体のソースコードを確認したい場合
- シンボルサーバーからソースコードを取得したい場合
- PDBに埋め込まれたソースコードを表示したい場合

**主要な処理内容**：
1. PDBからソースドキュメント情報を抽出
2. 埋め込みソースの解凍と表示
3. Source Link URLからのソース取得
4. チェックサム検証によるソース整合性確認

**関連システム・外部連携**：
- Symbol Server
- Source Link (GitHub, Azure DevOps等)
- デバッガーサービス

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | 定義へ移動の実行 |
| - | ソースビュー | 結果表示画面 | 取得したソースの表示 |
| - | オプション設定 | 設定画面 | Source Link有効/無効の切り替え |

## 機能種別

コードナビゲーション / ソース表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tempFilePath | string | Yes | 一時ファイル保存パス | null不可 |
| sourceDocument | SourceDocument | Yes | ソースドキュメント情報 | null不可 |
| encoding | Encoding | Yes | 文字エンコーディング | null不可 |
| useExtendedTimeout | bool | No | 拡張タイムアウト使用 | - |

### 入力データソース

- PDBファイル
- Source Link URL
- Symbol Server

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SourceFileInfo | SourceFileInfo? | ソースファイル情報（パス、TextLoader、チェックサムアルゴリズム） |

### 出力先

一時フォルダ内のソースファイル

## 処理フロー

### 処理シーケンス

```
1. 埋め込みソースの確認
   └─ TryGetEmbeddedSourceFileで埋め込みソースを取得
2. オリジナルファイルの確認
   └─ TryGetOriginalFileでローカルファイルを確認
3. Source Link取得
   └─ TryGetSourceLinkFileAsyncでリモート取得
4. チェックサム検証
   └─ ソースとPDBのチェックサムを比較
5. ファイル出力
   └─ 一時フォルダにファイル作成
```

### フローチャート

```mermaid
flowchart TD
    A[LoadSourceDocumentAsync] --> B[TryGetEmbeddedSourceFile]
    B --> C{埋め込みソースあり?}
    C -->|Yes| D[解凍してファイル作成]
    D --> E[チェックサム検証]
    E --> F{検証成功?}
    F -->|Yes| G[SourceFileInfo返却]
    F -->|No| H[null返却]
    C -->|No| I[TryGetOriginalFile]
    I --> J{オリジナルファイル存在?}
    J -->|Yes| E
    J -->|No| K[TryGetSourceLinkFileAsync]
    K --> L{Source Link URL存在?}
    L -->|No| H
    L -->|Yes| M[ISourceLinkService.GetSourceFilePathAsync]
    M --> N{タイムアウト?}
    N -->|Yes| H
    N -->|No| O{ファイル取得成功?}
    O -->|Yes| G
    O -->|No| H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 優先順位 | 埋め込みソース → ローカルファイル → Source Link | 順次試行 |
| BR-02 | チェックサム検証 | ソースのチェックサムがPDBと一致すること | 埋め込みソース、ローカルファイルで適用 |
| BR-03 | タイムアウト | 標準1秒、拡張4秒でタイムアウト | Source Link取得時 |
| BR-04 | キャッシュ | 一度取得したファイルは再利用 | 同一ファイルパス |

### 計算ロジック

チェックサムはSourceDocumentに記録されたアルゴリズム（SHA-1、SHA-256等）で計算。

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | タイムアウト | Source Link取得がタイムアウト | nullを返却 |
| - | チェックサム不一致 | ソースが改ざんされている | nullを返却 |
| - | ファイル書き込み失敗 | ディスクエラー | nullを返却 |

### リトライ仕様

なし（次のソース取得方法を試行）

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

なし

## パフォーマンス要件

- 埋め込みソースは即座に取得（1秒以内）
- Source Linkは最大4秒（拡張タイムアウト時）

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

- Source Link URLは信頼できるソースのみ
- チェックサム検証で改ざん検出
- 一時ファイルは読み取り専用

## 備考

- IPdbSourceDocumentLoggerでログ出力可能
- テレメトリでソース取得方法を記録

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SourceDocument.cs | `src/Features/Core/Portable/PdbSourceDocument/SourceDocument.cs` | ソースドキュメント情報の構造 |
| 1-2 | SourceFileInfo.cs | `src/Features/Core/Portable/PdbSourceDocument/SourceFileInfo.cs` | ソースファイル情報の構造 |

**読解のコツ**: SourceDocumentはFilePath、Checksum、ChecksumAlgorithm、EmbeddedTextBytes、SourceLinkUrlを保持。

#### Step 2: サービスインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IPdbSourceDocumentLoaderService.cs | `src/Features/Core/Portable/PdbSourceDocument/IPdbSourceDocumentLoaderService.cs` | ローダーサービスの公開API |

#### Step 3: サービス実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PdbSourceDocumentLoaderService.cs | `src/Features/Core/Portable/PdbSourceDocument/PdbSourceDocumentLoaderService.cs` | ローダー実装 |

**主要処理フロー**:
- **28-29行目**: タイムアウト定数（1秒、4秒）
- **38-44行目**: LoadSourceDocumentAsyncで優先順位に従い取得
- **47-123行目**: TryGetEmbeddedSourceFileで埋め込みソース処理
- **125-167行目**: TryGetSourceLinkFileAsyncでSource Link処理
- **169-189行目**: TryGetOriginalFileでローカルファイル処理
- **191-208行目**: LoadSourceFileでチェックサム検証

#### Step 4: Source Link連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ISourceLinkService.cs | `src/Features/Core/Portable/PdbSourceDocument/ISourceLinkService.cs` | Source Linkサービスインターフェース |

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

```
PdbSourceDocumentLoaderService.LoadSourceDocumentAsync
    │
    ├─ TryGetEmbeddedSourceFile
    │      ├─ DeflateStream で解凍
    │      ├─ File.OpenWrite でファイル書き込み
    │      └─ LoadSourceFile でチェックサム検証
    │
    ├─ TryGetOriginalFile
    │      ├─ File.Exists で存在確認
    │      └─ LoadSourceFile でチェックサム検証
    │
    └─ TryGetSourceLinkFileAsync
           ├─ ISourceLinkService.GetSourceFilePathAsync
           ├─ Task.WhenAny でタイムアウト制御
           └─ LoadSourceFile で読み込み
```

### データフロー図

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

SourceDocument ──▶ PdbSourceDocumentLoaderService
                        │
                        ├─ EmbeddedTextBytes? ──▶ DeflateStream
                        │                             │
                        │                             ▼
                        │                       ファイル書き込み
                        │
                        ├─ FilePath ──────────▶ File.Exists?
                        │                             │
                        │                             ▼
                        │                       ローカルファイル読み込み
                        │
                        └─ SourceLinkUrl ──────▶ ISourceLinkService
                                                      │
                                                      ▼
                                                リモート取得
                                                      │
                                                      ▼
Encoding ────────▶ SourceText.From ────────▶ SourceFileInfo
                        │
                        ▼
                  チェックサム検証
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IPdbSourceDocumentLoaderService.cs | `src/Features/Core/Portable/PdbSourceDocument/IPdbSourceDocumentLoaderService.cs` | ソース | ローダーインターフェース |
| PdbSourceDocumentLoaderService.cs | `src/Features/Core/Portable/PdbSourceDocument/PdbSourceDocumentLoaderService.cs` | ソース | ローダー実装 |
| SourceDocument.cs | `src/Features/Core/Portable/PdbSourceDocument/SourceDocument.cs` | ソース | ソースドキュメント情報 |
| SourceFileInfo.cs | `src/Features/Core/Portable/PdbSourceDocument/SourceFileInfo.cs` | ソース | ソースファイル情報 |
| ISourceLinkService.cs | `src/Features/Core/Portable/PdbSourceDocument/ISourceLinkService.cs` | ソース | Source Linkサービス |
| IPdbSourceDocumentLogger.cs | `src/Features/Core/Portable/PdbSourceDocument/IPdbSourceDocumentLogger.cs` | ソース | ログ出力インターフェース |
| PdbSourceDocumentMetadataAsSourceFileProvider.cs | `src/Features/Core/Portable/PdbSourceDocument/PdbSourceDocumentMetadataAsSourceFileProvider.cs` | ソース | プロバイダー実装 |
