# 帳票設計書 4-ZOIRデバッグ出力

## 概要

本ドキュメントは、Zigコンパイラにおける ZOIR（ZON Intermediate Representation）デバッグ出力帳票の設計仕様を記述するものである。ZOIRはZON（Zig Object Notation）ファイルから生成される中間表現であり、本帳票はその内容をノード数・メモリサイズ統計と共に人間が読みやすいテキスト形式で出力する機能を定義する。

### 本帳票の処理概要

ZOIRデバッグ出力は、ZONファイルがパース・処理された後の内部表現を可視化するための帳票である。ZONはZigの構成ファイル（build.zig.zon等）やデータファイルに使用されるフォーマットであり、そのパース結果を詳細に確認できる。

**業務上の目的・背景**：ZONはZigのビルドシステムで広く使用される設定ファイルフォーマットである。build.zig.zonでのプロジェクト依存関係の定義など、重要な用途に使われる。本帳票により、開発者はZONファイルのパース結果を検証し、パーサーの正確性確認やデバッグを効率的に行える。また、メモリ使用量の統計情報により、大規模なZONファイルのパフォーマンス分析も可能となる。

**帳票の利用シーン**：
1. ZONパーサー開発者がパース結果のデバッグを行う際
2. build.zig.zonの解析問題を調査する際
3. ZONファイルのメモリフットプリント分析
4. 新しいZON構文サポート追加時の動作確認
5. ZON関連のコンパイラバグ調査

**主要な出力内容**：
1. 統計情報（ノード数、Extra Data、BigInt Limbs、文字列テーブル、総バイト数）
2. 各ノードの詳細（ノードタイプ、値）
3. リテラル値（整数、浮動小数点、文字、文字列、enum）
4. 構造化リテラル（配列、構造体）の階層構造

**帳票の出力タイミング**：`renderToWriter`関数の明示的呼び出し時に出力される。

**帳票の利用者**：Zigコンパイラ開発者、ビルドシステム開発者、ZONパーサー保守担当者

## 帳票種別

デバッグ/診断レポート

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | デバッグAPI | `print_zoir.renderToWriter()` | プログラムからの呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（指定Writer） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（Writer出力） |
| 出力方法 | バッファリングされたストリーム書き込み |
| 文字コード | UTF-8 |

## 帳票レイアウト

### レイアウト概要

ZOIRデバッグ出力は統計ヘッダーとノードツリーで構成される。

