# 機能設計書 85-拡張機能開発

## 概要

本ドキュメントは、VS Codeの「拡張機能開発（extension-editing）」機能の設計内容を記載する。拡張機能のpackage.jsonやREADME.mdの編集時に、補完、リンティング、コードアクションを提供する。

### 本機能の処理概要

extension-editing拡張機能は、VS Code拡張機能を開発する際のpackage.json編集支援、README.md/CHANGELOG.mdの画像URL検証、提案APIの使用チェックなどを提供する。

**業務上の目的・背景**：VS Code拡張機能の開発において、package.jsonのスキーマは複雑であり、誤った設定やマーケットプレイスガイドライン違反を防止する必要がある。また、提案APIの使用制限なども自動的にチェックする。

**機能の利用シーン**：
- 拡張機能のpackage.jsonを編集する際に、contributes等の補完が利用できる
- README.mdで外部画像URLがHTTPSかどうかを検証
- アクティベーションイベントの冗長性や非推奨を警告

**主要な処理内容**：
1. package.jsonの補完候補提供（PackageDocumentHelper）
2. package.jsonのリンティング（ExtensionLinter）
3. README.md/CHANGELOG.mdの画像URL検証
4. コードアクション（クイックフィックス）の提供

**関連システム・外部連携**：VS Code拡張機能API、Markdownパーサー

**権限による制御**：信頼されていないワークスペースでもサポート

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | エディタ領域 | 主画面 | package.json/README.md編集 |
| 3 | サイドバー | 参照 | 問題パネルでの警告表示 |

## 機能種別

リンティング / インテリセンス補完 / ドキュメント検証

## 入力仕様

### 入力パラメータ

対象ファイルと検証内容：

| ファイル | 検証内容 |
|---------|---------|
| package.json | engines.vscode、activationEvents、enabledApiProposals、badges |
| README.md | 画像URL（HTTPS必須、SVG制限） |
| CHANGELOG.md | 画像URL（HTTPS必須、SVG制限） |

### 入力データソース

- 編集中のJSONまたはMarkdownドキュメント
- product.jsonの許可リスト（SVGソース、提案API）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| diagnostics | Diagnostic[] | リンティングエラー・警告 |
| completionItems | CompletionItem[] | 補完候補 |
| codeActions | CodeAction[] | クイックフィックス |

### 出力先

- 問題パネル（診断情報）
- エディタ内補完リスト
- 電球アイコン（コードアクション）

## 処理フロー

### 処理シーケンス

```
1. 拡張機能のアクティベーション
   └─ onLanguage:json/onLanguage:markdownで起動

2. ドキュメント監視開始
   └─ ExtensionLinterがファイルウォッチャー設定

3. ドキュメント変更検知
   └─ 300msのデバウンス後にlint実行

4. package.jsonリンティング
   ├─ アイコンURL検証
   ├─ バッジURL検証
   ├─ enabledApiProposals検証
   ├─ activationEvents検証
   └─ when句の構文検証

5. README.md/CHANGELOG.mdリンティング
   ├─ Markdownをパース
   └─ 画像URLを検証

6. 診断情報の発行
   └─ diagnosticsCollectionに追加
```

### フローチャート

