# 機能設計書 25-System.Reflection.Metadata

## 概要

本ドキュメントは、.NETランタイムのSystem.Reflection.Metadata名前空間が提供するメタデータ読み取り機能について、その設計仕様と実装の詳細を記述する。この機能は、ECMA-335仕様に基づくCLIメタデータの低レベルアクセスを提供する。

### 本機能の処理概要

System.Reflection.Metadataは、.NETアセンブリのメタデータ（型、メソッド、フィールド、カスタム属性等の定義情報）を直接読み取るための高性能なライブラリである。リフレクションAPIとは異なり、アセンブリをロードせずにメタデータのみを解析できる。

**業務上の目的・背景**：従来のリフレクションAPIは、アセンブリを実行ドメインにロードする必要があり、パフォーマンスやメモリ効率に課題があった。また、ロードされたアセンブリはアンロードが困難であった。System.Reflection.Metadataは、これらの課題を解決し、コンパイラ、静的解析ツール、IDE、デバッガなどがアセンブリメタデータに効率的にアクセスできるようにする。

**機能の利用シーン**：
- コンパイラ（Roslyn等）でのアセンブリ参照解決
- IDEでのコード補完・ナビゲーション
- 静的解析ツール（アナライザー）
- NuGetパッケージの解析
- デバッガ・プロファイラ
- アセンブリ差分ツール
- PDBファイルの解析

**主要な処理内容**：
1. メタデータストリームの読み取り（MetadataReader）
2. 型定義・参照の解析
3. メソッド・フィールド・プロパティの解析
4. カスタム属性のデコード
5. PEヘッダ・セクションの解析（PEReader）
6. Portable PDBの読み取り

**関連システム・外部連携**：System.Reflection.PortableExecutable（PEReader）、System.Reflection.Emit、Roslyn Compilerと統合。

**権限による制御**：特別な権限制御は不要。ファイルアクセス権限のみ必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はUIを持たないライブラリ機能である |

## 機能種別

メタデータ解析 / 低レベルリフレクション / 静的解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| metadata | byte* | Yes | メタデータへのポインタ | nullでないこと |
| length | int | Yes | メタデータの長さ | 正の整数 |
| options | MetadataReaderOptions | No | 読み取りオプション | 有効なフラグ |
| utf8Decoder | MetadataStringDecoder | No | 文字列デコーダ | UTF8エンコーディング |

### 入力データソース

- PEファイル（DLL/EXE）のメタデータセクション
- スタンドアロンPDB（Portable PDB）
- メモリマップされたファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MetadataReader | MetadataReader | メタデータリーダーインスタンス |
| TypeDefinition | TypeDefinition | 型定義情報 |
| MethodDefinition | MethodDefinition | メソッド定義情報 |
| CustomAttribute | CustomAttribute | カスタム属性情報 |
| Handle | Handle | メタデータハンドル |

### 出力先

- 呼び出し元への構造体/クラス返却
- BlobReader経由のバイナリデータ

## 処理フロー

### 処理シーケンス

```
1. PEファイル読み込み
   └─ PEReader.FromFile() または new PEReader(stream)

2. メタデータ取得
   └─ peReader.GetMetadataReader()

3. メタデータ解析
   └─ TypeDefinitions, MethodDefinitions等のコレクションを列挙
   └─ ハンドルから詳細情報を取得

4. シグネチャデコード
   └─ SignatureDecoder<TType, TGenericContext>でシグネチャ解析

5. カスタム属性デコード
   └─ CustomAttribute.DecodeValue<TType>()
```

### フローチャート

```mermaid
flowchart TD
    A[PEファイル/ストリーム] --> B[PEReader]
    B --> C{メタデータ取得}
    C --> D[MetadataReader]
    D --> E{解析対象}
    E -->|型| F[TypeDefinitions]
    E -->|メソッド| G[MethodDefinitions]
    E -->|フィールド| H[FieldDefinitions]
    E -->|属性| I[CustomAttributes]
    F --> J[Handle取得]
    G --> J
    H --> J
    I --> J
    J --> K[詳細情報取得]
    K --> L{シグネチャあり?}
    L -->|Yes| M[SignatureDecoder]
    L -->|No| N[結果返却]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | メモリ所有権 | メタデータメモリは呼び出し側が管理 | 常時 |
| BR-02 | リトルエンディアン | リトルエンディアンプラットフォームのみサポート | 常時 |
| BR-03 | UTF-8デコード | 文字列はUTF-8としてデコード | 常時 |
| BR-04 | ハンドル一意性 | ハンドルはリーダーインスタンス内で一意 | ハンドル使用時 |

### 計算ロジック

メタデータトークン計算:
```
token = (tableId << 24) | rowNumber
```

圧縮整数デコード:
- 1バイト: 0x00-0x7F
- 2バイト: 0x80-0xBF (上位ビットマスク)
- 4バイト: 0xC0-0xDF (上位ビットマスク)

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| BadImageFormatException | 例外 | 無効なメタデータヘッダ | 有効なアセンブリを使用 |
| ArgumentOutOfRangeException | 例外 | 負のlength | 正の値を指定 |
| ArgumentNullException | 例外 | metadataがnull | 有効なポインタを指定 |
| PlatformNotSupportedException | 例外 | ビッグエンディアン環境 | リトルエンディアン環境で実行 |
| ArgumentException | 例外 | 非UTF8デコーダ | UTF8デコーダを使用 |

### リトライ仕様

メタデータ読み取りは同期処理のため、リトライは不要。

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

本機能はトランザクションを使用しない。

## パフォーマンス要件

- メモリマップベースのゼロコピー読み取り
- 構造体によるアロケーション削減
- 遅延評価による不要なメタデータ読み込み回避
- ハンドルベースの軽量参照

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

- 信頼できないアセンブリのメタデータ解析時は注意
- ポインタ操作のため、境界チェックが重要
- BadImageFormatExceptionで不正なデータを検出

## 備考

- ECMA-335 CLI仕様に準拠
- Roslyn、MSBuild、Visual Studioで使用
- .NET Standard 1.1以降で利用可能

---

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

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

### 推奨読解順序

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

メタデータハンドルとBlobリーダーの基本を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Handle.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Handle.cs` | 基本ハンドル構造体 |
| 1-2 | EntityHandle.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/EntityHandle.cs` | エンティティハンドル |
| 1-3 | HandleKind.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/HandleKind.cs` | ハンドル種別列挙 |
| 1-4 | BlobReader.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobReader.cs` | バイナリデータリーダー |

**読解のコツ**: Handleはメタデータトークンのラッパーであり、テーブルIDと行番号を組み合わせて一意の識別子を形成する。

#### Step 2: メタデータリーダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MetadataReader.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs` | 中心的なリーダークラス |
| 2-2 | MetadataReaderOptions.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReaderOptions.cs` | リーダーオプション |
| 2-3 | MetadataReaderProvider.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReaderProvider.cs` | リーダープロバイダー |
| 2-4 | MetadataStringDecoder.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs` | 文字列デコーダ |

**主要処理フロー（MetadataReader.cs）**:
- **17-20行目**: NamespaceCache、MemoryBlockフィールド
- **39-42行目**: 基本コンストラクタ（ポインタ、長さ）
- **75-146行目**: 完全コンストラクタ（ヘッダ解析、ストリーム初期化）
- **102-103行目**: BlobReaderでヘッダ読み取り
- **108行目**: ストリームヘッダ初期化
- **121-125行目**: テーブルリーダー初期化
- **140行目**: NamespaceCache初期化

#### Step 3: BlobReaderを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BlobReader.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobReader.cs` | バイナリ読み取り詳細 |
| 3-2 | BlobBuilder.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs` | バイナリ書き込み |
| 3-3 | BlobWriter.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobWriter.cs` | Blobライター |

