# 機能設計書 73-設定ローダー

## 概要

本ドキュメントは、Lua Language Serverにおける設定ローダー機能の設計を記述する。この機能は、.luarc.json、config.lua、およびLSPクライアントからの設定を読み込み、統一されたフォーマットに変換して設定管理システムに提供する。

### 本機能の処理概要

**業務上の目的・背景**：Lua Language Serverは複数の設定ソースをサポートする必要がある。開発者はプロジェクトごとに.luarc.jsonを配置したり、VSCodeの設定パネルから設定を変更したりする。設定ローダーはこれらの異なるソースからの設定を統一的に読み込み、サーバーが利用できる形式に変換する役割を担う。

**機能の利用シーン**：
- サーバー起動時の初期設定読み込み
- ワークスペースフォルダ変更時の設定再読み込み
- .luarc.jsonファイルの変更検知時
- LSPクライアントからのworkspace/configuration要求時

**主要な処理内容**：
1. RCファイル（.luarc.json）の読み込みとJSONC解析
2. ローカル設定ファイル（JSON/Lua形式）の読み込み
3. LSPクライアントからの設定取得（workspace/configuration）
4. 設定読み込みエラー時のフォールバック処理
5. 前回正常値のキャッシュと復元

**関連システム・外部連携**：
- LSPクライアント（VSCode等）との設定同期
- ファイルシステムからの設定ファイル読み込み
- 設定管理システムへの設定提供
- ワークスペース管理システム（パス解決）

**権限による制御**：特になし。すべてのユーザーが設定ファイルを読み込み可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 31 | 設定変更 | 参照画面 | 設定ファイルの読み込み処理 |

## 機能種別

ファイル読み込み / データ変換処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | uri | Yes | 設定を適用するスコープのURI | 有効なファイルURI |
| filename | string | Yes | 設定ファイル名（loadLocalConfig用） | 有効なファイルパス |

### 入力データソース

- .luarc.json ファイル（JSONC形式）
- 任意のローカル設定ファイル（JSON/Lua形式）
- LSPクライアントからのworkspace/configurationレスポンス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| config | table | 読み込んだ設定テーブル |
| nil | nil | 読み込み失敗時 |

### 出力先

- 設定管理システム（config.update）
- スコープキャッシュ（lastRCConfig, lastLocalConfig）

## 処理フロー

### 処理シーケンス

```
1. ファイルパスの解決
   └─ ワークスペースからの相対パス解決
2. ファイル内容の読み込み
   └─ util.loadFileでファイル読み込み
3. フォーマット判定
   └─ 先頭文字で JSON/Lua を判定
4. 内容の解析
   └─ JSONC解析 または Luaコード実行
5. エラー処理
   └─ 失敗時はエラー通知と前回値復元
6. キャッシュ保存
   └─ 正常値をスコープにキャッシュ
```

### フローチャート

