# 機能設計書 10-GraphQL パース

## 概要

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

### 本機能の処理概要

GraphQLクエリおよびスキーマをパースし、GraphQL AST（抽象構文木）を生成する機能である。graphql-jsライブラリを使用して、クエリ、ミューテーション、サブスクリプション、スキーマ定義などをサポートする。

**業務上の目的・背景**：GraphQLはAPIクエリ言語として広く採用されており、スキーマ定義やクエリの一貫したフォーマットは、開発チームの生産性とコードの可読性向上に貢献する。

**機能の利用シーン**：
- GraphQLクエリファイル（.graphql, .gql）のフォーマット
- GraphQLスキーマ定義（.graphqls）のフォーマット
- GraphQL操作（クエリ、ミューテーション、サブスクリプション）のフォーマット
- Playgroundでのプレビュー

**主要な処理内容**：
1. graphql-jsのparse関数によるパース
2. レガシーフラグメント変数オプションの設定
3. コメントトークンの抽出
4. エラーハンドリング

**関連システム・外部連携**：
- graphql-js（GraphQL公式パーサー）
- GraphQL仕様に準拠したAST

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | API連携 | GraphQLクエリ・スキーマをパース |
| 5 | About - Prettier概要 | 補助機能 | 対応言語としてGraphQLパースを説明 |

## 機能種別

計算処理 / パース処理

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

### サポートパーサー

| パーサー名 | 説明 | 特徴 |
|-----------|------|------|
| graphql | GraphQLパーサー | graphql-js使用、レガシーフラグメント変数許可 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast | object | パースされたGraphQL AST |
| ast.kind | string | "Document" |
| ast.definitions | array | 定義ノード配列 |
| ast.comments | array | コメント配列（パース後に追加） |

### 出力先

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

## 処理フロー

### 処理シーケンス

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

2. graphql-js parse呼び出し
   └─ parseGraphql(text, parseOptions)

3. コメント抽出
   └─ トークンリストからCommentトークンを抽出
   └─ ast.commentsに追加

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

5. AST返却
```

### フローチャート

```mermaid
flowchart TD
    A[パース開始] --> B[パースオプション設定]
    B --> C[parseGraphql呼び出し]
    C --> D{パース成功?}
    D -->|No| E{GraphQLError?}
    E -->|Yes| F[位置情報付きエラー生成]
    E -->|No| G[エラー再スロー]
    F --> H[エラースロー]
    G --> H
    D -->|Yes| I[parseComments - コメント抽出]
    I --> J[ast.commentsに追加]
    J --> K[AST返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | レガシーフラグメント変数 | レガシーなフラグメント変数構文を許可 | 常時 |
| BR-02 | コメント抽出 | トークンリストからコメントを抽出してAST.commentsに追加 | 常時 |
| BR-03 | 位置情報 | 各コメントにloc（start, end）を付与 | 常時 |

### 計算ロジック

**コメント抽出**：
```javascript
function parseComments(ast) {
  const comments = [];
  const { startToken, endToken } = ast.loc;
  for (let token = startToken; token !== endToken; token = token.next) {
    if (token.kind === "Comment") {
      comments.push({ ...token, loc: { start: token.start, end: token.end } });
    }
  }
  return comments;
}
```

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

- 一般的なGraphQLファイル（200行程度）のパースは10ms以内
- 複雑なスキーマ定義でも安定した処理時間

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

- 入力コードの実行は行わない（静的解析のみ）
- GraphQLクエリは実行されない（パースのみ）

## 備考

- graphql-jsはGraphQL公式のJavaScript実装
- allowLegacyFragmentVariablesは後方互換性のため有効化
- コメントはトークンリストを走査して手動抽出

---

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

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

### 推奨読解順序

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

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

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

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

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

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

**主要処理フロー**:
- **1行目**: graphql-jsのインポート（GraphQLError, parse）
- **6-16行目**: parseComments関数（コメント抽出）
- **18-20行目**: parseOptionsの定義
- **22-33行目**: createParseError関数（エラー整形）
- **35-46行目**: parse関数本体
  - **38行目**: parseGraphql呼び出し
  - **44行目**: ast.comments追加
- **48-55行目**: パーサーオブジェクトのエクスポート

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

function parse(text) {
  let ast;
  try {
    ast = parseGraphql(text, parseOptions);
  } catch (error) {
    throw createParseError(error);
  }
  ast.comments = parseComments(ast);
  return ast;
}
```

#### Step 3: コメント抽出を理解する

parseComments関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | parser-graphql.js | `src/language-graphql/parser-graphql.js` | parseComments関数 |

**主要処理フロー**:
- トークンリストをstartTokenからendTokenまで走査
- kind === "Comment"のトークンを収集
- locオブジェクトを付与

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

```
parser-graphql.js (src/language-graphql/parser-graphql.js)
    │
    └─ graphql (エクスポートされるパーサーオブジェクト)
           │
           ├─ parse
           │      │
           │      ├─ parseGraphql (graphql-js)
           │      │
           │      ├─ createParseError (エラー時)
           │      │
           │      └─ parseComments (コメント抽出)
           │
           ├─ hasPragma (pragma.js)
           │
           ├─ hasIgnorePragma (pragma.js)
           │
           ├─ locStart (loc.js)
           │
           └─ locEnd (loc.js)
```

### データフロー図

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

GraphQLテキスト ─────────▶ parseGraphql ───────────────────▶ 生AST
                              │
                              ▼
                         parseComments ────────────────────▶ コメント配列
                              │
                              ▼
                         ast.comments追加 ─────────────────▶ 完全AST
                              │
                              ▼
                         （エラー時）
                         createParseError ─────────────────▶ エラー
```

### 関連ファイル一覧

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