# 機能設計書 75-DCDクライアント (serve-d:dcd)

## 概要

本ドキュメントは、serve-dのサブパッケージ `serve-d:dcd` の設計を記述する。DCD（D Completion Daemon）サーバーとの直接通信を行うクライアントを提供し、プロセス生成なしの低レイテンシ通信を実現するサブパッケージである。

### 本機能の処理概要

**業務上の目的・背景**：DCDはD言語のコード補完・シンボル検索・定義ジャンプ等のセマンティック解析を提供するデーモンプロセスである。serve-dはDCDと通信してこれらの機能をLSPクライアントに提供する。本サブパッケージは、外部DCDクライアントプロセスを介さずにDCDサーバーと直接ソケット通信を行うBuiltinDCDClientを提供し、通信オーバーヘッドを最小化する。

**機能の利用シーン**：serve-dがコード補完、定義ジャンプ、ホバー情報、シンボル検索、ドキュメントハイライト、インレイヒント等のLSP機能を処理する際に、DCDサーバーとの通信クライアントとして使用される。

**主要な処理内容**：
1. IDCDClientインターフェース：DCD通信の全操作を定義する抽象インターフェース
2. BuiltinDCDClient：ソケット（TCP/Unixドメインソケット）を使用した直接通信クライアント
3. ExternalDCDClient：dcd-clientプロセスをパイプ経由で呼び出す外部クライアント
4. データ型定義：CodeRequest、SymbolInformation、Completion、LocalUse、InlayHint

**関連システム・外部連携**：DCDサーバープロセスとのソケット通信（TCP: 127.0.0.1またはUnixドメインソケット）。dcd-clientバイナリの外部プロセス呼び出し（ExternalDCDClientの場合）。

**権限による制御**：なし（DCDサーバーとのローカル通信のみ）

## 関連画面

本サブパッケージは直接的に画面と関連しない。コード補完、定義ジャンプ等の全てのDCD依存機能が間接的に使用する。

## 機能種別

基盤ライブラリ / クライアント通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CodeRequest.fileName | string | Yes | 対象ファイル名 | - |
| CodeRequest.sourceCode | const(char)[] | Yes | ソースコードの内容 | - |
| CodeRequest.cursorPosition | size_t | Yes | カーソル位置（バイトオフセット） | デフォルトsize_t.max |
| query (requestSymbolSearch) | string | Yes | シンボル検索クエリ文字列 | - |
| importPaths | string[] | Yes | インポートパスの配列 | 各パスが空でないこと |

### 入力データソース

- serve-dの各LSP機能モジュールからの呼び出し
- DCDサーバーからのレスポンス

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Completion | struct | 補完結果（タイプ: identifiers/calltips、補完候補配列） |
| SymbolInformation | struct | シンボル位置情報（ファイルパス、宣言位置） |
| LocalUse | struct | ローカル使用箇所（宣言位置と全使用箇所のオフセット配列） |
| InlayHint | struct | インレイヒント（種類、識別子、位置） |
| DCDResponse.Completion[] | struct[] | シンボル検索結果の配列 |

### 出力先

serve-dの各LSP機能モジュール（complete.d、definition.d、highlight.d等）

## 処理フロー

### 処理シーケンス

```
1. CodeRequestの構築
   └─ ファイル名、ソースコード、カーソル位置を設定
2. ソケット接続
   └─ TCP（127.0.0.1:port）またはUnixドメインソケットで接続
3. リクエスト送信
   └─ AutocompleteRequestをDCDプロトコルでシリアライズして送信
4. レスポンス受信
   └─ DCDプロトコルでデシリアライズしてDCDResponseを取得
5. 結果変換
   └─ DCDResponseをserve-d内部の型（Completion、SymbolInformation等）に変換
6. 接続クローズ
   └─ ソケットのshutdownとclose
```

### フローチャート

