# 機能設計書 9-YAML パース

## 概要

本ドキュメントは、PrettierのYAMLパース機能の設計について記述する。

### 本機能の処理概要

YAMLファイルをパースし、YAML AST（抽象構文木）を生成する機能である。yaml-unist-parserライブラリを使用して、YAMLの複雑な構文（アンカー、エイリアス、複数ドキュメント等）をサポートする。

**業務上の目的・背景**：YAMLは設定ファイル、CI/CDパイプライン定義、Kubernetes マニフェストなど、多くの場面で使用されるデータシリアライゼーション言語である。これらのファイルを一貫したスタイルでフォーマットすることで、可読性と保守性を向上させる。

**機能の利用シーン**：
- YAMLファイル（.yml, .yaml）のフォーマット
- CI/CD設定ファイル（.github/workflows/*.yml等）のフォーマット
- Kubernetes マニフェストのフォーマット
- docker-compose.ymlのフォーマット
- Playgroundでのプレビュー

**主要な処理内容**：
1. yaml-unist-parserによるパース
2. 重複キー許可オプションの設定
3. コメント処理（削除）
4. エラーハンドリング

**関連システム・外部連携**：
- yaml-unist-parser（YAMLパーサー）
- unist形式のAST

**権限による制御**：特になし。すべてのユーザーがパーサー機能を利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | API連携 | YAMLファイルをパース |
| 5 | About - Prettier概要 | 補助機能 | 対応言語としてYAMLパースを説明 |

## 機能種別

計算処理 / パース処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text | string | Yes | パース対象のYAMLテキスト | - |
| options | object | No | パースオプション | - |
| options.parser | string | No | パーサー名（yaml） | 有効なパーサー名 |
| options.filepath | string | No | ファイルパス（パーサー推論用） | - |

### 入力データソース

- YAMLテキスト
- ファイルパス情報（パーサー推論用）

### サポートパーサー

| パーサー名 | 説明 | 特徴 |
|-----------|------|------|
| yaml | YAMLパーサー | YAML 1.2準拠、重複キー許可 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast | object | パースされたYAML AST |
| ast.type | string | ルートノードタイプ |
| ast.children | array | ドキュメントノード配列 |

### 出力先

- パース関数の戻り値として返却
- プリンターで使用

## 処理フロー

### 処理シーケンス

```
1. パースオプション設定
   └─ allowDuplicateKeysInMap: true

2. yaml-unist-parser呼び出し
   └─ parseYaml(text, options)

3. コメント削除
   └─ root.commentsを削除
   └─ printer-yamlで独自処理するため

4. エラーハンドリング
   └─ パースエラー時は位置情報付きエラーを生成

5. AST返却
```

### フローチャート

```mermaid
flowchart TD
    A[パース開始] --> B[パースオプション設定]
    B --> C[parseYaml呼び出し]
    C --> D{パース成功?}
    D -->|No| E{位置情報あり?}
    E -->|Yes| F[位置情報付きエラー生成]
    E -->|No| G[エラー再スロー]
    F --> H[エラースロー]
    G --> H
    D -->|Yes| I[root.comments削除]
    I --> J[AST返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 重複キー許可 | マップ内の重複キーを許可 | 常時 |
| BR-02 | コメント別処理 | コメントはprinter-yamlで独自処理 | 常時 |
| BR-03 | 複数ドキュメント | ---区切りの複数ドキュメントをサポート | 常時 |
| BR-04 | アンカー/エイリアス | &anchor、*aliasをサポート | 常時 |

### 計算ロジック

**パースオプション**：
```javascript
const parseOptions = {
  allowDuplicateKeysInMap: true,
};
```

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

### 操作別データベース影響一覧

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パースエラー | YAML構文エラー | YAMLを修正 |
| ConfigError | 設定エラー | パーサーが見つからない | パーサー名を確認 |

### リトライ仕様

リトライは行わない。エラー発生時は即座に例外をスロー。

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

トランザクション管理は不要（ステートレスな処理）。

## パフォーマンス要件

- 一般的なYAMLファイル（300行程度）のパースは15ms以内
- 複雑なネスト構造でも安定した処理時間

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

- 入力コードの実行は行わない（静的解析のみ）
- YAMLの危険なタグ（!!python/object等）は解釈しない

## 備考

- コメントはAST.commentsから削除されるが、printer-yamlで独自に処理される
- YAML 1.2仕様に準拠
- 重複キーを許可する設定により、実世界のYAMLファイルとの互換性を確保

---

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

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

### 推奨読解順序

#### Step 1: パーサープラグインの構成を理解する

YAMLパーサーがプラグインとしてどのように構成されているかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | yaml.js | `src/plugins/yaml.js` | YAMLパーサープラグインのエクスポート |
| 1-2 | index.js | `src/language-yaml/index.js` | 言語モジュールの構成 |

#### Step 2: パーサー実装を理解する

YAMLパーサーの詳細な実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | parser-yaml.js | `src/language-yaml/parser-yaml.js` | パーサー実装本体 |

**主要処理フロー**:
- **1行目**: yaml-unist-parserのインポート
- **6-8行目**: parseOptionsの定義
- **10-34行目**: parse関数
  - **12行目**: parseYaml呼び出し
  - **20行目**: root.comments削除
  - **23-29行目**: エラーハンドリング
- **36-43行目**: パーサーオブジェクトのエクスポート

```javascript
const parseOptions = {
  allowDuplicateKeysInMap: true,
};

function parse(text) {
  try {
    const root = parseYaml(text, parseOptions);
    delete root.comments;  // printer-yamlで独自処理
    return root;
  } catch (error) {
    if (error?.position) {
      throw createError(error.message, {
        loc: error.position,
        cause: error,
      });
    }
    throw error;
  }
}
```

#### Step 3: プラグマ処理を理解する

YAMLのプラグマ処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pragma.js | `src/language-yaml/pragma.js` | プラグマ処理 |

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

```
parser-yaml.js (src/language-yaml/parser-yaml.js)
    │
    └─ yaml (エクスポートされるパーサーオブジェクト)
           │
           ├─ parse
           │      │
           │      ├─ parseYaml (yaml-unist-parser)
           │      │
           │      └─ createError (エラー時)
           │
           ├─ hasPragma (pragma.js)
           │
           ├─ hasIgnorePragma (pragma.js)
           │
           ├─ locStart (loc.js)
           │
           └─ locEnd (loc.js)
```

### データフロー図

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

YAMLテキスト ───────────▶ parseYaml ───────────────────────▶ 生AST
                              │
                              ▼
                         コメント削除 ─────────────────────▶ 整形AST
                              │
                              ▼
                         （エラー時）
                         createError ─────────────────────▶ エラー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| yaml.js | `src/plugins/yaml.js` | ソース | YAMLパーサープラグイン |
| index.js | `src/language-yaml/index.js` | ソース | 言語モジュールエクスポート |
| parser-yaml.js | `src/language-yaml/parser-yaml.js` | ソース | パーサー実装本体 |
| pragma.js | `src/language-yaml/pragma.js` | ソース | プラグマ処理 |
| loc.js | `src/language-yaml/loc.js` | ソース | 位置情報関数 |
| printer-yaml.js | `src/language-yaml/printer-yaml.js` | ソース | YAMLプリンター |
| options.js | `src/language-yaml/options.js` | ソース | YAMLオプション定義 |