```mermaid
flowchart TD
    A[設定読み込み開始] --> B[ファイルパス解決]
    B --> C{パス存在?}
    C -->|No| D[キャッシュクリア, nil返却]
    C -->|Yes| E[ファイル読み込み]
    E --> F{読み込み成功?}
    F -->|No| D
    F -->|Yes| G{JSON形式?}
    G -->|Yes| H[JSONC解析]
    G -->|No| I[Lua実行]
    H --> J{解析成功?}
    I --> J
    J -->|No| K[エラー通知, 前回値返却]
    J -->|Yes| L[キャッシュ保存]
    L --> M[設定テーブル返却]
    K --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | フォーマット自動判定 | ファイル先頭の非空白文字が`{`ならJSON、それ以外はLua | loadLocalConfig |
| BR-73-02 | JSONC対応 | コメント付きJSONを解析可能 | JSON形式ファイル |
| BR-73-03 | 前回値復元 | 解析エラー時は前回の正常値を返却 | 解析失敗時 |
| BR-73-04 | エラー通知 | 解析エラー時はクライアントにメッセージ表示 | 解析失敗時 |

### 計算ロジック

**フォーマット判定ロジック**:
```lua
local firstChar = buf:match '%S'
if firstChar == '{' then
    -- JSON形式として解析
    local suc, res = pcall(jsonc.decode_jsonc, buf)
else
    -- Lua形式として実行
    local suc, res = pcall(function ()
        return assert(load(buf, '@' .. path, 't'))()
    end)
end
```

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

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

本機能はファイルシステム操作のみで、データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CONFIG_LOAD_FAILED | ファイル読込失敗 | ファイルが存在しない | nilを返却、キャッシュクリア |
| CONFIG_LOAD_ERROR | 解析エラー | JSON/Lua構文エラー | エラー通知、前回値返却 |

### リトライ仕様

リトライは行わない。ファイル変更時に再度読み込みが試行される。

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

トランザクション管理は不要。読み取り専用の処理。

## パフォーマンス要件

- ファイル読み込みは非同期で実行（awaitRequest使用）
- キャッシュにより同一設定の再解析を回避

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

- Lua形式の設定ファイルはコードとして実行されるため、信頼できるソースのみ使用
- `load`関数の第4引数でグローバル環境を制限なしで渡している点に注意

## 備考

- loadRCConfigは.luarc.json専用、loadLocalConfigは汎用
- loadClientConfigはLSPのworkspace/configurationリクエストを使用

---

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

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

### 推奨読解順序

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

設定ローダーモジュールの構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | loader.lua | `script/config/loader.lua` | 17-19行目: config.loaderクラス定義 |

**読解のコツ**: このモジュールは3つの主要な読み込み関数を提供する。

#### Step 2: RCファイル読み込みを理解する

.luarc.json の読み込み処理。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | loader.lua | `script/config/loader.lua` | 20-41行目: loadRCConfig関数 |

**主要処理フロー**:
1. **22-23行目**: スコープとパスの取得
2. **28行目**: util.loadFileでファイル読み込み
3. **33行目**: jsonc.decode_jsoncでJSONC解析
4. **36行目**: エラー時は前回値を返却

#### Step 3: ローカル設定読み込みを理解する

JSON/Lua形式の汎用設定ファイル読み込み。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | loader.lua | `script/config/loader.lua` | 43-85行目: loadLocalConfig関数 |

**主要処理フロー**:
- **62行目**: 先頭文字でフォーマット判定
- **63-72行目**: JSON形式の場合の処理
- **73-84行目**: Lua形式の場合の処理

#### Step 4: クライアント設定読み込みを理解する

LSPクライアントからの設定取得。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | loader.lua | `script/config/loader.lua` | 87-130行目: loadClientConfig関数 |

**主要処理フロー**:
- **91-114行目**: workspace/configurationリクエスト送信
- **120-127行目**: レスポンスを設定テーブルに変換

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

```
m.loadRCConfig (公開API)
    │
    ├─ scope.getScope(uri)
    │
    ├─ workspace.getAbsolutePath(uri, filename)
    │
    ├─ util.loadFile(path)
    │
    └─ jsonc.decode_jsonc(buf)

m.loadLocalConfig (公開API)
    │
    ├─ scope.getScope(uri)
    │
    ├─ workspace.getAbsolutePath(uri, filename)
    │
    ├─ util.loadFile(path)
    │
    └─ jsonc.decode_jsonc(buf) または load(buf)()

m.loadClientConfig (公開API, async)
    │
    └─ proto.awaitRequest('workspace/configuration')
           │
           └─ LSPクライアントに設定要求
```

### データフロー図

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

.luarc.json ─────────▶ loadRCConfig ─────────▶ ┐
                           │                   │
                           ▼                   │
                      JSONC解析                │
                                               │
ローカル設定ファイル ▶ loadLocalConfig ─────▶ ├─▶ 設定テーブル
                           │                   │     (table)
                           ▼                   │
                      JSON/Lua解析             │
                                               │
LSPクライアント ────▶ loadClientConfig ────▶ ┘
                           │
                           ▼
                      workspace/configuration
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| loader.lua | `script/config/loader.lua` | ソース | 設定ローダーのメインモジュール |
| jsonc.lua | `script/jsonc.lua` | ソース | JSONC（コメント付きJSON）解析 |
| utility.lua | `script/utility.lua` | ソース | ファイル読み込みユーティリティ |
| proto.lua | `script/proto.lua` | ソース | LSPプロトコル通信 |
| workspace.lua | `script/workspace/init.lua` | ソース | パス解決機能 |
| scope.lua | `script/workspace/scope.lua` | ソース | スコープ管理 |
| language.lua | `script/language.lua` | ソース | エラーメッセージの多言語対応 |