```
┌─────────────────────────────────────────────────────────────┐
│ # Nodes:              N (XXX bytes)                         │
│ # Extra Data Items:   N (XXX bytes)                         │
│ # BigInt Limbs:       N (XXX bytes)                         │
│ # String Table Bytes: XXX bytes                             │
│ # Total ZON Bytes:    XXX bytes                             │
├─────────────────────────────────────────────────────────────┤
│ %0 = root_node_type(value)                                  │
│   %1 = child_node_type(value),                              │
│   %2 = child_node_type(value),                              │
│   ...                                                       │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Nodes | ノード数とサイズ | `zoir.nodes.len` | `{} ({Bi})` |
| 2 | Extra Data Items | 追加データ項目数 | `zoir.extra.len` | `{} ({Bi})` |
| 3 | BigInt Limbs | 大整数リム数 | `zoir.limbs.len` | `{} ({Bi})` |
| 4 | String Table Bytes | 文字列テーブルサイズ | `zoir.string_bytes.len` | `{Bi}` |
| 5 | Total ZON Bytes | 総バイト数 | 計算値 | `{Bi}` |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | ノード番号 | ZOIRノードのインデックス | `Zoir.Node.Index` | `%N` | 可変 |
| 2 | ノードタイプ | ノードの種別 | `Zoir.Node` | 型名 | 可変 |
| 3 | 値 | ノードの値 | ノード固有データ | 型に応じた表現 | 可変 |

### フッター部

N/A

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| コンパイルエラーなし | `!zoir.hasCompileErrors()` | Yes |
| renderToWriter呼び出し | 明示的なAPI呼び出し | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ノードインデックス | 昇順（深さ優先） |

### 改ページ条件

N/A（連続テキスト出力）

## データベース参照仕様

N/A（データベースを使用しない。コンパイラ内部のZOIRデータ構造を参照）

### 内部データ構造参照

| 参照項目 | 帳票項目との対応 | 取得条件 | 備考 |
|---------|----------------|---------|------|
| `Zoir.nodes` | 各ノードの詳細 | 全ノードを走査 | ノードのRepr構造体 |
| `Zoir.extra` | 追加データ | ノードタイプに応じて | 可変長データ |
| `Zoir.limbs` | 大整数のリム | big整数参照時 | std.math.big.Limb |
| `Zoir.string_bytes` | 文字列リテラル | 文字列参照時 | バイト配列 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| bytes_per_node | `@sizeOf(Zoir.Node.Repr)`のフィールドサイズ合計 | なし | comptime計算 |
| node_bytes | `nodes.len * bytes_per_node` | なし | - |
| extra_bytes | `extra.len * @sizeOf(u32)` | なし | 4バイト/項目 |
| limb_bytes | `limbs.len * @sizeOf(std.math.big.Limb)` | なし | - |
| total_bytes | `node_bytes + extra_bytes + limb_bytes + string_bytes.len` | なし | - |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[renderToWriter呼び出し] --> B{hasCompileErrors?}
    B -->|Yes| C[assert失敗]
    B -->|No| D[サイズ計算]
    D --> E[統計ヘッダー出力]
    E --> F[PrintZon初期化]
    F --> G[renderRoot呼び出し]
    G --> H[renderNode(root)]
    H --> I{ノードタイプ?}
    I -->|リテラル| J[値を直接出力]
    I -->|配列| K[要素を再帰出力]
    I -->|構造体| L[フィールドを再帰出力]
    J --> M[改行出力]
    K --> M
    L --> M
    M --> N[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| WriteFailed | 出力ストリームエラー | なし | エラー返却 |
| OutOfMemory | アロケーション失敗 | なし | エラー返却 |
| アサーション失敗 | コンパイルエラー存在時 | assert失敗 | 呼び出し元で事前チェック |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数十〜数千ノード（ZONファイルサイズに依存） |
| 目標出力時間 | O(N)（ノード数に比例） |
| 同時出力数上限 | 1件 |

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

- ZOIRダンプにはZONファイルの全内容が含まれる
- 依存関係URLや認証情報がZONに含まれる場合は注意

## 備考

- `hasCompileErrors()`がtrueの場合は出力不可（assertで強制）
- インデント管理により階層構造を視覚化
- 大整数は`toStringAlloc`で10進数文字列に変換

---

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

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

### 推奨読解順序

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

ZOIRの基本構造を理解することが前提となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Zoir.zig | `lib/std/zig/Zoir.zig`（標準ライブラリ） | `Zoir`構造体：nodes, extra, limbs, string_bytes |
| 1-2 | Zoir.zig | `lib/std/zig/Zoir.zig` | `Node`構造体：各ノードタイプの定義 |

**読解のコツ**: ZOIRはZONデータをツリー構造で表現。リテラル値と構造化データ（配列・構造体）を区別して理解する。

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

ZOIRテキスト出力の起点を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | print_zoir.zig | `src/print_zoir.zig` | `renderToWriter`関数（行3-43）：エントリーポイント |

**主要処理フロー**:
1. **行4**: `assert(!zoir.hasCompileErrors())`でエラーチェック
2. **行6-12**: bytes_per_nodeのcomptime計算
3. **行14-17**: 各データサイズの計算
4. **行19-33**: 統計ヘッダーの出力
5. **行35-43**: PrintZon初期化とrenderRoot呼び出し

#### Step 3: PrintZon構造体を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | print_zoir.zig | `src/print_zoir.zig` | `PrintZon`構造体（行45-50）：出力状態管理 |
| 3-2 | print_zoir.zig | `src/print_zoir.zig` | `renderRoot`関数（行51-54）：ルートノード出力 |
| 3-3 | print_zoir.zig | `src/print_zoir.zig` | `renderNode`関数（行56-104）：ノードタイプに応じた出力 |

**主要処理フロー**:
- `indent`: インデントレベル管理
- `arena`: 一時メモリアロケータ（大整数変換用）

#### Step 4: ノード出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | print_zoir.zig | `src/print_zoir.zig` | `renderNode`のswitch文（行59-103）：ノードタイプごとの出力 |
| 4-2 | print_zoir.zig | `src/print_zoir.zig` | `newline`関数（行106-109）：インデント付き改行 |

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

```
renderToWriter
    |
    +-- 統計計算・ヘッダー出力
    |
    +-- PrintZon初期化
    |
    +-- renderRoot
            |
            +-- renderNode(root)
                    |
                    +-- [ノードタイプに応じた分岐]
                    |       |
                    |       +-- true/false/null/inf/nan: 固定文字列
                    |       +-- int_literal: 整数値出力
                    |       +-- float_literal: 浮動小数点出力
                    |       +-- char_literal: 文字出力
                    |       +-- enum_literal: 識別子出力
                    |       +-- string_literal: 文字列出力
                    |       +-- empty_literal: ".{}"出力
                    |       +-- array_literal: 要素を再帰出力
                    |       +-- struct_literal: フィールドを再帰出力
                    |
                    +-- newline (インデント管理)
```

### データフロー図

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

Zoir構造体           ─────> renderToWriter ───────────────> Writer
  |                         |
  +-- nodes          ─────> renderNode ───────────────────> "%N = type(value)"
  |                         |
  +-- extra          ─────> 配列/構造体のインデックス参照 ─> 子ノード
  |                         |
  +-- limbs          ─────> toStringAlloc ────────────────> 大整数文字列
  |                         |
  +-- string_bytes   ─────> 直接参照 ─────────────────────> 文字列値
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| print_zoir.zig | `src/print_zoir.zig` | ソース | ZOIRテキスト出力のメイン実装 |
| Zoir.zig | `lib/std/zig/Zoir.zig` | ソース（標準ライブラリ） | ZOIRデータ構造定義 |
| std.math.big | 標準ライブラリ | ソース | 大整数処理 |