```mermaid
flowchart TD
    A[CodeRequest構築] --> B{BuiltinDCDClient?}
    B -->|Yes| C[ソケット接続]
    B -->|No| D[dcd-clientプロセス起動]
    C --> E[AutocompleteRequest送信]
    D --> F[パイプ経由でリクエスト送信]
    E --> G[DCDResponse受信]
    F --> H[stdout読み込み・パース]
    G --> I[内部型に変換]
    H --> I
    I --> J[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-01 | ソケット選択 | macOS/Linux/BSDではUnixドメインソケット、それ以外ではTCPを使用 | BuiltinDCDClient初期化時 |
| BR-75-02 | 排他制御 | ソケット操作はMutexで排他制御し、同時アクセスを防止 | 全リクエスト |
| BR-75-03 | 受信タイムアウト | ソケットの受信タイムアウトは5秒 | ソケット接続時 |
| BR-75-04 | バージョン互換性 | サポートするDCDサーバーバージョンは0.8.0以上0.17.0未満 | クライアント初期化時 |
| BR-75-05 | stdinからの入力 | ExternalDCDClientではソースコードをdcd-clientプロセスのstdinに書き込む | 外部クライアント使用時 |

### 計算ロジック

特になし。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Exception | DCDサーバーへのリクエスト送信が失敗した場合 | "Failed to send request"例外を発生 |
| - | Exception | DCDレスポンスの受信中にエラーが発生した場合 | DCDResponse.initを返却 |
| - | assert | 接続中に再度connectForRequestを呼び出した場合 | assert失敗（プログラミングエラー） |

### リトライ仕様

リトライは行わない。呼び出し元の各LSP機能で適切なフォールバック処理を行う。

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

不要（ステートレスなリクエスト/レスポンス通信）。

## パフォーマンス要件

- BuiltinDCDClient：プロセス生成オーバーヘッドなしの低レイテンシ通信
- ExternalDCDClient：毎回dcd-clientプロセスを生成するため、BuiltinDCDClientより高レイテンシ
- ソケット受信タイムアウト: 5秒
- Mutex排他制御による逐次リクエスト処理

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

DCDサーバーとの通信はローカルホスト(127.0.0.1)またはUnixドメインソケットに限定されており、ネットワーク経由の外部アクセスは不可。

## 備考

- `platformSupportsDCDUnixSockets`定数でプラットフォームのUnixドメインソケットサポートを判定
- ExternalDCDClientはフォールバック用であり、通常はBuiltinDCDClientが使用される
- `unescapeTabs`関数でDCDレスポンス中のエスケープされたタブ・改行文字を復元

---

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

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

### 推奨読解順序

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

DCD通信に使用されるデータ型を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | client.d | `dcd/source/served/dcd/client.d` | CodeRequest構造体（631-646行目）、SymbolInformation（648-658行目）、Completion（660-670行目）、LocalUse（672-684行目）、InlayHint（686-691行目） |

**読解のコツ**: `CodeRequest.apply`メソッド（638-645行目）は`const(char)[]`から`ubyte[]`へのキャストを行う。`@trusted`で安全性を保証しており、DCDプロトコルのAutocompleteRequestに変換する。

#### Step 2: インターフェースを理解する

IDCDClientインターフェースで定義される全操作を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | client.d | `dcd/source/served/dcd/client.d` | IDCDClientインターフェース（33-53行目）: 全操作メソッドの定義 |

**主要処理フロー**:
- **41行目**: `queryRunning` - DCDサーバーの稼働確認
- **42行目**: `shutdown` - DCDサーバーのシャットダウン
- **43行目**: `clearCache` - キャッシュクリア
- **44-46行目**: インポートパスの追加・削除・一覧
- **47-52行目**: シンボル情報・ドキュメント・検索・ローカル使用・補完・インレイヒントのリクエスト

#### Step 3: BuiltinDCDClientの実装を理解する

直接ソケット通信の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | client.d | `dcd/source/served/dcd/client.d` | BuiltinDCDClient class（385-629行目）: ソケットベースの直接通信実装 |

**主要処理フロー**:
- **387-388行目**: `minSupportedServerInclusive`/`maxSupportedServerExclusive`でサポートバージョン範囲を定義
- **465-498行目**: `connectForRequest`でTCPまたはUnixドメインソケットに接続、5秒タイムアウト設定
- **501-511行目**: `closeRequestConnection`でソケットのshutdownとclose
- **522-539行目**: `performRequest`でリクエスト送信とレスポンス受信

#### Step 4: ExternalDCDClientの実装を理解する

外部プロセス呼び出しの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | client.d | `dcd/source/served/dcd/client.d` | ExternalDCDClient class（55-383行目）: dcd-clientプロセス経由の通信実装 |

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

```
serve-d LSP機能モジュール
    │
    ├─ IDCDClient (インターフェース)
    │      │
    │      ├─ BuiltinDCDClient (直接ソケット通信)
    │      │      ├─ connectForRequest (TCP/Unixソケット接続)
    │      │      ├─ performRequest (送受信)
    │      │      ├─ performNotification (送信のみ)
    │      │      └─ closeRequestConnection (切断)
    │      │
    │      └─ ExternalDCDClient (外部プロセス呼び出し)
    │             ├─ doClient (dcd-clientプロセス起動)
    │             └─ raw (pipeProcess経由の実行)
    │
    └─ データ型
           ├─ CodeRequest (リクエストパラメータ)
           ├─ Completion (補完結果)
           ├─ SymbolInformation (シンボル位置)
           ├─ LocalUse (ローカル使用箇所)
           └─ InlayHint (インレイヒント)
```

### データフロー図

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

CodeRequest ──────────▶ BuiltinDCDClient ────────────▶ Completion
  (fileName,             (ソケット通信)                  (補完候補)
   sourceCode,
   cursorPosition)     ┌─ connectForRequest
                       ├─ sendRequest
                       ├─ getResponse
                       └─ closeRequestConnection

CodeRequest ──────────▶ ExternalDCDClient ───────────▶ SymbolInformation
                         (dcd-clientプロセス)            (シンボル位置)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| client.d | `dcd/source/served/dcd/client.d` | ソース | DCDクライアントの全実装（インターフェース、BuiltinClient、ExternalClient、データ型） |
| dcd_version.d | `workspace-d/source/workspaced/com/dcd_version.d` | ソース | DCDバージョン互換性管理 |
| dcd.d | `workspace-d/source/workspaced/com/dcd.d` | ソース | DCDコンポーネント（DCDサーバーの起動・管理） |