```mermaid
flowchart TD
    A[ドキュメントを開く/変更] --> B{ファイルタイプ}
    B -->|package.json| C[ExtensionLinter.lintPackageJson]
    B -->|README.md/CHANGELOG.md| D[ExtensionLinter.lintReadme]
    C --> E{engines.vscode存在?}
    E -->|Yes| F[拡張機能として処理]
    E -->|No| G[スキップ]
    F --> H[アイコンURL検証]
    F --> I[バッジURL検証]
    F --> J[enabledApiProposals検証]
    F --> K[activationEvents検証]
    F --> L[when句検証]
    H --> M[診断情報発行]
    I --> M
    J --> M
    K --> M
    L --> M
    D --> N[Markdownパース]
    N --> O[画像URL抽出]
    O --> P{URL検証}
    P -->|HTTPS以外| Q[警告]
    P -->|信頼されていないSVG| R[警告]
    P -->|OK| S[スキップ]
    Q --> M
    R --> M
    G --> T[終了]
    M --> T
    S --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-1 | HTTPS必須 | 画像URLはHTTPSプロトコル必須 | バッジ/README画像 |
| BR-85-2 | SVG制限 | 信頼されていないソースのSVGは警告 | 画像URL |
| BR-85-3 | 提案API制限 | product.jsonで許可されていない提案APIは使用不可 | enabledApiProposals |
| BR-85-4 | 暗黙的アクティベーション | 冗長なアクティベーションイベントは警告 | activationEvents |
| BR-85-5 | スターアクティベーション | "*"アクティベーションは推奨しない（情報） | activationEvents |

### 許可されたSVGソース

product.jsonの`extensionAllowedBadgeProviders`と`extensionAllowedBadgeProvidersRegex`で定義。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | 画像URLがHTTPS以外 | Diagnostic表示 |
| - | 警告 | SVGソースが信頼されていない | Diagnostic表示 |
| - | エラー | 提案APIが許可リストにない | Diagnostic表示 |
| - | 警告 | 冗長なアクティベーションイベント | Diagnostic表示 |
| - | エラー | when句の構文エラー | Diagnostic表示 |

### リトライ仕様

リトライは行わない。ドキュメント変更時に自動的に再検証。

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

該当なし

## パフォーマンス要件

- リンティングは300msのデバウンスで実行
- 大きなREADMEでも効率的にパース

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

- 信頼されていないワークスペースでもサポート
- 仮想ワークスペースでもサポート

## 備考

- markdown-itライブラリを使用してMarkdownパース
- parse5ライブラリを使用してHTML解析

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | package.json | `extensions/extension-editing/package.json` | jsonValidationとlanguages定義 |
| 1-2 | extensionLinter.ts | `extensions/extension-editing/src/extensionLinter.ts` | PackageJsonInfoインターフェース（52-58行目） |

**読解のコツ**: PackageJsonInfoはpackage.jsonから抽出した拡張機能情報を保持する構造体。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extensionEditingMain.ts | `extensions/extension-editing/src/extensionEditingMain.ts` | activate関数 |

**主要処理フロー**:
1. **13行目**: registerPackageDocumentCompletions() - 補完プロバイダー登録
2. **16行目**: registerCodeActionsProvider() - コードアクション登録
3. **18行目**: ExtensionLinter初期化 - リンター開始

#### Step 3: リンティングロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extensionLinter.ts | `extensions/extension-editing/src/extensionLinter.ts` | ExtensionLinterクラス（60-598行目） |

**主要処理フロー**:
- **112-117行目**: lint()でpackage.jsonとREADMEを並列リント
- **119-201行目**: lintPackageJson()でpackage.json検証
- **272-374行目**: lintReadme()でREADME検証
- **203-270行目**: lintWhenClauses()でwhen句検証

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

```
activate() [extensionEditingMain.ts 10行目]
    │
    ├─ registerPackageDocumentCompletions() [21-26行目]
    │      └─ PackageDocument.provideCompletionItems()
    │
    ├─ registerCodeActionsProvider() [29-34行目]
    │      └─ PackageDocument.provideCodeActions()
    │
    └─ new ExtensionLinter() [18行目]
           │
           ├─ constructor [73-83行目]
           │      └─ イベントリスナー登録
           │
           ├─ queue() [85-92行目]
           │      └─ startTimer() [102-109行目]
           │
           └─ lint() [112-117行目]
                  │
                  ├─ lintPackageJson() [119-201行目]
                  │      │
                  │      ├─ readPackageJsonInfo() [394-415行目]
                  │      │
                  │      ├─ アイコンURL検証 [132-135行目]
                  │      ├─ バッジURL検証 [137-142行目]
                  │      ├─ enabledApiProposals検証 [144-160行目]
                  │      ├─ activationEvents検証 [161-194行目]
                  │      └─ when句検証 [196-197行目]
                  │
                  └─ lintReadme() [272-374行目]
                         │
                         └─ markdown-itでパース [294行目]
```

### データフロー図

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

package.json         ──▶ jsonc-parser.parseTree()
                            │
                            ▼
                      readPackageJsonInfo() [394行目]
                            │
                            ├──▶ engines.vscode確認
                            ├──▶ repository URL確認
                            └──▶ 暗黙的アクティベーション解析
                                   │
                                   ▼
                      addDiagnostics() [441行目]   ──▶ Diagnostic[]
                            │
                            ▼
README.md            ──▶ markdown-it.parse() [294行目]
                            │
                            ▼
                      tokensAndPositions [295-318行目]
                            │
                            ▼
                      画像URL検証 [322-335行目]   ──▶ Diagnostic[]
                            │
                            ▼
                      diagnosticsCollection.set() ──▶ 問題パネル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| extensionEditingMain.ts | `extensions/extension-editing/src/extensionEditingMain.ts` | ソース | エントリーポイント、プロバイダー登録 |
| extensionLinter.ts | `extensions/extension-editing/src/extensionLinter.ts` | ソース | リンティングロジック |
| packageDocumentHelper.ts | `extensions/extension-editing/src/packageDocumentHelper.ts` | ソース | 補完ロジック |
| constants.ts | `extensions/extension-editing/src/constants.ts` | ソース | エラーメッセージ定数 |
| extensionEngineValidation.ts | `extensions/extension-editing/src/extensionEngineValidation.ts` | ソース | エンジンバージョン検証 |
| package.json | `extensions/extension-editing/package.json` | 設定 | マニフェスト |