**主要処理フロー（BlobReader.cs）**:
- **13-22行目**: 構造体定義、MemoryBlock、ポインタフィールド
- **32-36行目**: コンストラクタ（バッファ、長さ）
- **76-86行目**: StartPointer、CurrentPointer、Lengthプロパティ
- **92-100行目**: Offsetプロパティ（get/set）

#### Step 4: ECMA-335テーブル構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MetadataTokens.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataTokens.cs` | トークン操作 |
| 4-2 | MetadataBuilder.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataBuilder.cs` | メタデータビルダー |

#### Step 5: PEリーダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | PEReaderExtensions.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/PEReaderExtensions.cs` | PE拡張メソッド |

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

```
PEReader(stream)
    │
    └─ GetMetadataReader()
           │
           └─ new MetadataReader(byte* metadata, int length, options, decoder)
                  │
                  ├─ new BlobReader(metadata, length)
                  │      └─ ReadMetadataHeader()
                  │
                  ├─ ReadStreamHeaders()
                  │      └─ InitializeStreamReaders()
                  │
                  ├─ ReadMetadataTableHeader()
                  │      └─ InitializeTableReaders()
                  │
                  └─ new NamespaceCache(this)

MetadataReader.TypeDefinitions
    │
    └─ TypeDefinitionHandleCollection.GetEnumerator()
           │
           └─ foreach TypeDefinitionHandle
                  │
                  └─ MetadataReader.GetTypeDefinition(handle)
                         │
                         └─ TypeDefinition構造体
                                ├─ Name
                                ├─ Namespace
                                ├─ BaseType
                                └─ GetMethods()
```

### データフロー図

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

PEファイル        PEReader / MetadataReader    構造化データ
   │                   │                         │
   ├─ Stream ────────▶│                         │
   │                   │                         │
   │              ┌────┴────┐                    │
   │              │ヘッダ解析│                    │
   │              │ストリーム│                    │
   │              │  初期化  │                    │
   │              └────┬────┘                    │
   │                   │                         │
   │              ┌────┴────┐                    │
   │              │テーブル  │                    │
   │              │リーダー  │                    │
   │              │  初期化  │                    │
   │              └────┬────┘                    │
   │                   │                         │
Handle要求             │                         │
   ├─ TypeDef ───────▶│─────────────────────────▶│TypeDefinition
   ├─ MethodDef ─────▶│─────────────────────────▶│MethodDefinition
   ├─ CustomAttr ────▶│─────────────────────────▶│CustomAttribute
   │                   │                         │
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MetadataReader.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.cs` | ソース | 中心的リーダー |
| MetadataReaderOptions.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReaderOptions.cs` | ソース | リーダーオプション |
| MetadataReaderProvider.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReaderProvider.cs` | ソース | リーダープロバイダー |
| Handle.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Handle.cs` | ソース | 基本ハンドル |
| EntityHandle.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/EntityHandle.cs` | ソース | エンティティハンドル |
| HandleKind.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/HandleKind.cs` | ソース | ハンドル種別 |
| BlobReader.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobReader.cs` | ソース | Blobリーダー |
| BlobBuilder.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs` | ソース | Blobビルダー |
| BlobWriter.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobWriter.cs` | ソース | Blobライター |
| MetadataStringDecoder.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs` | ソース | 文字列デコーダ |
| MetadataKind.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataKind.cs` | ソース | メタデータ種別 |
| TypeName.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs` | ソース | 型名パーサー |
| AssemblyNameInfo.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs` | ソース | アセンブリ名情報 |
| PEReaderExtensions.cs | `src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/PEReaderExtensions.cs` | ソース | PE拡張メソッド |
