< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 1697
Coverable lines: 1697
Total lines: 3170
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 513
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
File 1: GetSerializedMetadata(...)100%110%
File 1: SerializeMetadataHeader(...)0%10100%
File 1: SerializeStreamHeader(...)100%110%
File 2: .ctor(...)100%110%
File 2: AllocateChunk(...)100%110%
File 2: SetCapacity(...)100%110%
File 2: .ctor(...)0%12120%
File 2: SetCapacity(...)0%770%
File 2: SerializeHandle(...)100%110%
File 2: SerializeHandle(...)100%110%
File 2: SerializeHandle(...)100%110%
File 2: SerializeHandle(...)100%110%
File 2: GetOrAddBlob(...)0%440%
File 2: GetOrAddBlob(...)0%220%
File 2: GetOrAddBlob(...)0%220%
File 2: GetOrAddBlob(...)0%220%
File 2: GetOrAddConstantBlob(...)0%220%
File 2: GetOrAddBlobUTF16(...)0%440%
File 2: GetOrAddBlobUTF8(...)100%110%
File 2: GetOrAddDocumentName(...)0%880%
File 2: ChooseSeparator(...)0%880%
File 2: GetOrAddGuid(...)0%440%
File 2: ReserveGuid()100%110%
File 2: GetNewGuidHandle()100%110%
File 2: GetOrAddString(...)0%660%
File 2: ReserveUserString(...)0%220%
File 2: GetOrAddUserString(...)0%440%
File 2: GetNewUserStringHandle()0%220%
File 2: SerializeStringHeap(...)0%660%
File 2: .cctor()100%110%
File 2: Compare(...)0%660%
File 2: WriteHeapsTo(...)100%110%
File 2: WriteAlignedBlobHeap(...)0%440%
File 2: WriteAligned(...)100%110%
File 3: .ctor(...)100%110%
File 3: SetCapacity(...)0%59590%
File 3: SetTableCapacity(...)0%220%
File 3: GetRowCount(...)0%61610%
File 3: GetRowCounts()0%440%
File 3: AddModule(...)0%440%
File 3: AddAssembly(...)0%440%
File 3: AddAssemblyReference(...)0%220%
File 3: AddTypeDefinition(...)0%220%
File 3: AddTypeLayout(...)100%110%
File 3: AddInterfaceImplementation(...)100%110%
File 3: AddNestedType(...)100%110%
File 3: AddTypeReference(...)0%220%
File 3: AddTypeSpecification(...)100%110%
File 3: AddStandaloneSignature(...)100%110%
File 3: AddProperty(...)100%110%
File 3: AddPropertyMap(...)100%110%
File 3: AddEvent(...)100%110%
File 3: AddEventMap(...)100%110%
File 3: AddConstant(...)100%110%
File 3: AddMethodSemantics(...)100%110%
File 3: AddCustomAttribute(...)100%110%
File 3: AddMethodSpecification(...)100%110%
File 3: AddModuleReference(...)100%110%
File 3: AddParameter(...)0%220%
File 3: AddGenericParameter(...)0%220%
File 3: AddGenericParameterConstraint(...)100%110%
File 3: AddFieldDefinition(...)100%110%
File 3: AddFieldLayout(...)100%110%
File 3: AddMarshallingDescriptor(...)100%110%
File 3: AddFieldRelativeVirtualAddress(...)0%220%
File 3: AddMethodDefinition(...)0%220%
File 3: AddMethodImport(...)100%110%
File 3: AddMethodImplementation(...)100%110%
File 3: AddMemberReference(...)100%110%
File 3: AddManifestResource(...)0%220%
File 3: AddAssemblyFile(...)0%220%
File 3: AddExportedType(...)100%110%
File 3: AddDeclarativeSecurityAttribute(...)100%110%
File 3: AddEncLogEntry(...)100%110%
File 3: AddEncMapEntry(...)100%110%
File 3: AddDocument(...)100%110%
File 3: AddMethodDebugInformation(...)100%110%
File 3: AddLocalScope(...)100%110%
File 3: AddLocalVariable(...)0%220%
File 3: AddLocalConstant(...)100%110%
File 3: AddImportScope(...)100%110%
File 3: AddStateMachineMethod(...)100%110%
File 3: AddCustomDebugInformation(...)100%110%
File 3: ValidateOrder()100%110%
File 3: ValidateClassLayoutTable()0%440%
File 3: ValidateFieldLayoutTable()0%440%
File 3: ValidateFieldRvaTable()0%440%
File 3: ValidateGenericParamTable()0%10100%
File 3: ValidateGenericParamConstaintTable()0%440%
File 3: ValidateImplMapTable()0%440%
File 3: ValidateInterfaceImplTable()0%440%
File 3: ValidateMethodImplTable()0%440%
File 3: ValidateNestedClassTable()0%440%
File 3: ValidateLocalScopeTable()0%14140%
File 3: ValidateStateMachineMethodTable()0%440%
File 3: SerializeMetadataTables(...)0%88880%
File 3: SerializeTablesHeader(...)0%12120%
File 3: SerializeModuleTable(...)0%220%
File 3: SerializeEncLogTable(...)0%220%
File 3: SerializeEncMapTable(...)0%220%
File 3: SerializeTypeRefTable(...)0%220%
File 3: SerializeTypeDefTable(...)0%220%
File 3: SerializeFieldTable(...)0%220%
File 3: SerializeMethodDefTable(...)0%440%
File 3: SerializeParamTable(...)0%220%
File 3: SerializeInterfaceImplTable(...)0%220%
File 3: SerializeMemberRefTable(...)0%220%
File 3: SerializeConstantTable(...)0%440%
File 3: SerializeCustomAttributeTable(...)0%660%
File 3: SerializeFieldMarshalTable(...)0%440%
File 3: SerializeDeclSecurityTable(...)0%440%
File 3: SerializeClassLayoutTable(...)0%220%
File 3: SerializeFieldLayoutTable(...)0%220%
File 3: SerializeStandAloneSigTable(...)0%220%
File 3: SerializeEventMapTable(...)0%220%
File 3: SerializeEventTable(...)0%220%
File 3: SerializePropertyMapTable(...)0%220%
File 3: SerializePropertyTable(...)0%220%
File 3: SerializeMethodSemanticsTable(...)0%440%
File 3: SerializeMethodImplTable(...)0%220%
File 3: SerializeModuleRefTable(...)0%220%
File 3: SerializeTypeSpecTable(...)0%220%
File 3: SerializeImplMapTable(...)0%220%
File 3: SerializeFieldRvaTable(...)0%220%
File 3: SerializeAssemblyTable(...)0%220%
File 3: SerializeAssemblyRefTable(...)0%220%
File 3: SerializeFileTable(...)0%220%
File 3: SerializeExportedTypeTable(...)0%220%
File 3: SerializeManifestResourceTable(...)0%220%
File 3: SerializeNestedClassTable(...)0%220%
File 3: SerializeGenericParamTable(...)0%220%
File 3: SerializeGenericParamConstraintTable(...)0%220%
File 3: SerializeMethodSpecTable(...)0%220%
File 3: SerializeDocumentTable(...)0%220%
File 3: SerializeMethodDebugInformationTable(...)0%220%
File 3: SerializeLocalScopeTable(...)0%220%
File 3: SerializeLocalVariableTable(...)0%220%
File 3: SerializeLocalConstantTable(...)0%220%
File 3: SerializeImportScopeTable(...)0%220%
File 3: SerializeStateMachineMethodTable(...)0%220%
File 3: SerializeCustomDebugInformationTable(...)0%440%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataBuilder.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using System.Diagnostics;
 6using System.Reflection.Internal;
 7
 8namespace System.Reflection.Metadata.Ecma335
 9{
 10    public sealed partial class MetadataBuilder
 11    {
 12        internal SerializedMetadata GetSerializedMetadata(ImmutableArray<int> externalRowCounts, int metadataVersionByte
 013        {
 014            var stringHeapBuilder = new HeapBlobBuilder(_stringHeapCapacity);
 015            var stringMap = SerializeStringHeap(stringHeapBuilder, _strings, _stringHeapStartOffset);
 16
 017            Debug.Assert(HeapIndex.UserString == 0);
 018            Debug.Assert((int)HeapIndex.String == 1);
 019            Debug.Assert((int)HeapIndex.Blob == 2);
 020            Debug.Assert((int)HeapIndex.Guid == 3);
 21
 022            var heapSizes = ImmutableArray.Create(
 023                _userStringBuilder.Count,
 024                stringHeapBuilder.Count,
 025                _blobHeapSize,
 026                _guidBuilder.Count);
 27
 028            var sizes = new MetadataSizes(GetRowCounts(), externalRowCounts, heapSizes, metadataVersionByteCount, isStan
 29
 030            return new SerializedMetadata(sizes, stringHeapBuilder, stringMap);
 031        }
 32
 33        internal static void SerializeMetadataHeader(BlobBuilder builder, string metadataVersion, MetadataSizes sizes)
 034        {
 035            int startOffset = builder.Count;
 36
 37            // signature
 038            builder.WriteUInt32(0x424A5342);
 39
 40            // major version
 041            builder.WriteUInt16(1);
 42
 43            // minor version
 044            builder.WriteUInt16(1);
 45
 46            // reserved
 047            builder.WriteUInt32(0);
 48
 49            // Spec (section 24.2.1 Metadata Root):
 50            // Length ... Number of bytes allocated to hold version string (including null terminator), call this x.
 51            //            Call the length of the string (including the terminator) m (we require m <= 255);
 52            //            the length x is m rounded up to a multiple of four.
 053            builder.WriteInt32(sizes.MetadataVersionPaddedLength);
 54
 055            int metadataVersionStart = builder.Count;
 056            builder.WriteUTF8(metadataVersion);
 057            builder.WriteByte(0);
 058            int metadataVersionEnd = builder.Count;
 59
 060            builder.WriteBytes(0, sizes.MetadataVersionPaddedLength - (metadataVersionEnd - metadataVersionStart));
 61
 62            // reserved
 063            builder.WriteUInt16(0);
 64
 65            // number of streams
 066            builder.WriteUInt16((ushort)(5 + (sizes.IsEncDelta ? 1 : 0) + (sizes.IsStandaloneDebugMetadata ? 1 : 0)));
 67
 68            // stream headers
 069            int offsetFromStartOfMetadata = sizes.MetadataHeaderSize;
 70
 71            // emit the #Pdb stream first so that only a single page has to be read in order to find out PDB ID
 072            if (sizes.IsStandaloneDebugMetadata)
 073            {
 074                SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.StandalonePdbStreamSize, "#Pdb"u8, builder);
 075            }
 76
 77            // Spec: Some compilers store metadata in a #- stream, which holds an uncompressed, or non-optimized, repres
 78            // this includes extra metadata -Ptr tables. Such PE files do not form part of ECMA-335 standard.
 79            //
 80            // Note: EnC delta is stored as uncompressed metadata stream.
 081            SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.MetadataTableStreamSize, (sizes.IsCompressed ? "#
 82
 083            SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.GetAlignedHeapSize(HeapIndex.String), "#Strings"u
 084            SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.GetAlignedHeapSize(HeapIndex.UserString), "#US"u8
 085            SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.GetAlignedHeapSize(HeapIndex.Guid), "#GUID"u8, bu
 086            SerializeStreamHeader(ref offsetFromStartOfMetadata, sizes.GetAlignedHeapSize(HeapIndex.Blob), "#Blob"u8, bu
 87
 088            if (sizes.IsEncDelta)
 089            {
 090                SerializeStreamHeader(ref offsetFromStartOfMetadata, 0, "#JTD"u8, builder);
 091            }
 92
 093            int endOffset = builder.Count;
 094            Debug.Assert(endOffset - startOffset == sizes.MetadataHeaderSize);
 095        }
 96
 97        private static void SerializeStreamHeader(ref int offsetFromStartOfMetadata, int alignedStreamSize, ReadOnlySpan
 098        {
 99            // 4 for the first uint (offset), 4 for the second uint (padded size), length of stream name + 1 for null te
 0100            int sizeOfStreamHeader = MetadataSizes.GetMetadataStreamHeaderSize(streamName);
 0101            builder.WriteInt32(offsetFromStartOfMetadata);
 0102            builder.WriteInt32(alignedStreamSize);
 0103            builder.WriteBytes(streamName);
 104
 105            // After offset, size, and stream name, write 0-bytes until we reach our padded size.
 0106            builder.WriteBytes(0, sizeOfStreamHeader - (8 + streamName.Length));
 107
 0108            offsetFromStartOfMetadata += alignedStreamSize;
 0109        }
 110    }
 111}
 112

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataBuilder.Heaps.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Generic;
 5using System.Collections.Immutable;
 6using System.Reflection.Internal;
 7using System.Runtime.InteropServices;
 8using System.Text;
 9
 10namespace System.Reflection.Metadata.Ecma335
 11{
 12    public sealed partial class MetadataBuilder
 13    {
 14        private sealed class HeapBlobBuilder : BlobBuilder
 15        {
 16            private int _capacityExpansion;
 17
 18            public HeapBlobBuilder(int capacity)
 019                : base(capacity)
 020            {
 021            }
 22
 23            protected override BlobBuilder AllocateChunk(int minimalSize)
 024            {
 025                return new HeapBlobBuilder(Math.Max(Math.Max(minimalSize, ChunkCapacity), _capacityExpansion));
 026            }
 27
 28            internal void SetCapacity(int capacity)
 029            {
 030                _capacityExpansion = Math.Max(0, capacity - Count - FreeBytes);
 031            }
 32        }
 33
 34        // #US heap
 35        private const int UserStringHeapSizeLimit = 0x01000000;
 036        private readonly Dictionary<string, UserStringHandle> _userStrings = new Dictionary<string, UserStringHandle>(25
 037        private readonly HeapBlobBuilder _userStringBuilder = new HeapBlobBuilder(4 * 1024);
 38        private readonly int _userStringHeapStartOffset;
 39
 40        // #String heap
 041        private readonly Dictionary<string, StringHandle> _strings = new Dictionary<string, StringHandle>(256);
 42        private readonly int _stringHeapStartOffset;
 043        private int _stringHeapCapacity = 4 * 1024;
 44
 45        // #Blob heap
 046        private readonly BlobDictionary _blobs = new BlobDictionary(1024);
 47        private readonly int _blobHeapStartOffset;
 48        private int _blobHeapSize;
 49
 50        // #GUID heap
 051        private readonly Dictionary<Guid, GuidHandle> _guids = new Dictionary<Guid, GuidHandle>();
 052        private readonly HeapBlobBuilder _guidBuilder = new HeapBlobBuilder(16); // full metadata has just a single guid
 53
 54        /// <summary>
 55        /// Creates a builder for metadata tables and heaps.
 56        /// </summary>
 57        /// <param name="userStringHeapStartOffset">
 58        /// Start offset of the User String heap.
 59        /// The cumulative size of User String heaps of all previous EnC generations. Should be 0 unless the metadata is
 60        /// </param>
 61        /// <param name="stringHeapStartOffset">
 62        /// Start offset of the String heap.
 63        /// The cumulative size of String heaps of all previous EnC generations. Should be 0 unless the metadata is EnC 
 64        /// </param>
 65        /// <param name="blobHeapStartOffset">
 66        /// Start offset of the Blob heap.
 67        /// The cumulative size of Blob heaps of all previous EnC generations. Should be 0 unless the metadata is EnC de
 68        /// </param>
 69        /// <param name="guidHeapStartOffset">
 70        /// Start offset of the Guid heap.
 71        /// The cumulative size of Guid heaps of all previous EnC generations. Should be 0 unless the metadata is EnC de
 72        /// </param>
 73        /// <exception cref="ImageFormatLimitationException">Offset is too big.</exception>
 74        /// <exception cref="ArgumentOutOfRangeException">Offset is negative.</exception>
 75        /// <exception cref="ArgumentException"><paramref name="guidHeapStartOffset"/> is not a multiple of size of GUID
 076        public MetadataBuilder(
 077            int userStringHeapStartOffset = 0,
 078            int stringHeapStartOffset = 0,
 079            int blobHeapStartOffset = 0,
 080            int guidHeapStartOffset = 0)
 081        {
 82            // -1 for the 0 we always write at the beginning of the heap:
 083            if (userStringHeapStartOffset >= UserStringHeapSizeLimit - 1)
 084            {
 085                Throw.HeapSizeLimitExceeded(HeapIndex.UserString);
 86            }
 87
 088            if (userStringHeapStartOffset < 0)
 089            {
 090                Throw.ArgumentOutOfRange(nameof(userStringHeapStartOffset));
 91            }
 92
 093            if (stringHeapStartOffset < 0)
 094            {
 095                Throw.ArgumentOutOfRange(nameof(stringHeapStartOffset));
 96            }
 97
 098            if (blobHeapStartOffset < 0)
 099            {
 0100                Throw.ArgumentOutOfRange(nameof(blobHeapStartOffset));
 101            }
 102
 0103            if (guidHeapStartOffset < 0)
 0104            {
 0105                Throw.ArgumentOutOfRange(nameof(guidHeapStartOffset));
 106            }
 107
 0108            if (guidHeapStartOffset % BlobUtilities.SizeOfGuid != 0)
 0109            {
 0110                throw new ArgumentException(SR.Format(SR.ValueMustBeMultiple, BlobUtilities.SizeOfGuid), nameof(guidHeap
 111            }
 112
 113            // Add zero-th entry to all heaps, even in EnC delta.
 114            // We don't want generation-relative handles to ever be IsNil.
 115            // In both full and delta metadata all nil heap handles should have zero value.
 116            // There should be no blob handle that references the 0 byte added at the
 117            // beginning of the delta blob.
 0118            _userStringBuilder.WriteByte(0);
 119
 0120            _blobs.GetOrAdd(ReadOnlySpan<byte>.Empty, ImmutableArray<byte>.Empty, default, out _);
 0121            _blobHeapSize = 1;
 122
 123            // When EnC delta is applied #US, #String and #Blob heaps are appended.
 124            // Thus indices of strings and blobs added to this generation are offset
 125            // by the sum of respective heap sizes of all previous generations.
 0126            _userStringHeapStartOffset = userStringHeapStartOffset;
 0127            _stringHeapStartOffset = stringHeapStartOffset;
 0128            _blobHeapStartOffset = blobHeapStartOffset;
 129
 130            // Unlike other heaps, #Guid heap in EnC delta is zero-padded.
 0131            _guidBuilder.WriteBytes(0, guidHeapStartOffset);
 0132        }
 133
 134        /// <summary>
 135        /// Sets the capacity of the specified table.
 136        /// </summary>
 137        /// <param name="heap">Heap index.</param>
 138        /// <param name="byteCount">Number of bytes.</param>
 139        /// <exception cref="ArgumentOutOfRangeException"><paramref name="heap"/> is not a valid heap index.</exception>
 140        /// <exception cref="ArgumentOutOfRangeException"><paramref name="byteCount"/> is negative.</exception>
 141        /// <remarks>
 142        /// Use to reduce allocations if the approximate number of bytes is known ahead of time.
 143        /// </remarks>
 144        public void SetCapacity(HeapIndex heap, int byteCount)
 0145        {
 0146            if (byteCount < 0)
 0147            {
 0148                Throw.ArgumentOutOfRange(nameof(byteCount));
 149            }
 150
 0151            switch (heap)
 152            {
 153                case HeapIndex.Blob:
 154                    // Not useful to set capacity.
 155                    // By the time the blob heap is serialized we know the exact size we need.
 0156                    break;
 157
 158                case HeapIndex.Guid:
 0159                    _guidBuilder.SetCapacity(byteCount);
 0160                    break;
 161
 162                case HeapIndex.String:
 0163                    _stringHeapCapacity = byteCount;
 0164                    break;
 165
 166                case HeapIndex.UserString:
 0167                    _userStringBuilder.SetCapacity(byteCount);
 0168                    break;
 169
 170                default:
 0171                    Throw.ArgumentOutOfRange(nameof(heap));
 172                    break;
 173            }
 0174        }
 175
 176        // internal for testing
 0177        internal static int SerializeHandle(ImmutableArray<int> map, StringHandle handle) => map[handle.GetWriterVirtual
 0178        internal static int SerializeHandle(BlobHandle handle) => handle.GetHeapOffset();
 0179        internal static int SerializeHandle(GuidHandle handle) => handle.Index;
 0180        internal static int SerializeHandle(UserStringHandle handle) => handle.GetHeapOffset();
 181
 182        /// <summary>
 183        /// Adds specified blob to Blob heap, if it's not there already.
 184        /// </summary>
 185        /// <param name="value"><see cref="BlobBuilder"/> containing the blob.</param>
 186        /// <returns>Handle to the added or existing blob.</returns>
 187        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 188        public BlobHandle GetOrAddBlob(BlobBuilder value)
 0189        {
 0190            if (value is null)
 0191            {
 0192                Throw.ArgumentNull(nameof(value));
 193            }
 194
 0195            if (value.TryGetSpan(out ReadOnlySpan<byte> buffer))
 0196            {
 0197                return GetOrAddBlob(buffer);
 198            }
 199
 0200            return GetOrAddBlob(value.ToImmutableArray());
 0201        }
 202
 203        /// <summary>
 204        /// Adds specified blob to Blob heap, if it's not there already.
 205        /// </summary>
 206        /// <param name="value">Array containing the blob.</param>
 207        /// <returns>Handle to the added or existing blob.</returns>
 208        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 209        public BlobHandle GetOrAddBlob(byte[] value)
 0210        {
 0211            if (value is null)
 0212            {
 0213                Throw.ArgumentNull(nameof(value));
 214            }
 215
 0216            return GetOrAddBlob(new ReadOnlySpan<byte>(value));
 0217        }
 218
 219        private BlobHandle GetOrAddBlob(ReadOnlySpan<byte> value, ImmutableArray<byte> immutableValue = default)
 0220        {
 0221            BlobHandle nextHandle = BlobHandle.FromOffset(_blobHeapStartOffset + _blobHeapSize);
 0222            BlobHandle handle = _blobs.GetOrAdd(value, immutableValue, nextHandle, out bool exists);
 0223            if (!exists)
 0224            {
 0225                _blobHeapSize += BlobWriterImpl.GetCompressedIntegerSize(value.Length) + value.Length;
 0226            }
 227
 0228            return handle;
 0229        }
 230
 231        /// <summary>
 232        /// Adds specified blob to Blob heap, if it's not there already.
 233        /// </summary>
 234        /// <param name="value">Array containing the blob.</param>
 235        /// <returns>Handle to the added or existing blob.</returns>
 236        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 237        public BlobHandle GetOrAddBlob(ImmutableArray<byte> value)
 0238        {
 0239            if (value.IsDefault)
 0240            {
 0241                Throw.ArgumentNull(nameof(value));
 242            }
 243
 0244            return GetOrAddBlob(value.AsSpan(), value);
 0245        }
 246
 247        /// <summary>
 248        /// Encodes a constant value to a blob and adds it to the Blob heap, if it's not there already.
 249        /// Uses UTF-16 to encode string constants.
 250        /// </summary>
 251        /// <param name="value">Constant value.</param>
 252        /// <returns>Handle to the added or existing blob.</returns>
 253        public unsafe BlobHandle GetOrAddConstantBlob(object? value)
 0254        {
 0255            if (value is string str)
 0256            {
 0257                return GetOrAddBlobUTF16(str);
 258            }
 259
 0260            Span<byte> buffer = stackalloc byte[BlobWriterImpl.MaxScalarConstantSize];
 0261            int length = BlobWriterImpl.WriteScalarConstant(buffer, value);
 0262            return GetOrAddBlob(buffer.Slice(0, length));
 0263        }
 264
 265        /// <summary>
 266        /// Encodes a string using UTF-16 encoding to a blob and adds it to the Blob heap, if it's not there already.
 267        /// </summary>
 268        /// <param name="value">String.</param>
 269        /// <returns>Handle to the added or existing blob.</returns>
 270        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 271        public BlobHandle GetOrAddBlobUTF16(string value)
 0272        {
 0273            if (value is null)
 0274            {
 0275                Throw.ArgumentNull(nameof(value));
 276            }
 277
 0278            if (BitConverter.IsLittleEndian)
 0279            {
 0280                return GetOrAddBlob(MemoryMarshal.AsBytes(value.AsSpan()));
 281            }
 282
 0283            var builder = PooledBlobBuilder.GetInstance();
 0284            builder.WriteUTF16(value);
 0285            var handle = GetOrAddBlob(builder);
 0286            builder.Free();
 0287            return handle;
 0288        }
 289
 290        /// <summary>
 291        /// Encodes a string using UTF-8 encoding to a blob and adds it to the Blob heap, if it's not there already.
 292        /// </summary>
 293        /// <param name="value">Constant value.</param>
 294        /// <param name="allowUnpairedSurrogates">
 295        /// True to encode unpaired surrogates as specified, otherwise replace them with U+FFFD character.
 296        /// </param>
 297        /// <returns>Handle to the added or existing blob.</returns>
 298        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 299        public BlobHandle GetOrAddBlobUTF8(string value, bool allowUnpairedSurrogates = true)
 0300        {
 0301            var builder = PooledBlobBuilder.GetInstance();
 0302            builder.WriteUTF8(value, allowUnpairedSurrogates);
 0303            var handle = GetOrAddBlob(builder);
 0304            builder.Free();
 0305            return handle;
 0306        }
 307
 308        /// <summary>
 309        /// Encodes a debug document name and adds it to the Blob heap, if it's not there already.
 310        /// </summary>
 311        /// <param name="value">Document name.</param>
 312        /// <returns>
 313        /// Handle to the added or existing document name blob
 314        /// (see https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md#DocumentNameBlob)
 315        /// </returns>
 316        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 317        public BlobHandle GetOrAddDocumentName(string value)
 0318        {
 0319            if (value is null)
 0320            {
 0321                Throw.ArgumentNull(nameof(value));
 322            }
 323
 0324            char separator = ChooseSeparator(value);
 325
 0326            var resultBuilder = PooledBlobBuilder.GetInstance();
 0327            resultBuilder.WriteByte((byte)separator);
 328
 0329            var partBuilder = PooledBlobBuilder.GetInstance();
 330
 0331            int i = 0;
 0332            while (true)
 0333            {
 0334                int next = value.IndexOf(separator, i);
 335
 0336                partBuilder.WriteUTF8(value, i, (next >= 0 ? next : value.Length) - i, allowUnpairedSurrogates: true, pr
 0337                resultBuilder.WriteCompressedInteger(GetOrAddBlob(partBuilder).GetHeapOffset());
 338
 0339                if (next == -1)
 0340                {
 0341                    break;
 342                }
 343
 0344                if (next == value.Length - 1)
 0345                {
 346                    // trailing separator:
 0347                    resultBuilder.WriteByte(0);
 0348                    break;
 349                }
 350
 0351                partBuilder.Clear();
 0352                i = next + 1;
 0353            }
 354
 0355            partBuilder.Free();
 356
 0357            var resultHandle = GetOrAddBlob(resultBuilder);
 0358            resultBuilder.Free();
 0359            return resultHandle;
 0360        }
 361
 362        private static char ChooseSeparator(string str)
 0363        {
 364            const char s1 = '/';
 365            const char s2 = '\\';
 366
 0367            int count1 = 0, count2 = 0;
 0368            foreach (var c in str)
 0369            {
 0370                if (c == s1)
 0371                {
 0372                    count1++;
 0373                }
 0374                else if (c == s2)
 0375                {
 0376                    count2++;
 0377                }
 0378            }
 379
 0380            return (count1 >= count2) ? s1 : s2;
 0381        }
 382
 383        /// <summary>
 384        /// Adds specified Guid to Guid heap, if it's not there already.
 385        /// </summary>
 386        /// <param name="guid">Guid to add.</param>
 387        /// <returns>Handle to the added or existing Guid.</returns>
 388        public GuidHandle GetOrAddGuid(Guid guid)
 0389        {
 0390            if (guid == Guid.Empty)
 0391            {
 0392                return default(GuidHandle);
 393            }
 394
 395            GuidHandle result;
 0396            if (_guids.TryGetValue(guid, out result))
 0397            {
 0398                return result;
 399            }
 400
 0401            result = GetNewGuidHandle();
 0402            _guids.Add(guid, result);
 0403            _guidBuilder.WriteGuid(guid);
 0404            return result;
 0405        }
 406
 407        /// <summary>
 408        /// Reserves space on the Guid heap for a GUID.
 409        /// </summary>
 410        /// <returns>
 411        /// Handle to the reserved Guid and a <see cref="Blob"/> representing the GUID blob as stored on the heap.
 412        /// </returns>
 413        /// <exception cref="ImageFormatLimitationException">The remaining space on the heap is too small to fit the str
 414        public ReservedBlob<GuidHandle> ReserveGuid()
 0415        {
 0416            var handle = GetNewGuidHandle();
 0417            var content = _guidBuilder.ReserveBytes(BlobUtilities.SizeOfGuid);
 0418            return new ReservedBlob<GuidHandle>(handle, content);
 0419        }
 420
 421        private GuidHandle GetNewGuidHandle()
 0422        {
 423            // Unlike #Blob, #String and #US streams delta #GUID stream is padded to the
 424            // size of the previous generation #GUID stream before new GUIDs are added.
 425            // The first GUID added in a delta will thus have an index that equals the number
 426            // of GUIDs in all previous generations + 1.
 427
 428            // Metadata Spec:
 429            // The Guid heap is an array of GUIDs, each 16 bytes wide.
 430            // Its first element is numbered 1, its second 2, and so on.
 0431            return GuidHandle.FromIndex((_guidBuilder.Count >> 4) + 1);
 0432        }
 433
 434        /// <summary>
 435        /// Adds specified string to String heap, if it's not there already.
 436        /// </summary>
 437        /// <param name="value">Array containing the blob.</param>
 438        /// <returns>Handle to the added or existing blob.</returns>
 439        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 440        public StringHandle GetOrAddString(string value)
 0441        {
 0442            if (value is null)
 0443            {
 0444                Throw.ArgumentNull(nameof(value));
 445            }
 446
 447            StringHandle handle;
 0448            if (value.Length == 0)
 0449            {
 0450                handle = default(StringHandle);
 0451            }
 0452            else if (!_strings.TryGetValue(value, out handle))
 0453            {
 0454                handle = StringHandle.FromWriterVirtualIndex(_strings.Count + 1); // idx 0 is reserved for empty string
 0455                _strings.Add(value, handle);
 0456            }
 457
 0458            return handle;
 0459        }
 460
 461        /// <summary>
 462        /// Reserves space on the User String heap for a string of specified length.
 463        /// </summary>
 464        /// <param name="length">The number of characters to reserve.</param>
 465        /// <returns>
 466        /// Handle to the reserved User String and a <see cref="Blob"/> representing the entire User String blob (includ
 467        ///
 468        /// Handle may be used in <see cref="InstructionEncoder.LoadString(UserStringHandle)"/>.
 469        /// Use <see cref="BlobWriter.WriteUserString(string)"/> to fill in the blob content.
 470        /// </returns>
 471        /// <exception cref="ImageFormatLimitationException">The remaining space on the heap is too small to fit the str
 472        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative.</exception>
 473        public ReservedBlob<UserStringHandle> ReserveUserString(int length)
 0474        {
 0475            if (length < 0)
 0476            {
 0477                Throw.ArgumentOutOfRange(nameof(length));
 478            }
 479
 0480            var handle = GetNewUserStringHandle();
 0481            int encodedLength = BlobUtilities.GetUserStringByteLength(length);
 0482            var reservedUserString = _userStringBuilder.ReserveBytes(BlobWriterImpl.GetCompressedIntegerSize(encodedLeng
 0483            return new ReservedBlob<UserStringHandle>(handle, reservedUserString);
 0484        }
 485
 486        /// <summary>
 487        /// Adds specified string to User String heap, if it's not there already.
 488        /// </summary>
 489        /// <param name="value">String to add.</param>
 490        /// <returns>
 491        /// Handle to the added or existing string.
 492        /// May be used in <see cref="InstructionEncoder.LoadString(UserStringHandle)"/>.
 493        /// </returns>
 494        /// <exception cref="ImageFormatLimitationException">The remaining space on the heap is too small to fit the str
 495        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
 496        public UserStringHandle GetOrAddUserString(string value)
 0497        {
 0498            if (value is null)
 0499            {
 0500                Throw.ArgumentNull(nameof(value));
 501            }
 502
 503            UserStringHandle handle;
 0504            if (!_userStrings.TryGetValue(value, out handle))
 0505            {
 0506                handle = GetNewUserStringHandle();
 507
 0508                _userStrings.Add(value, handle);
 0509                _userStringBuilder.WriteUserString(value);
 0510            }
 511
 0512            return handle;
 0513        }
 514
 515        private UserStringHandle GetNewUserStringHandle()
 0516        {
 0517            int offset = _userStringHeapStartOffset + _userStringBuilder.Count;
 518
 519            // Native metadata emitter allows strings to exceed the heap size limit as long
 520            // as the index is within the limits (see https://github.com/dotnet/roslyn/issues/9852)
 0521            if (offset >= UserStringHeapSizeLimit)
 0522            {
 0523                Throw.HeapSizeLimitExceeded(HeapIndex.UserString);
 524            }
 525
 0526            return UserStringHandle.FromOffset(offset);
 0527        }
 528
 529        /// <summary>
 530        /// Fills in stringIndexMap with data from stringIndex and write to stringWriter.
 531        /// Releases stringIndex as the stringTable is sealed after this point.
 532        /// </summary>
 533        private static ImmutableArray<int> SerializeStringHeap(
 534            BlobBuilder heapBuilder,
 535            Dictionary<string, StringHandle> strings,
 536            int stringHeapStartOffset)
 0537        {
 538            // Sort by suffix and remove stringIndex
 0539            var sorted = new List<KeyValuePair<string, StringHandle>>(strings);
 0540            sorted.Sort(SuffixSort.Instance);
 541
 542            // Create VirtIdx to Idx map and add entry for empty string
 0543            int totalCount = sorted.Count + 1;
 0544            var stringVirtualIndexToHeapOffsetMap = ImmutableArray.CreateBuilder<int>(totalCount);
 0545            stringVirtualIndexToHeapOffsetMap.Count = totalCount;
 546
 0547            stringVirtualIndexToHeapOffsetMap[0] = 0;
 0548            heapBuilder.WriteByte(0);
 549
 550            // Find strings that can be folded
 0551            string prev = string.Empty;
 0552            foreach (KeyValuePair<string, StringHandle> entry in sorted)
 0553            {
 0554                int position = stringHeapStartOffset + heapBuilder.Count;
 555
 556                // It is important to use ordinal comparison otherwise we'll use the current culture!
 0557                if (prev.EndsWith(entry.Key, StringComparison.Ordinal) && !char.IsLowSurrogate(entry.Key[0]))
 0558                {
 559                    // Map over the tail of prev string. Watch for null-terminator of prev string.
 0560                    stringVirtualIndexToHeapOffsetMap[entry.Value.GetWriterVirtualIndex()] = position - (Encoding.UTF8.G
 0561                }
 562                else
 0563                {
 0564                    stringVirtualIndexToHeapOffsetMap[entry.Value.GetWriterVirtualIndex()] = position;
 0565                    heapBuilder.WriteUTF8(entry.Key, allowUnpairedSurrogates: false);
 0566                    heapBuilder.WriteByte(0);
 0567                }
 568
 0569                prev = entry.Key;
 0570            }
 571
 0572            return stringVirtualIndexToHeapOffsetMap.MoveToImmutable();
 0573        }
 574
 575        /// <summary>
 576        /// Sorts strings such that a string is followed immediately by all strings
 577        /// that are a suffix of it.
 578        /// </summary>
 579        private sealed class SuffixSort : IComparer<KeyValuePair<string, StringHandle>>
 580        {
 0581            internal static readonly SuffixSort Instance = new SuffixSort();
 582
 583            public int Compare(KeyValuePair<string, StringHandle> xPair, KeyValuePair<string, StringHandle> yPair)
 0584            {
 0585                string x = xPair.Key;
 0586                string y = yPair.Key;
 587
 0588                for (int i = x.Length - 1, j = y.Length - 1; i >= 0 & j >= 0; i--, j--)
 0589                {
 0590                    if (x[i] < y[j])
 0591                    {
 0592                        return -1;
 593                    }
 594
 0595                    if (x[i] > y[j])
 0596                    {
 0597                        return +1;
 598                    }
 0599                }
 600
 0601                return y.Length.CompareTo(x.Length);
 0602            }
 603        }
 604
 605        internal void WriteHeapsTo(BlobBuilder builder, BlobBuilder stringHeap)
 0606        {
 0607            WriteAligned(stringHeap, builder);
 0608            WriteAligned(_userStringBuilder, builder);
 0609            WriteAligned(_guidBuilder, builder);
 0610            WriteAlignedBlobHeap(builder);
 0611        }
 612
 613        private void WriteAlignedBlobHeap(BlobBuilder builder)
 0614        {
 0615            int alignment = BitArithmetic.Align(_blobHeapSize, 4) - _blobHeapSize;
 616
 0617            var writer = new BlobWriter(builder.ReserveBytes(_blobHeapSize + alignment));
 618
 619            // Perf consideration: With large heap the following loop may cause a lot of cache misses
 620            // since the order of entries in _blobs dictionary depends on the hash of the array values,
 621            // which is not correlated to the heap index. If we observe such issue we should order
 622            // the entries by heap position before running this loop.
 623
 0624            int startOffset = _blobHeapStartOffset;
 0625            foreach (var entry in _blobs)
 0626            {
 0627                int heapOffset = entry.Value.Value.GetHeapOffset();
 0628                var blob = entry.Value.Key;
 629
 0630                writer.Offset = (heapOffset == 0) ? 0 : heapOffset - startOffset;
 0631                writer.WriteCompressedInteger(blob.Length);
 0632                writer.WriteBytes(blob);
 0633            }
 634
 0635            writer.Offset = _blobHeapSize;
 0636            writer.WriteBytes(0, alignment);
 0637        }
 638
 639        private static void WriteAligned(BlobBuilder source, BlobBuilder target)
 0640        {
 0641            int length = source.Count;
 0642            target.LinkSuffix(source);
 0643            target.WriteBytes(0, BitArithmetic.Align(length, 4) - length);
 0644        }
 645    }
 646}
 647

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataBuilder.Tables.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Generic;
 5using System.Collections.Immutable;
 6using System.Diagnostics;
 7using System.Reflection.Internal;
 8
 9namespace System.Reflection.Metadata.Ecma335
 10{
 11    public partial class MetadataBuilder
 12    {
 13        private const byte MetadataFormatMajorVersion = 2;
 14        private const byte MetadataFormatMinorVersion = 0;
 15
 16        // type system table rows:
 17        private struct AssemblyRefTableRow { public Version Version; public BlobHandle PublicKeyToken; public StringHand
 18        private struct ModuleRow { public ushort Generation; public StringHandle Name; public GuidHandle ModuleVersionId
 19        private struct AssemblyRow { public uint HashAlgorithm; public Version Version; public ushort Flags; public Blob
 20        private struct ClassLayoutRow { public ushort PackingSize; public uint ClassSize; public int Parent; }
 21        private struct ConstantRow { public byte Type; public int Parent; public BlobHandle Value; }
 22        private struct CustomAttributeRow { public int Parent; public int Type; public BlobHandle Value; }
 23        private struct DeclSecurityRow { public ushort Action; public int Parent; public BlobHandle PermissionSet; }
 24        private struct EncLogRow { public int Token; public byte FuncCode; }
 25        private struct EncMapRow { public int Token; }
 26        private struct EventRow { public ushort EventFlags; public StringHandle Name; public int EventType; }
 27        private struct EventMapRow { public int Parent; public int EventList; }
 28        private struct ExportedTypeRow { public uint Flags; public int TypeDefId; public StringHandle TypeName; public S
 29        private struct FieldLayoutRow { public int Offset; public int Field; }
 30        private struct FieldMarshalRow { public int Parent; public BlobHandle NativeType; }
 31        private struct FieldRvaRow { public int Offset; public int Field; }
 32        private struct FieldDefRow { public ushort Flags; public StringHandle Name; public BlobHandle Signature; }
 33        private struct FileTableRow { public uint Flags; public StringHandle FileName; public BlobHandle HashValue; }
 34        private struct GenericParamConstraintRow { public int Owner; public int Constraint; }
 35        private struct GenericParamRow { public ushort Number; public ushort Flags; public int Owner; public StringHandl
 36        private struct ImplMapRow { public ushort MappingFlags; public int MemberForwarded; public StringHandle ImportNa
 37        private struct InterfaceImplRow { public int Class; public int Interface; }
 38        private struct ManifestResourceRow { public uint Offset; public uint Flags; public StringHandle Name; public int
 39        private struct MemberRefRow { public int Class; public StringHandle Name; public BlobHandle Signature; }
 40        private struct MethodImplRow { public int Class; public int MethodBody; public int MethodDecl; }
 41        private struct MethodSemanticsRow { public ushort Semantic; public int Method; public int Association; }
 42        private struct MethodSpecRow { public int Method; public BlobHandle Instantiation; }
 43        private struct MethodRow { public int BodyOffset; public ushort ImplFlags; public ushort Flags; public StringHan
 44        private struct ModuleRefRow { public StringHandle Name; }
 45        private struct NestedClassRow { public int NestedClass; public int EnclosingClass; }
 46        private struct ParamRow { public ushort Flags; public ushort Sequence; public StringHandle Name; }
 47        private struct PropertyMapRow { public int Parent; public int PropertyList; }
 48        private struct PropertyRow { public ushort PropFlags; public StringHandle Name; public BlobHandle Type; }
 49        private struct TypeDefRow { public uint Flags; public StringHandle Name; public StringHandle Namespace; public i
 50        private struct TypeRefRow { public int ResolutionScope; public StringHandle Name; public StringHandle Namespace;
 51        private struct TypeSpecRow { public BlobHandle Signature; }
 52        private struct StandaloneSigRow { public BlobHandle Signature; }
 53
 54        // debug table rows:
 55        private struct DocumentRow { public BlobHandle Name; public GuidHandle HashAlgorithm; public BlobHandle Hash; pu
 56        private struct MethodDebugInformationRow { public int Document; public BlobHandle SequencePoints; }
 57        private struct LocalScopeRow { public int Method; public int ImportScope; public int VariableList; public int Co
 58        private struct LocalVariableRow { public ushort Attributes; public ushort Index; public StringHandle Name; }
 59        private struct LocalConstantRow { public StringHandle Name; public BlobHandle Signature; }
 60        private struct ImportScopeRow { public int Parent; public BlobHandle Imports; }
 61        private struct StateMachineMethodRow { public int MoveNextMethod; public int KickoffMethod; }
 62        private struct CustomDebugInformationRow { public int Parent; public GuidHandle Kind; public BlobHandle Value; }
 63
 64        // type system tables:
 65        private ModuleRow? _moduleRow;
 66        private AssemblyRow? _assemblyRow;
 067        private readonly List<ClassLayoutRow> _classLayoutTable = new List<ClassLayoutRow>();
 68
 069        private readonly List<ConstantRow> _constantTable = new List<ConstantRow>();
 70        private int _constantTableLastParent;
 71        private bool _constantTableNeedsSorting;
 72
 073        private readonly List<CustomAttributeRow> _customAttributeTable = new List<CustomAttributeRow>();
 74        private int _customAttributeTableLastParent;
 75        private bool _customAttributeTableNeedsSorting;
 76
 077        private readonly List<DeclSecurityRow> _declSecurityTable = new List<DeclSecurityRow>();
 78        private int _declSecurityTableLastParent;
 79        private bool _declSecurityTableNeedsSorting;
 80
 081        private readonly List<EncLogRow> _encLogTable = new List<EncLogRow>();
 082        private readonly List<EncMapRow> _encMapTable = new List<EncMapRow>();
 083        private readonly List<EventRow> _eventTable = new List<EventRow>();
 084        private readonly List<EventMapRow> _eventMapTable = new List<EventMapRow>();
 085        private readonly List<ExportedTypeRow> _exportedTypeTable = new List<ExportedTypeRow>();
 086        private readonly List<FieldLayoutRow> _fieldLayoutTable = new List<FieldLayoutRow>();
 87
 088        private readonly List<FieldMarshalRow> _fieldMarshalTable = new List<FieldMarshalRow>();
 89        private int _fieldMarshalTableLastParent;
 90        private bool _fieldMarshalTableNeedsSorting;
 91
 092        private readonly List<FieldRvaRow> _fieldRvaTable = new List<FieldRvaRow>();
 093        private readonly List<FieldDefRow> _fieldTable = new List<FieldDefRow>();
 094        private readonly List<FileTableRow> _fileTable = new List<FileTableRow>();
 095        private readonly List<GenericParamConstraintRow> _genericParamConstraintTable = new List<GenericParamConstraintR
 096        private readonly List<GenericParamRow> _genericParamTable = new List<GenericParamRow>();
 097        private readonly List<ImplMapRow> _implMapTable = new List<ImplMapRow>();
 098        private readonly List<InterfaceImplRow> _interfaceImplTable = new List<InterfaceImplRow>();
 099        private readonly List<ManifestResourceRow> _manifestResourceTable = new List<ManifestResourceRow>();
 0100        private readonly List<MemberRefRow> _memberRefTable = new List<MemberRefRow>();
 0101        private readonly List<MethodImplRow> _methodImplTable = new List<MethodImplRow>();
 102
 0103        private readonly List<MethodSemanticsRow> _methodSemanticsTable = new List<MethodSemanticsRow>();
 104        private int _methodSemanticsTableLastAssociation;
 105        private bool _methodSemanticsTableNeedsSorting;
 106
 0107        private readonly List<MethodSpecRow> _methodSpecTable = new List<MethodSpecRow>();
 0108        private readonly List<MethodRow> _methodDefTable = new List<MethodRow>();
 0109        private readonly List<ModuleRefRow> _moduleRefTable = new List<ModuleRefRow>();
 0110        private readonly List<NestedClassRow> _nestedClassTable = new List<NestedClassRow>();
 0111        private readonly List<ParamRow> _paramTable = new List<ParamRow>();
 0112        private readonly List<PropertyMapRow> _propertyMapTable = new List<PropertyMapRow>();
 0113        private readonly List<PropertyRow> _propertyTable = new List<PropertyRow>();
 0114        private readonly List<TypeDefRow> _typeDefTable = new List<TypeDefRow>();
 0115        private readonly List<TypeRefRow> _typeRefTable = new List<TypeRefRow>();
 0116        private readonly List<TypeSpecRow> _typeSpecTable = new List<TypeSpecRow>();
 0117        private readonly List<AssemblyRefTableRow> _assemblyRefTable = new List<AssemblyRefTableRow>();
 0118        private readonly List<StandaloneSigRow> _standAloneSigTable = new List<StandaloneSigRow>();
 119
 120        // debug tables:
 0121        private readonly List<DocumentRow> _documentTable = new List<DocumentRow>();
 0122        private readonly List<MethodDebugInformationRow> _methodDebugInformationTable = new List<MethodDebugInformationR
 0123        private readonly List<LocalScopeRow> _localScopeTable = new List<LocalScopeRow>();
 0124        private readonly List<LocalVariableRow> _localVariableTable = new List<LocalVariableRow>();
 0125        private readonly List<LocalConstantRow> _localConstantTable = new List<LocalConstantRow>();
 0126        private readonly List<ImportScopeRow> _importScopeTable = new List<ImportScopeRow>();
 0127        private readonly List<StateMachineMethodRow> _stateMachineMethodTable = new List<StateMachineMethodRow>();
 0128        private readonly List<CustomDebugInformationRow> _customDebugInformationTable = new List<CustomDebugInformationR
 129
 130        /// <summary>
 131        /// Sets the capacity of the specified table.
 132        /// </summary>
 133        /// <exception cref="ArgumentOutOfRangeException"><paramref name="table"/> is not a valid table index.</exceptio
 134        /// <exception cref="ArgumentOutOfRangeException"><paramref name="rowCount"/> is negative.</exception>
 135        /// <remarks>
 136        /// Use to reduce allocations if the approximate number of rows is known ahead of time.
 137        /// </remarks>
 138        public void SetCapacity(TableIndex table, int rowCount)
 0139        {
 0140            if (rowCount < 0)
 0141            {
 0142                Throw.ArgumentOutOfRange(nameof(rowCount));
 143            }
 144
 0145            switch (table)
 146            {
 0147                case TableIndex.Module:                 break; // no-op, max row count is 1
 0148                case TableIndex.TypeRef:                SetTableCapacity(_typeRefTable, rowCount); break;
 0149                case TableIndex.TypeDef:                SetTableCapacity(_typeDefTable, rowCount); break;
 0150                case TableIndex.Field:                  SetTableCapacity(_fieldTable, rowCount); break;
 0151                case TableIndex.MethodDef:              SetTableCapacity(_methodDefTable, rowCount); break;
 0152                case TableIndex.Param:                  SetTableCapacity(_paramTable, rowCount); break;
 0153                case TableIndex.InterfaceImpl:          SetTableCapacity(_interfaceImplTable, rowCount); break;
 0154                case TableIndex.MemberRef:              SetTableCapacity(_memberRefTable, rowCount); break;
 0155                case TableIndex.Constant:               SetTableCapacity(_constantTable, rowCount); break;
 0156                case TableIndex.CustomAttribute:        SetTableCapacity(_customAttributeTable, rowCount); break;
 0157                case TableIndex.FieldMarshal:           SetTableCapacity(_fieldMarshalTable, rowCount); break;
 0158                case TableIndex.DeclSecurity:           SetTableCapacity(_declSecurityTable, rowCount); break;
 0159                case TableIndex.ClassLayout:            SetTableCapacity(_classLayoutTable, rowCount); break;
 0160                case TableIndex.FieldLayout:            SetTableCapacity(_fieldLayoutTable, rowCount); break;
 0161                case TableIndex.StandAloneSig:          SetTableCapacity(_standAloneSigTable, rowCount); break;
 0162                case TableIndex.EventMap:               SetTableCapacity(_eventMapTable, rowCount); break;
 0163                case TableIndex.Event:                  SetTableCapacity(_eventTable, rowCount); break;
 0164                case TableIndex.PropertyMap:            SetTableCapacity(_propertyMapTable, rowCount); break;
 0165                case TableIndex.Property:               SetTableCapacity(_propertyTable, rowCount); break;
 0166                case TableIndex.MethodSemantics:        SetTableCapacity(_methodSemanticsTable, rowCount); break;
 0167                case TableIndex.MethodImpl:             SetTableCapacity(_methodImplTable, rowCount); break;
 0168                case TableIndex.ModuleRef:              SetTableCapacity(_moduleRefTable, rowCount); break;
 0169                case TableIndex.TypeSpec:               SetTableCapacity(_typeSpecTable, rowCount); break;
 0170                case TableIndex.ImplMap:                SetTableCapacity(_implMapTable, rowCount); break;
 0171                case TableIndex.FieldRva:               SetTableCapacity(_fieldRvaTable, rowCount); break;
 0172                case TableIndex.EncLog:                 SetTableCapacity(_encLogTable, rowCount); break;
 0173                case TableIndex.EncMap:                 SetTableCapacity(_encMapTable, rowCount); break;
 0174                case TableIndex.Assembly:               break; // no-op, max row count is 1
 0175                case TableIndex.AssemblyRef:            SetTableCapacity(_assemblyRefTable, rowCount); break;
 0176                case TableIndex.File:                   SetTableCapacity(_fileTable, rowCount); break;
 0177                case TableIndex.ExportedType:           SetTableCapacity(_exportedTypeTable, rowCount); break;
 0178                case TableIndex.ManifestResource:       SetTableCapacity(_manifestResourceTable, rowCount); break;
 0179                case TableIndex.NestedClass:            SetTableCapacity(_nestedClassTable, rowCount); break;
 0180                case TableIndex.GenericParam:           SetTableCapacity(_genericParamTable, rowCount); break;
 0181                case TableIndex.MethodSpec:             SetTableCapacity(_methodSpecTable, rowCount); break;
 0182                case TableIndex.GenericParamConstraint: SetTableCapacity(_genericParamConstraintTable, rowCount); break;
 0183                case TableIndex.Document:               SetTableCapacity(_documentTable, rowCount); break;
 0184                case TableIndex.MethodDebugInformation: SetTableCapacity(_methodDebugInformationTable, rowCount); break;
 0185                case TableIndex.LocalScope:             SetTableCapacity(_localScopeTable, rowCount); break;
 0186                case TableIndex.LocalVariable:          SetTableCapacity(_localVariableTable, rowCount); break;
 0187                case TableIndex.LocalConstant:          SetTableCapacity(_localConstantTable, rowCount); break;
 0188                case TableIndex.ImportScope:            SetTableCapacity(_importScopeTable, rowCount); break;
 0189                case TableIndex.StateMachineMethod:     SetTableCapacity(_stateMachineMethodTable, rowCount); break;
 0190                case TableIndex.CustomDebugInformation: SetTableCapacity(_customDebugInformationTable, rowCount); break;
 191
 192                case TableIndex.AssemblyOS:
 193                case TableIndex.AssemblyProcessor:
 194                case TableIndex.AssemblyRefOS:
 195                case TableIndex.AssemblyRefProcessor:
 196                case TableIndex.EventPtr:
 197                case TableIndex.FieldPtr:
 198                case TableIndex.MethodPtr:
 199                case TableIndex.ParamPtr:
 200                case TableIndex.PropertyPtr:
 201                    // these tables are currently not serialized
 0202                    break;
 203
 204                default:
 0205                    throw new ArgumentOutOfRangeException(nameof(table));
 206            }
 0207        }
 208
 209        private static void SetTableCapacity<T>(List<T> table, int rowCount)
 0210        {
 0211            if (rowCount > table.Count)
 0212            {
 0213                table.Capacity = rowCount;
 0214            }
 0215        }
 216
 217        /// <summary>
 218        /// Returns the current number of entries in the specified table.
 219        /// </summary>
 220        /// <param name="table">Table index.</param>
 221        /// <returns>The number of entries in the table.</returns>
 222        /// <exception cref="ArgumentOutOfRangeException"><paramref name="table"/> is not a valid table index.</exceptio
 223        public int GetRowCount(TableIndex table)
 0224        {
 0225            switch (table)
 226            {
 0227                case TableIndex.Assembly                : return _assemblyRow.HasValue ? 1 : 0;
 0228                case TableIndex.AssemblyRef             : return _assemblyRefTable.Count;
 0229                case TableIndex.ClassLayout             : return _classLayoutTable.Count;
 0230                case TableIndex.Constant                : return _constantTable.Count;
 0231                case TableIndex.CustomAttribute         : return _customAttributeTable.Count;
 0232                case TableIndex.DeclSecurity            : return _declSecurityTable.Count;
 0233                case TableIndex.EncLog                  : return _encLogTable.Count;
 0234                case TableIndex.EncMap                  : return _encMapTable.Count;
 0235                case TableIndex.EventMap                : return _eventMapTable.Count;
 0236                case TableIndex.Event                   : return _eventTable.Count;
 0237                case TableIndex.ExportedType            : return _exportedTypeTable.Count;
 0238                case TableIndex.FieldLayout             : return _fieldLayoutTable.Count;
 0239                case TableIndex.FieldMarshal            : return _fieldMarshalTable.Count;
 0240                case TableIndex.FieldRva                : return _fieldRvaTable.Count;
 0241                case TableIndex.Field                   : return _fieldTable.Count;
 0242                case TableIndex.File                    : return _fileTable.Count;
 0243                case TableIndex.GenericParamConstraint  : return _genericParamConstraintTable.Count;
 0244                case TableIndex.GenericParam            : return _genericParamTable.Count;
 0245                case TableIndex.ImplMap                 : return _implMapTable.Count;
 0246                case TableIndex.InterfaceImpl           : return _interfaceImplTable.Count;
 0247                case TableIndex.ManifestResource        : return _manifestResourceTable.Count;
 0248                case TableIndex.MemberRef               : return _memberRefTable.Count;
 0249                case TableIndex.MethodImpl              : return _methodImplTable.Count;
 0250                case TableIndex.MethodSemantics         : return _methodSemanticsTable.Count;
 0251                case TableIndex.MethodSpec              : return _methodSpecTable.Count;
 0252                case TableIndex.MethodDef               : return _methodDefTable.Count;
 0253                case TableIndex.ModuleRef               : return _moduleRefTable.Count;
 0254                case TableIndex.Module                  : return _moduleRow.HasValue ? 1 : 0;
 0255                case TableIndex.NestedClass             : return _nestedClassTable.Count;
 0256                case TableIndex.Param                   : return _paramTable.Count;
 0257                case TableIndex.PropertyMap             : return _propertyMapTable.Count;
 0258                case TableIndex.Property                : return _propertyTable.Count;
 0259                case TableIndex.StandAloneSig           : return _standAloneSigTable.Count;
 0260                case TableIndex.TypeDef                 : return _typeDefTable.Count;
 0261                case TableIndex.TypeRef                 : return _typeRefTable.Count;
 0262                case TableIndex.TypeSpec                : return _typeSpecTable.Count;
 0263                case TableIndex.Document                : return _documentTable.Count;
 0264                case TableIndex.MethodDebugInformation  : return _methodDebugInformationTable.Count;
 0265                case TableIndex.LocalScope              : return _localScopeTable.Count;
 0266                case TableIndex.LocalVariable           : return _localVariableTable.Count;
 0267                case TableIndex.LocalConstant           : return _localConstantTable.Count;
 0268                case TableIndex.StateMachineMethod      : return _stateMachineMethodTable.Count;
 0269                case TableIndex.ImportScope             : return _importScopeTable.Count;
 0270                case TableIndex.CustomDebugInformation  : return _customDebugInformationTable.Count;
 271
 272                case TableIndex.AssemblyOS:
 273                case TableIndex.AssemblyProcessor:
 274                case TableIndex.AssemblyRefOS:
 275                case TableIndex.AssemblyRefProcessor:
 276                case TableIndex.EventPtr:
 277                case TableIndex.FieldPtr:
 278                case TableIndex.MethodPtr:
 279                case TableIndex.ParamPtr:
 280                case TableIndex.PropertyPtr:
 0281                    return 0;
 282
 283                default:
 0284                    throw new ArgumentOutOfRangeException(nameof(table));
 285            }
 0286        }
 287
 288        /// <summary>
 289        /// Returns the current number of entries in each table.
 290        /// </summary>
 291        /// <returns>
 292        /// An array of size <see cref="MetadataTokens.TableCount"/> with each item filled with the current row count of
 293        /// </returns>
 294        public ImmutableArray<int> GetRowCounts()
 0295        {
 0296            var rowCounts = ImmutableArray.CreateBuilder<int>(MetadataTokens.TableCount);
 0297            rowCounts.Count = MetadataTokens.TableCount;
 298
 0299            rowCounts[(int)TableIndex.Assembly] = _assemblyRow.HasValue ? 1 : 0;
 0300            rowCounts[(int)TableIndex.AssemblyRef] = _assemblyRefTable.Count;
 0301            rowCounts[(int)TableIndex.ClassLayout] = _classLayoutTable.Count;
 0302            rowCounts[(int)TableIndex.Constant] = _constantTable.Count;
 0303            rowCounts[(int)TableIndex.CustomAttribute] = _customAttributeTable.Count;
 0304            rowCounts[(int)TableIndex.DeclSecurity] = _declSecurityTable.Count;
 0305            rowCounts[(int)TableIndex.EncLog] = _encLogTable.Count;
 0306            rowCounts[(int)TableIndex.EncMap] = _encMapTable.Count;
 0307            rowCounts[(int)TableIndex.EventMap] = _eventMapTable.Count;
 0308            rowCounts[(int)TableIndex.Event] = _eventTable.Count;
 0309            rowCounts[(int)TableIndex.ExportedType] = _exportedTypeTable.Count;
 0310            rowCounts[(int)TableIndex.FieldLayout] = _fieldLayoutTable.Count;
 0311            rowCounts[(int)TableIndex.FieldMarshal] = _fieldMarshalTable.Count;
 0312            rowCounts[(int)TableIndex.FieldRva] = _fieldRvaTable.Count;
 0313            rowCounts[(int)TableIndex.Field] = _fieldTable.Count;
 0314            rowCounts[(int)TableIndex.File] = _fileTable.Count;
 0315            rowCounts[(int)TableIndex.GenericParamConstraint] = _genericParamConstraintTable.Count;
 0316            rowCounts[(int)TableIndex.GenericParam] = _genericParamTable.Count;
 0317            rowCounts[(int)TableIndex.ImplMap] = _implMapTable.Count;
 0318            rowCounts[(int)TableIndex.InterfaceImpl] = _interfaceImplTable.Count;
 0319            rowCounts[(int)TableIndex.ManifestResource] = _manifestResourceTable.Count;
 0320            rowCounts[(int)TableIndex.MemberRef] = _memberRefTable.Count;
 0321            rowCounts[(int)TableIndex.MethodImpl] = _methodImplTable.Count;
 0322            rowCounts[(int)TableIndex.MethodSemantics] = _methodSemanticsTable.Count;
 0323            rowCounts[(int)TableIndex.MethodSpec] = _methodSpecTable.Count;
 0324            rowCounts[(int)TableIndex.MethodDef] = _methodDefTable.Count;
 0325            rowCounts[(int)TableIndex.ModuleRef] = _moduleRefTable.Count;
 0326            rowCounts[(int)TableIndex.Module] = _moduleRow.HasValue ? 1 : 0;
 0327            rowCounts[(int)TableIndex.NestedClass] = _nestedClassTable.Count;
 0328            rowCounts[(int)TableIndex.Param] = _paramTable.Count;
 0329            rowCounts[(int)TableIndex.PropertyMap] = _propertyMapTable.Count;
 0330            rowCounts[(int)TableIndex.Property] = _propertyTable.Count;
 0331            rowCounts[(int)TableIndex.StandAloneSig] = _standAloneSigTable.Count;
 0332            rowCounts[(int)TableIndex.TypeDef] = _typeDefTable.Count;
 0333            rowCounts[(int)TableIndex.TypeRef] = _typeRefTable.Count;
 0334            rowCounts[(int)TableIndex.TypeSpec] = _typeSpecTable.Count;
 335
 0336            rowCounts[(int)TableIndex.Document] = _documentTable.Count;
 0337            rowCounts[(int)TableIndex.MethodDebugInformation] = _methodDebugInformationTable.Count;
 0338            rowCounts[(int)TableIndex.LocalScope] = _localScopeTable.Count;
 0339            rowCounts[(int)TableIndex.LocalVariable] = _localVariableTable.Count;
 0340            rowCounts[(int)TableIndex.LocalConstant] = _localConstantTable.Count;
 0341            rowCounts[(int)TableIndex.StateMachineMethod] = _stateMachineMethodTable.Count;
 0342            rowCounts[(int)TableIndex.ImportScope] = _importScopeTable.Count;
 0343            rowCounts[(int)TableIndex.CustomDebugInformation] = _customDebugInformationTable.Count;
 344
 0345            return rowCounts.MoveToImmutable();
 0346        }
 347
 348        #region Building
 349
 350        // Note on argument value checking:
 351        //
 352        // To avoid perf overhead we do minimal argument checking.
 353        // We only check integer parameter bounds if we perform a narrowing conversion,
 354        // so that we don't mangle values that match the Add method signature but are too big to represent in the metada
 355        // We do not validate ranges of enum values, we just ignore high bits when converting to smaller integral type.
 356        // Adding such checks would unlikely catch bugs in reasonably written code.
 357
 358        public ModuleDefinitionHandle AddModule(
 359            int generation,
 360            StringHandle moduleName,
 361            GuidHandle mvid,
 362            GuidHandle encId,
 363            GuidHandle encBaseId)
 0364        {
 0365            if (unchecked((uint)generation) > ushort.MaxValue)
 0366            {
 0367                Throw.ArgumentOutOfRange(nameof(generation));
 368            }
 369
 0370            if (_moduleRow.HasValue)
 0371            {
 0372                Throw.InvalidOperation(SR.ModuleAlreadyAdded);
 373            }
 374
 0375            _moduleRow = new ModuleRow
 0376            {
 0377                Generation = (ushort)generation,
 0378                Name = moduleName,
 0379                ModuleVersionId = mvid,
 0380                EncId = encId,
 0381                EncBaseId = encBaseId,
 0382            };
 383
 0384            return EntityHandle.ModuleDefinition;
 0385        }
 386
 387        public AssemblyDefinitionHandle AddAssembly(
 388            StringHandle name,
 389            Version version,
 390            StringHandle culture,
 391            BlobHandle publicKey,
 392            AssemblyFlags flags,
 393            AssemblyHashAlgorithm hashAlgorithm)
 0394        {
 0395            if (version is null)
 0396            {
 0397                Throw.ArgumentNull(nameof(version));
 398            }
 399
 0400            if (_assemblyRow.HasValue)
 0401            {
 0402                Throw.InvalidOperation(SR.AssemblyAlreadyAdded);
 403            }
 404
 0405            _assemblyRow = new AssemblyRow
 0406            {
 0407                Flags = unchecked((ushort)flags),
 0408                HashAlgorithm = unchecked((uint)hashAlgorithm),
 0409                Version = version,
 0410                AssemblyKey = publicKey,
 0411                AssemblyName = name,
 0412                AssemblyCulture = culture
 0413            };
 414
 0415            return EntityHandle.AssemblyDefinition;
 0416        }
 417
 418        public AssemblyReferenceHandle AddAssemblyReference(
 419            StringHandle name,
 420            Version version,
 421            StringHandle culture,
 422            BlobHandle publicKeyOrToken,
 423            AssemblyFlags flags,
 424            BlobHandle hashValue)
 0425        {
 0426            if (version is null)
 0427            {
 0428                Throw.ArgumentNull(nameof(version));
 429            }
 430
 0431            _assemblyRefTable.Add(new AssemblyRefTableRow
 0432            {
 0433                Name = name,
 0434                Version = version,
 0435                Culture = culture,
 0436                PublicKeyToken = publicKeyOrToken,
 0437                Flags = unchecked((uint)flags),
 0438                HashValue = hashValue
 0439            });
 440
 0441            return AssemblyReferenceHandle.FromRowId(_assemblyRefTable.Count);
 0442        }
 443
 444        /// <summary>
 445        /// Adds a type definition.
 446        /// </summary>
 447        /// <param name="attributes">Attributes</param>
 448        /// <param name="namespace">Namespace</param>
 449        /// <param name="name">Type name</param>
 450        /// <param name="baseType"><see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/>, <see cref="Typ
 451        /// <param name="fieldList">
 452        /// If the type declares fields the handle of the first one, otherwise the handle of the first field declared by
 453        /// If no type defines any fields in the module, <see cref="MetadataTokens.FieldDefinitionHandle(int)"/>(1).
 454        /// </param>
 455        /// <param name="methodList">
 456        /// If the type declares methods the handle of the first one, otherwise the handle of the first method declared 
 457        /// If no type defines any methods in the module, <see cref="MetadataTokens.MethodDefinitionHandle(int)"/>(1).
 458        /// </param>
 459        /// <exception cref="ArgumentException"><paramref name="baseType"/> doesn't have the expected handle kind.</exce
 460        public TypeDefinitionHandle AddTypeDefinition(
 461            TypeAttributes attributes,
 462            StringHandle @namespace,
 463            StringHandle name,
 464            EntityHandle baseType,
 465            FieldDefinitionHandle fieldList,
 466            MethodDefinitionHandle methodList)
 0467        {
 0468            _typeDefTable.Add(new TypeDefRow
 0469            {
 0470                Flags = unchecked((uint)attributes),
 0471                Name = name,
 0472                Namespace = @namespace,
 0473                Extends = baseType.IsNil ? 0 : CodedIndex.TypeDefOrRefOrSpec(baseType),
 0474                FieldList = fieldList.RowId,
 0475                MethodList = methodList.RowId
 0476            });
 477
 0478            return TypeDefinitionHandle.FromRowId(_typeDefTable.Count);
 0479        }
 480
 481        /// <summary>
 482        /// Defines a type layout of a type definition.
 483        /// </summary>
 484        /// <param name="type">Type definition.</param>
 485        /// <param name="packingSize">
 486        /// Specifies that fields should be placed within the type instance at byte addresses which are a multiple of th
 487        /// or at natural alignment for that field type, whichever is smaller. Shall be one of the following: 0, 1, 2, 4
 488        /// A value of zero indicates that the packing size used should match the default for the current platform.
 489        /// </param>
 490        /// <param name="size">
 491        /// Indicates a minimum size of the type instance, and is intended to allow for padding.
 492        /// The amount of memory allocated is the maximum of the size calculated from the layout and <paramref name="siz
 493        /// Note that if this directive applies to a value type, then the size shall be less than 1 MB.
 494        /// </param>
 495        /// <remarks>
 496        /// Entries must be added in the same order as the corresponding type definitions.
 497        /// </remarks>
 498        public void AddTypeLayout(
 499            TypeDefinitionHandle type,
 500            ushort packingSize,
 501            uint size)
 0502        {
 0503            _classLayoutTable.Add(new ClassLayoutRow
 0504            {
 0505                Parent = type.RowId,
 0506                PackingSize = packingSize,
 0507                ClassSize = size
 0508            });
 0509        }
 510
 511        /// <summary>
 512        /// Adds an interface implementation to a type.
 513        /// </summary>
 514        /// <param name="type">The type implementing the interface.</param>
 515        /// <param name="implementedInterface">
 516        /// The interface being implemented:
 517        /// <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/> or <see cref="TypeSpecificationHandle"
 518        /// </param>
 519        /// <remarks>
 520        /// Interface implementations must be added in the same order as the corresponding type definitions implementing
 521        /// If a type implements multiple interfaces the corresponding entries must be added in the order determined by 
 522        /// </remarks>
 523        /// <exception cref="ArgumentException"><paramref name="implementedInterface"/> doesn't have the expected handle
 524        public InterfaceImplementationHandle AddInterfaceImplementation(
 525            TypeDefinitionHandle type,
 526            EntityHandle implementedInterface)
 0527        {
 0528            _interfaceImplTable.Add(new InterfaceImplRow
 0529            {
 0530                Class = type.RowId,
 0531                Interface = CodedIndex.TypeDefOrRefOrSpec(implementedInterface)
 0532            });
 533
 0534            return InterfaceImplementationHandle.FromRowId(_interfaceImplTable.Count);
 0535        }
 536
 537        /// <summary>
 538        /// Defines a nesting relationship to specified type definitions.
 539        /// </summary>
 540        /// <param name="type">The nested type definition handle.</param>
 541        /// <param name="enclosingType">The enclosing type definition handle.</param>
 542        /// <remarks>
 543        /// Entries must be added in the same order as the corresponding nested type definitions.
 544        /// </remarks>
 545        public void AddNestedType(
 546            TypeDefinitionHandle type,
 547            TypeDefinitionHandle enclosingType)
 0548        {
 0549            _nestedClassTable.Add(new NestedClassRow
 0550            {
 0551                NestedClass = type.RowId,
 0552                EnclosingClass = enclosingType.RowId
 0553            });
 0554        }
 555
 556        /// <summary>
 557        /// Add a type reference.
 558        /// </summary>
 559        /// <param name="resolutionScope">
 560        /// The entity declaring the target type:
 561        /// <see cref="ModuleDefinitionHandle"/>, <see cref="ModuleReferenceHandle"/>, <see cref="AssemblyReferenceHandl
 562        /// </param>
 563        /// <param name="namespace">Namespace.</param>
 564        /// <param name="name">Type name.</param>
 565        /// <exception cref="ArgumentException"><paramref name="resolutionScope"/> doesn't have the expected handle kind
 566        public TypeReferenceHandle AddTypeReference(
 567            EntityHandle resolutionScope,
 568            StringHandle @namespace,
 569            StringHandle name)
 0570        {
 0571            _typeRefTable.Add(new TypeRefRow
 0572            {
 0573                ResolutionScope = resolutionScope.IsNil ? 0 : CodedIndex.ResolutionScope(resolutionScope),
 0574                Name = name,
 0575                Namespace = @namespace
 0576            });
 577
 0578            return TypeReferenceHandle.FromRowId(_typeRefTable.Count);
 0579        }
 580
 581        public TypeSpecificationHandle AddTypeSpecification(BlobHandle signature)
 0582        {
 0583            _typeSpecTable.Add(new TypeSpecRow
 0584            {
 0585                Signature = signature
 0586            });
 587
 0588            return TypeSpecificationHandle.FromRowId(_typeSpecTable.Count);
 0589        }
 590
 591        public StandaloneSignatureHandle AddStandaloneSignature(BlobHandle signature)
 0592        {
 0593            _standAloneSigTable.Add(new StandaloneSigRow
 0594            {
 0595                Signature = signature
 0596            });
 597
 0598            return StandaloneSignatureHandle.FromRowId(_standAloneSigTable.Count);
 0599        }
 600
 601        /// <summary>
 602        /// Adds a property definition.
 603        /// </summary>
 604        /// <param name="attributes">Attributes</param>
 605        /// <param name="name">Name</param>
 606        /// <param name="signature">Signature of the property.</param>
 607        public PropertyDefinitionHandle AddProperty(PropertyAttributes attributes, StringHandle name, BlobHandle signatu
 0608        {
 0609            _propertyTable.Add(new PropertyRow
 0610            {
 0611                PropFlags = unchecked((ushort)attributes),
 0612                Name = name,
 0613                Type = signature
 0614            });
 615
 0616            return PropertyDefinitionHandle.FromRowId(_propertyTable.Count);
 0617        }
 618
 619        public void AddPropertyMap(TypeDefinitionHandle declaringType, PropertyDefinitionHandle propertyList)
 0620        {
 0621            _propertyMapTable.Add(new PropertyMapRow
 0622            {
 0623                Parent = declaringType.RowId,
 0624                PropertyList = propertyList.RowId
 0625            });
 0626        }
 627
 628        /// <summary>
 629        /// Adds an event definition.
 630        /// </summary>
 631        /// <param name="attributes">Attributes</param>
 632        /// <param name="name">Name</param>
 633        /// <param name="type">Type of the event: <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/>,
 634        /// <exception cref="ArgumentException"><paramref name="type"/> doesn't have the expected handle kind.</exceptio
 635        public EventDefinitionHandle AddEvent(EventAttributes attributes, StringHandle name, EntityHandle type)
 0636        {
 0637            _eventTable.Add(new EventRow
 0638            {
 0639                EventFlags = unchecked((ushort)attributes),
 0640                Name = name,
 0641                EventType = CodedIndex.TypeDefOrRefOrSpec(type)
 0642            });
 643
 0644            return EventDefinitionHandle.FromRowId(_eventTable.Count);
 0645        }
 646
 647        public void AddEventMap(TypeDefinitionHandle declaringType, EventDefinitionHandle eventList)
 0648        {
 0649            _eventMapTable.Add(new EventMapRow
 0650            {
 0651                Parent = declaringType.RowId,
 0652                EventList = eventList.RowId
 0653            });
 0654        }
 655
 656        /// <summary>
 657        /// Adds a default value for a parameter, field or property.
 658        /// </summary>
 659        /// <param name="parent"><see cref="ParameterHandle"/>, <see cref="FieldDefinitionHandle"/>, or <see cref="Prope
 660        /// <param name="value">The constant value.</param>
 661        /// <remarks>
 662        /// Entries may be added in any order. The table is automatically sorted when serialized.
 663        /// </remarks>
 664        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 665        public ConstantHandle AddConstant(EntityHandle parent, object? value)
 0666        {
 0667            int parentCodedIndex = CodedIndex.HasConstant(parent);
 668
 669            // the table is required to be sorted by Parent:
 0670            _constantTableNeedsSorting |= parentCodedIndex < _constantTableLastParent;
 0671            _constantTableLastParent = parentCodedIndex;
 672
 0673            _constantTable.Add(new ConstantRow
 0674            {
 0675                Type = (byte)MetadataWriterUtilities.GetConstantTypeCode(value),
 0676                Parent = parentCodedIndex,
 0677                Value = GetOrAddConstantBlob(value)
 0678            });
 679
 0680            return ConstantHandle.FromRowId(_constantTable.Count);
 0681        }
 682
 683        /// <summary>
 684        /// Associates a method (a getter, a setter, an adder, etc.) with a property or an event.
 685        /// </summary>
 686        /// <param name="association"><see cref="EventDefinitionHandle"/> or <see cref="PropertyDefinitionHandle"/>.</pa
 687        /// <param name="semantics">Semantics.</param>
 688        /// <param name="methodDefinition">Method definition.</param>
 689        /// <exception cref="ArgumentException"><paramref name="association"/> doesn't have the expected handle kind.</e
 690        /// <remarks>
 691        /// Entries may be added in any order. The table is automatically sorted when serialized.
 692        /// </remarks>
 693        public void AddMethodSemantics(EntityHandle association, MethodSemanticsAttributes semantics, MethodDefinitionHa
 0694        {
 0695            int associationCodedIndex = CodedIndex.HasSemantics(association);
 696
 697            // the table is required to be sorted by Association:
 0698            _methodSemanticsTableNeedsSorting |= associationCodedIndex < _methodSemanticsTableLastAssociation;
 0699            _methodSemanticsTableLastAssociation = associationCodedIndex;
 700
 0701            _methodSemanticsTable.Add(new MethodSemanticsRow
 0702            {
 0703                Association = associationCodedIndex,
 0704                Method = methodDefinition.RowId,
 0705                Semantic = unchecked((ushort)semantics)
 0706            });
 0707        }
 708
 709        /// <summary>
 710        /// Add a custom attribute.
 711        /// </summary>
 712        /// <param name="parent">
 713        /// An entity to attach the custom attribute to:
 714        /// <see cref="MethodDefinitionHandle"/>,
 715        /// <see cref="FieldDefinitionHandle"/>,
 716        /// <see cref="TypeReferenceHandle"/>,
 717        /// <see cref="TypeDefinitionHandle"/>,
 718        /// <see cref="ParameterHandle"/>,
 719        /// <see cref="InterfaceImplementationHandle"/>,
 720        /// <see cref="MemberReferenceHandle"/>,
 721        /// <see cref="ModuleDefinitionHandle"/>,
 722        /// <see cref="DeclarativeSecurityAttributeHandle"/>,
 723        /// <see cref="PropertyDefinitionHandle"/>,
 724        /// <see cref="EventDefinitionHandle"/>,
 725        /// <see cref="StandaloneSignatureHandle"/>,
 726        /// <see cref="ModuleReferenceHandle"/>,
 727        /// <see cref="TypeSpecificationHandle"/>,
 728        /// <see cref="AssemblyDefinitionHandle"/>,
 729        /// <see cref="AssemblyReferenceHandle"/>,
 730        /// <see cref="AssemblyFileHandle"/>,
 731        /// <see cref="ExportedTypeHandle"/>,
 732        /// <see cref="ManifestResourceHandle"/>,
 733        /// <see cref="GenericParameterHandle"/>,
 734        /// <see cref="GenericParameterConstraintHandle"/> or
 735        /// <see cref="MethodSpecificationHandle"/>.
 736        /// </param>
 737        /// <param name="constructor">
 738        /// Custom attribute constructor: <see cref="MethodDefinitionHandle"/> or <see cref="MemberReferenceHandle"/>
 739        /// </param>
 740        /// <param name="value">
 741        /// Custom attribute value blob.
 742        /// </param>
 743        /// <remarks>
 744        /// Entries may be added in any order. The table is automatically sorted when serialized.
 745        /// </remarks>
 746        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 747        public CustomAttributeHandle AddCustomAttribute(EntityHandle parent, EntityHandle constructor, BlobHandle value)
 0748        {
 0749            int parentCodedIndex = CodedIndex.HasCustomAttribute(parent);
 750
 751            // the table is required to be sorted by Parent:
 0752            _customAttributeTableNeedsSorting |= parentCodedIndex < _customAttributeTableLastParent;
 0753            _customAttributeTableLastParent = parentCodedIndex;
 754
 0755            _customAttributeTable.Add(new CustomAttributeRow
 0756            {
 0757                Parent = parentCodedIndex,
 0758                Type = CodedIndex.CustomAttributeType(constructor),
 0759                Value = value
 0760            });
 761
 0762            return CustomAttributeHandle.FromRowId(_customAttributeTable.Count);
 0763        }
 764
 765        /// <summary>
 766        /// Adds a method specification (instantiation).
 767        /// </summary>
 768        /// <param name="method">Generic method: <see cref="MethodDefinitionHandle"/> or <see cref="MemberReferenceHandl
 769        /// <param name="instantiation">Instantiation blob encoding the generic arguments of the method.</param>
 770        /// <exception cref="ArgumentException"><paramref name="method"/> doesn't have the expected handle kind.</except
 771        public MethodSpecificationHandle AddMethodSpecification(EntityHandle method, BlobHandle instantiation)
 0772        {
 0773            _methodSpecTable.Add(new MethodSpecRow
 0774            {
 0775                Method = CodedIndex.MethodDefOrRef(method),
 0776                Instantiation = instantiation
 0777            });
 778
 0779            return MethodSpecificationHandle.FromRowId(_methodSpecTable.Count);
 0780        }
 781
 782        public ModuleReferenceHandle AddModuleReference(StringHandle moduleName)
 0783        {
 0784            _moduleRefTable.Add(new ModuleRefRow
 0785            {
 0786                Name = moduleName
 0787            });
 788
 0789            return ModuleReferenceHandle.FromRowId(_moduleRefTable.Count);
 0790        }
 791
 792        /// <summary>
 793        /// Adds a parameter definition.
 794        /// </summary>
 795        /// <param name="attributes"><see cref="ParameterAttributes"/></param>
 796        /// <param name="name">Parameter name (optional).</param>
 797        /// <param name="sequenceNumber">Sequence number of the parameter. Value of 0 refers to the owner method's retur
 798        /// <exception cref="ArgumentOutOfRangeException"><paramref name="sequenceNumber"/> is greater than <see cref="u
 799        public ParameterHandle AddParameter(ParameterAttributes attributes, StringHandle name, int sequenceNumber)
 0800        {
 0801            if (unchecked((uint)sequenceNumber) > ushort.MaxValue)
 0802            {
 0803                Throw.ArgumentOutOfRange(nameof(sequenceNumber));
 804            }
 805
 0806            _paramTable.Add(new ParamRow
 0807            {
 0808                Flags = unchecked((ushort)attributes),
 0809                Name = name,
 0810                Sequence = (ushort)sequenceNumber
 0811            });
 812
 0813            return ParameterHandle.FromRowId(_paramTable.Count);
 0814        }
 815
 816        /// <summary>
 817        /// Adds a generic parameter definition.
 818        /// </summary>
 819        /// <param name="parent">Parent entity handle: <see cref="TypeDefinitionHandle"/> or <see cref="MethodDefinition
 820        /// <param name="attributes">Attributes.</param>
 821        /// <param name="name">Parameter name.</param>
 822        /// <param name="index">Zero-based parameter index.</param>
 823        /// <remarks>
 824        /// Generic parameters must be added in an order determined by the coded index of their parent entity (<see cref
 825        /// Generic parameters with the same parent must be ordered by their <paramref name="index"/>.
 826        /// </remarks>
 827        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 828        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is greater than <see cref="ushort.Max
 829        public GenericParameterHandle AddGenericParameter(
 830            EntityHandle parent,
 831            GenericParameterAttributes attributes,
 832            StringHandle name,
 833            int index)
 0834        {
 0835            if (unchecked((uint)index) > ushort.MaxValue)
 0836            {
 0837                Throw.ArgumentOutOfRange(nameof(index));
 838            }
 839
 0840            _genericParamTable.Add(new GenericParamRow
 0841            {
 0842                Flags = unchecked((ushort)attributes),
 0843                Name = name,
 0844                Number = (ushort)index,
 0845                Owner = CodedIndex.TypeOrMethodDef(parent)
 0846            });
 847
 0848            return GenericParameterHandle.FromRowId(_genericParamTable.Count);
 0849        }
 850
 851        /// <summary>
 852        /// Adds a type constraint to a generic parameter.
 853        /// </summary>
 854        /// <param name="genericParameter">Generic parameter to constrain.</param>
 855        /// <param name="constraint">Type constraint: <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle
 856        /// <exception cref="ArgumentException"><paramref name="genericParameter"/> doesn't have the expected handle kin
 857        /// <remarks>
 858        /// Constraints must be added in the same order as the corresponding generic parameters.
 859        /// </remarks>
 860        public GenericParameterConstraintHandle AddGenericParameterConstraint(
 861            GenericParameterHandle genericParameter,
 862            EntityHandle constraint)
 0863        {
 0864            _genericParamConstraintTable.Add(new GenericParamConstraintRow
 0865            {
 0866                Owner = genericParameter.RowId,
 0867                Constraint = CodedIndex.TypeDefOrRefOrSpec(constraint),
 0868            });
 869
 0870            return GenericParameterConstraintHandle.FromRowId(_genericParamConstraintTable.Count);
 0871        }
 872
 873        /// <summary>
 874        /// Adds a field definition.
 875        /// </summary>
 876        /// <param name="attributes">Field attributes.</param>
 877        /// <param name="name">Field name.</param>
 878        /// <param name="signature">Field signature. Use <see cref="BlobEncoder.FieldSignature"/> to construct the blob.
 879        public FieldDefinitionHandle AddFieldDefinition(
 880            FieldAttributes attributes,
 881            StringHandle name,
 882            BlobHandle signature)
 0883        {
 0884            _fieldTable.Add(new FieldDefRow
 0885            {
 0886                Flags = unchecked((ushort)attributes),
 0887                Name = name,
 0888                Signature = signature
 0889            });
 890
 0891            return FieldDefinitionHandle.FromRowId(_fieldTable.Count);
 0892        }
 893
 894        /// <summary>
 895        /// Defines a field layout of a field definition.
 896        /// </summary>
 897        /// <param name="field">Field definition.</param>
 898        /// <param name="offset">The byte offset of the field within the declaring type instance.</param>
 899        /// <remarks>
 900        /// Entries must be added in the same order as the corresponding field definitions.
 901        /// </remarks>
 902        public void AddFieldLayout(
 903            FieldDefinitionHandle field,
 904            int offset)
 0905        {
 0906            _fieldLayoutTable.Add(new FieldLayoutRow
 0907            {
 0908                Field = field.RowId,
 0909                Offset = offset
 0910            });
 0911        }
 912
 913        /// <summary>
 914        /// Add marshalling information to a field or a parameter.
 915        /// </summary>
 916        /// <param name="parent"><see cref="ParameterHandle"/> or <see cref="FieldDefinitionHandle"/>.</param>
 917        /// <param name="descriptor">Descriptor blob.</param>
 918        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 919        /// <remarks>
 920        /// Entries may be added in any order. The table is automatically sorted when serialized.
 921        /// </remarks>
 922        public void AddMarshallingDescriptor(
 923            EntityHandle parent,
 924            BlobHandle descriptor)
 0925        {
 0926            int codedIndex = CodedIndex.HasFieldMarshal(parent);
 927
 928            // the table is required to be sorted by Parent:
 0929            _fieldMarshalTableNeedsSorting |= codedIndex < _fieldMarshalTableLastParent;
 0930            _fieldMarshalTableLastParent = codedIndex;
 931
 0932            _fieldMarshalTable.Add(new FieldMarshalRow
 0933            {
 0934                Parent = codedIndex,
 0935                NativeType = descriptor
 0936            });
 0937        }
 938
 939        /// <summary>
 940        /// Adds a mapping from a field to its initial value stored in the PE image.
 941        /// </summary>
 942        /// <param name="field">Field definition handle.</param>
 943        /// <param name="offset">
 944        /// Offset within the block in the PE image that stores initial values of mapped fields (usually in .text sectio
 945        /// The final relative virtual address stored in the metadata is calculated when the metadata is serialized
 946        /// by adding the offset to the virtual address of the block start.
 947        /// </param>
 948        /// <remarks>
 949        /// Entries must be added in the same order as the corresponding field definitions.
 950        /// </remarks>
 951        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative.</exception>
 952        public void AddFieldRelativeVirtualAddress(FieldDefinitionHandle field, int offset)
 0953        {
 0954            if (offset < 0)
 0955            {
 0956                Throw.ArgumentOutOfRange(nameof(offset));
 957            }
 958
 0959            _fieldRvaTable.Add(new FieldRvaRow
 0960            {
 0961                Field = field.RowId,
 0962                Offset = offset
 0963            });
 0964        }
 965
 966        /// <summary>
 967        /// Adds a method definition.
 968        /// </summary>
 969        /// <param name="attributes"><see cref="MethodAttributes"/></param>
 970        /// <param name="implAttributes"><see cref="MethodImplAttributes"/></param>
 971        /// <param name="name">Method name/</param>
 972        /// <param name="signature">Method signature.</param>
 973        /// <param name="bodyOffset">
 974        /// Offset within the block in the PE image that stores method bodies (IL stream),
 975        /// or -1 if the method doesn't have a body.
 976        ///
 977        /// The final relative virtual address stored in the metadata is calculated when the metadata is serialized
 978        /// by adding the offset to the virtual address of the beginning of the block.
 979        /// </param>
 980        /// <param name="parameterList">
 981        /// If the method declares parameters in Params table the handle of the first one, otherwise the handle of the f
 982        /// If no parameters are declared in the module, <see cref="MetadataTokens.ParameterHandle(int)"/>(1).
 983        /// </param>
 984        /// <exception cref="ArgumentOutOfRangeException"><paramref name="bodyOffset"/> is less than -1.</exception>
 985        public MethodDefinitionHandle AddMethodDefinition(
 986            MethodAttributes attributes,
 987            MethodImplAttributes implAttributes,
 988            StringHandle name,
 989            BlobHandle signature,
 990            int bodyOffset,
 991            ParameterHandle parameterList)
 0992        {
 0993            if (bodyOffset < -1)
 0994            {
 0995                Throw.ArgumentOutOfRange(nameof(bodyOffset));
 996            }
 997
 0998            _methodDefTable.Add(new MethodRow
 0999            {
 01000                Flags = unchecked((ushort)attributes),
 01001                ImplFlags = unchecked((ushort)implAttributes),
 01002                Name = name,
 01003                Signature = signature,
 01004                BodyOffset = bodyOffset,
 01005                ParamList = parameterList.RowId
 01006            });
 1007
 01008            return MethodDefinitionHandle.FromRowId(_methodDefTable.Count);
 01009        }
 1010
 1011        /// <summary>
 1012        /// Adds import information to a method definition (P/Invoke).
 1013        /// </summary>
 1014        /// <param name="method">Method definition handle.</param>
 1015        /// <param name="attributes">Attributes.</param>
 1016        /// <param name="name">Unmanaged method name.</param>
 1017        /// <param name="module">Module containing the unmanaged method.</param>
 1018        /// <remarks>
 1019        /// Method imports must be added in the same order as the corresponding method definitions.
 1020        /// </remarks>
 1021        public void AddMethodImport(
 1022            MethodDefinitionHandle method,
 1023            MethodImportAttributes attributes,
 1024            StringHandle name,
 1025            ModuleReferenceHandle module)
 01026        {
 01027            _implMapTable.Add(new ImplMapRow
 01028            {
 01029                MemberForwarded = CodedIndex.MemberForwarded(method),
 01030                ImportName = name,
 01031                ImportScope = module.RowId,
 01032                MappingFlags = unchecked((ushort)attributes),
 01033            });
 01034        }
 1035
 1036        /// <summary>
 1037        /// Defines an implementation for a method declaration within a type.
 1038        /// </summary>
 1039        /// <param name="type">Type</param>
 1040        /// <param name="methodBody"><see cref="MethodDefinitionHandle"/> or <see cref="MemberReferenceHandle"/> which p
 1041        /// <param name="methodDeclaration"><see cref="MethodDefinitionHandle"/> or <see cref="MemberReferenceHandle"/> 
 1042        /// <remarks>
 1043        /// Method implementations must be added in the same order as the corresponding type definitions.
 1044        /// </remarks>
 1045        /// <exception cref="ArgumentException"><paramref name="methodBody"/> or <paramref name="methodDeclaration"/> do
 1046        public MethodImplementationHandle AddMethodImplementation(
 1047            TypeDefinitionHandle type,
 1048            EntityHandle methodBody,
 1049            EntityHandle methodDeclaration)
 01050        {
 01051            _methodImplTable.Add(new MethodImplRow
 01052            {
 01053                Class = type.RowId,
 01054                MethodBody = CodedIndex.MethodDefOrRef(methodBody),
 01055                MethodDecl = CodedIndex.MethodDefOrRef(methodDeclaration)
 01056            });
 1057
 01058            return MethodImplementationHandle.FromRowId(_methodImplTable.Count);
 01059        }
 1060
 1061        /// <summary>
 1062        /// Adds a MemberRef table row.
 1063        /// </summary>
 1064        /// <param name="parent">Containing entity:
 1065        /// <see cref="TypeDefinitionHandle"/>,
 1066        /// <see cref="TypeReferenceHandle"/>,
 1067        /// <see cref="ModuleReferenceHandle"/>,
 1068        /// <see cref="MethodDefinitionHandle"/>, or
 1069        /// <see cref="TypeSpecificationHandle"/>.
 1070        /// </param>
 1071        /// <param name="name">Member name.</param>
 1072        /// <param name="signature">Member signature.</param>
 1073        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 1074        public MemberReferenceHandle AddMemberReference(
 1075            EntityHandle parent,
 1076            StringHandle name,
 1077            BlobHandle signature)
 01078        {
 01079            _memberRefTable.Add(new MemberRefRow
 01080            {
 01081                Class = CodedIndex.MemberRefParent(parent),
 01082                Name = name,
 01083                Signature = signature
 01084            });
 1085
 01086            return MemberReferenceHandle.FromRowId(_memberRefTable.Count);
 01087        }
 1088
 1089        /// <summary>
 1090        /// Adds a manifest resource.
 1091        /// </summary>
 1092        /// <param name="attributes">Attributes</param>
 1093        /// <param name="name">Resource name</param>
 1094        /// <param name="implementation"><see cref="AssemblyFileHandle"/>, <see cref="AssemblyReferenceHandle"/>, or nil
 1095        /// <param name="offset">Specifies the byte offset within the referenced file at which this resource record begi
 1096        /// <exception cref="ArgumentException"><paramref name="implementation"/> doesn't have the expected handle kind.
 1097        public ManifestResourceHandle AddManifestResource(
 1098            ManifestResourceAttributes attributes,
 1099            StringHandle name,
 1100            EntityHandle implementation,
 1101            uint offset)
 01102        {
 01103            _manifestResourceTable.Add(new ManifestResourceRow
 01104            {
 01105                Flags = unchecked((uint)attributes),
 01106                Name = name,
 01107                Implementation = implementation.IsNil ? 0 : CodedIndex.Implementation(implementation),
 01108                Offset = offset
 01109            });
 1110
 01111            return ManifestResourceHandle.FromRowId(_manifestResourceTable.Count);
 01112        }
 1113
 1114        public AssemblyFileHandle AddAssemblyFile(
 1115            StringHandle name,
 1116            BlobHandle hashValue,
 1117            bool containsMetadata)
 01118        {
 01119            _fileTable.Add(new FileTableRow
 01120            {
 01121                FileName = name,
 01122                Flags = containsMetadata ? 0u : 1u,
 01123                HashValue = hashValue
 01124            });
 1125
 01126            return AssemblyFileHandle.FromRowId(_fileTable.Count);
 01127        }
 1128
 1129        /// <summary>
 1130        /// Adds an exported type.
 1131        /// </summary>
 1132        /// <param name="attributes">Attributes</param>
 1133        /// <param name="namespace">Namespace</param>
 1134        /// <param name="name">Type name</param>
 1135        /// <param name="implementation"><see cref="AssemblyFileHandle"/>, <see cref="ExportedTypeHandle"/> or <see cref
 1136        /// <param name="typeDefinitionId">Type definition id</param>
 1137        /// <exception cref="ArgumentException"><paramref name="implementation"/> doesn't have the expected handle kind.
 1138        public ExportedTypeHandle AddExportedType(
 1139            TypeAttributes attributes,
 1140            StringHandle @namespace,
 1141            StringHandle name,
 1142            EntityHandle implementation,
 1143            int typeDefinitionId)
 01144        {
 01145            _exportedTypeTable.Add(new ExportedTypeRow
 01146            {
 01147                Flags = unchecked((uint)attributes),
 01148                Implementation = CodedIndex.Implementation(implementation),
 01149                TypeNamespace = @namespace,
 01150                TypeName = name,
 01151                TypeDefId = typeDefinitionId
 01152            });
 1153
 01154            return ExportedTypeHandle.FromRowId(_exportedTypeTable.Count);
 01155        }
 1156
 1157        /// <summary>
 1158        /// Adds declarative security attribute to a type, method or an assembly.
 1159        /// </summary>
 1160        /// <param name="parent"><see cref="TypeDefinitionHandle"/>, <see cref="MethodDefinitionHandle"/>, or <see cref=
 1161        /// <param name="action">Security action</param>
 1162        /// <param name="permissionSet">Permission set blob.</param>
 1163        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 1164        /// <remarks>
 1165        /// Entries may be added in any order. The table is automatically sorted when serialized.
 1166        /// </remarks>
 1167        public DeclarativeSecurityAttributeHandle AddDeclarativeSecurityAttribute(
 1168            EntityHandle parent,
 1169            DeclarativeSecurityAction action,
 1170            BlobHandle permissionSet)
 01171        {
 01172            int parentCodedIndex = CodedIndex.HasDeclSecurity(parent);
 1173
 1174            // the table is required to be sorted by Parent:
 01175            _declSecurityTableNeedsSorting |= parentCodedIndex < _declSecurityTableLastParent;
 01176            _declSecurityTableLastParent = parentCodedIndex;
 1177
 01178            _declSecurityTable.Add(new DeclSecurityRow
 01179            {
 01180                Parent = parentCodedIndex,
 01181                Action = unchecked((ushort)action),
 01182                PermissionSet = permissionSet
 01183            });
 1184
 01185            return DeclarativeSecurityAttributeHandle.FromRowId(_declSecurityTable.Count);
 01186        }
 1187
 1188        public void AddEncLogEntry(EntityHandle entity, EditAndContinueOperation code)
 01189        {
 01190            _encLogTable.Add(new EncLogRow
 01191            {
 01192                Token = entity.Token,
 01193                FuncCode = unchecked((byte)code)
 01194            });
 01195        }
 1196
 1197        public void AddEncMapEntry(EntityHandle entity)
 01198        {
 01199            _encMapTable.Add(new EncMapRow
 01200            {
 01201                Token = entity.Token
 01202            });
 01203        }
 1204
 1205        /// <summary>
 1206        /// Add document debug information.
 1207        /// </summary>
 1208        /// <param name="name">
 1209        /// Document Name blob.
 1210        /// </param>
 1211        /// <param name="hashAlgorithm">
 1212        /// GUID of the hash algorithm used to calculate the value of <paramref name="hash"/>.
 1213        /// </param>
 1214        /// <param name="hash">
 1215        /// The hash of the document content.
 1216        /// </param>
 1217        /// <param name="language">
 1218        /// GUID of the language.
 1219        /// </param>
 1220        /// See https://github.com/dotnet/runtime/blob/main/src/libraries/System.Reflection.Metadata/specs/PortablePdb-M
 1221        public DocumentHandle AddDocument(BlobHandle name, GuidHandle hashAlgorithm, BlobHandle hash, GuidHandle languag
 01222        {
 01223            _documentTable.Add(new DocumentRow
 01224            {
 01225                Name = name,
 01226                HashAlgorithm = hashAlgorithm,
 01227                Hash = hash,
 01228                Language = language
 01229            });
 1230
 01231            return DocumentHandle.FromRowId(_documentTable.Count);
 01232        }
 1233
 1234        /// <summary>
 1235        /// Add method debug information.
 1236        /// </summary>
 1237        /// <param name="document">
 1238        /// The handle of a single document containing all sequence points of the method, or nil if the method doesn't h
 1239        /// </param>
 1240        /// <param name="sequencePoints">
 1241        /// Sequence Points blob, or nil if the method doesn't have sequence points.
 1242        /// See https://github.com/dotnet/runtime/blob/main/src/libraries/System.Reflection.Metadata/specs/PortablePdb-M
 1243        /// </param>
 1244        public MethodDebugInformationHandle AddMethodDebugInformation(DocumentHandle document, BlobHandle sequencePoints
 01245        {
 01246            _methodDebugInformationTable.Add(new MethodDebugInformationRow
 01247            {
 01248                Document = document.RowId,
 01249                SequencePoints = sequencePoints
 01250            });
 1251
 01252            return MethodDebugInformationHandle.FromRowId(_methodDebugInformationTable.Count);
 01253        }
 1254
 1255        /// <summary>
 1256        /// Add local scope debug information.
 1257        /// </summary>
 1258        /// <param name="method">The containing method.</param>
 1259        /// <param name="importScope">Handle of the associated import scope.</param>
 1260        /// <param name="variableList">
 1261        /// If the scope declares variables the handle of the first one, otherwise the handle of the first variable decl
 1262        /// If no scope defines any variables, <see cref="MetadataTokens.LocalVariableHandle(int)"/>(1).
 1263        /// </param>
 1264        /// <param name="constantList">
 1265        /// If the scope declares constants the handle of the first one, otherwise the handle of the first constant decl
 1266        /// If no scope defines any constants, <see cref="MetadataTokens.LocalConstantHandle(int)"/>(1).
 1267        /// </param>
 1268        /// <param name="startOffset">Offset of the first instruction covered by the scope.</param>
 1269        /// <param name="length">The length (in bytes) of the scope.</param>
 1270        /// <remarks>
 1271        /// Local scopes should be added in the same order as the corresponding method definition.
 1272        /// Within a method they should be ordered by ascending <paramref name="startOffset"/> and then by descending <p
 1273        /// </remarks>
 1274        public LocalScopeHandle AddLocalScope(MethodDefinitionHandle method, ImportScopeHandle importScope, LocalVariabl
 01275        {
 01276            _localScopeTable.Add(new LocalScopeRow
 01277            {
 01278                Method = method.RowId,
 01279                ImportScope = importScope.RowId,
 01280                VariableList = variableList.RowId,
 01281                ConstantList = constantList.RowId,
 01282                StartOffset = startOffset,
 01283                Length = length
 01284            });
 1285
 01286            return LocalScopeHandle.FromRowId(_localScopeTable.Count);
 01287        }
 1288
 1289        /// <summary>
 1290        /// Add local variable debug information.
 1291        /// </summary>
 1292        /// <param name="attributes"><see cref="LocalVariableAttributes"/></param>
 1293        /// <param name="index">Local variable index in the local signature (zero-based).</param>
 1294        /// <param name="name">Name of the variable.</param>
 1295        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is greater than <see cref="ushort.Max
 1296        public LocalVariableHandle AddLocalVariable(LocalVariableAttributes attributes, int index, StringHandle name)
 01297        {
 01298            if (unchecked((uint)index) > ushort.MaxValue)
 01299            {
 01300                Throw.ArgumentOutOfRange(nameof(index));
 1301            }
 1302
 01303            _localVariableTable.Add(new LocalVariableRow
 01304            {
 01305                Attributes = unchecked((ushort)attributes),
 01306                Index = (ushort)index,
 01307                Name = name
 01308            });
 1309
 01310            return LocalVariableHandle.FromRowId(_localVariableTable.Count);
 01311        }
 1312
 1313        /// <summary>
 1314        /// Add local constant debug information.
 1315        /// </summary>
 1316        /// <param name="name">Name of the variable.</param>
 1317        /// <param name="signature">
 1318        /// LocalConstantSig blob, see https://github.com/dotnet/runtime/blob/main/src/libraries/System.Reflection.Metad
 1319        /// </param>
 1320        public LocalConstantHandle AddLocalConstant(StringHandle name, BlobHandle signature)
 01321        {
 01322            _localConstantTable.Add(new LocalConstantRow
 01323            {
 01324                Name = name,
 01325                Signature = signature
 01326            });
 1327
 01328            return LocalConstantHandle.FromRowId(_localConstantTable.Count);
 01329        }
 1330
 1331        /// <summary>
 1332        /// Add local scope debug information.
 1333        /// </summary>
 1334        /// <param name="parentScope">Parent scope handle.</param>
 1335        /// <param name="imports">
 1336        /// Imports blob, see https://github.com/dotnet/runtime/blob/main/src/libraries/System.Reflection.Metadata/specs
 1337        /// </param>
 1338        public ImportScopeHandle AddImportScope(ImportScopeHandle parentScope, BlobHandle imports)
 01339        {
 01340            _importScopeTable.Add(new ImportScopeRow
 01341            {
 01342                Parent = parentScope.RowId,
 01343                Imports = imports
 01344            });
 1345
 01346            return ImportScopeHandle.FromRowId(_importScopeTable.Count);
 01347        }
 1348
 1349        /// <summary>
 1350        /// Add state machine method debug information.
 1351        /// </summary>
 1352        /// <param name="moveNextMethod">Handle of the MoveNext method of the state machine (the compiler-generated meth
 1353        /// <param name="kickoffMethod">Handle of the kickoff method (the user defined iterator/async method)</param>
 1354        /// <remarks>
 1355        /// Entries should be added in the same order as the corresponding MoveNext method definitions.
 1356        /// </remarks>
 1357        public void AddStateMachineMethod(MethodDefinitionHandle moveNextMethod, MethodDefinitionHandle kickoffMethod)
 01358        {
 01359            _stateMachineMethodTable.Add(new StateMachineMethodRow
 01360            {
 01361                MoveNextMethod = moveNextMethod.RowId,
 01362                KickoffMethod = kickoffMethod.RowId
 01363            });
 01364        }
 1365
 1366        /// <summary>
 1367        /// Add custom debug information.
 1368        /// </summary>
 1369        /// <param name="parent">
 1370        /// An entity to attach the debug information to:
 1371        /// <see cref="MethodDefinitionHandle"/>,
 1372        /// <see cref="FieldDefinitionHandle"/>,
 1373        /// <see cref="TypeReferenceHandle"/>,
 1374        /// <see cref="TypeDefinitionHandle"/>,
 1375        /// <see cref="ParameterHandle"/>,
 1376        /// <see cref="InterfaceImplementationHandle"/>,
 1377        /// <see cref="MemberReferenceHandle"/>,
 1378        /// <see cref="ModuleDefinitionHandle"/>,
 1379        /// <see cref="DeclarativeSecurityAttributeHandle"/>,
 1380        /// <see cref="PropertyDefinitionHandle"/>,
 1381        /// <see cref="EventDefinitionHandle"/>,
 1382        /// <see cref="StandaloneSignatureHandle"/>,
 1383        /// <see cref="ModuleReferenceHandle"/>,
 1384        /// <see cref="TypeSpecificationHandle"/>,
 1385        /// <see cref="AssemblyDefinitionHandle"/>,
 1386        /// <see cref="AssemblyReferenceHandle"/>,
 1387        /// <see cref="AssemblyFileHandle"/>,
 1388        /// <see cref="ExportedTypeHandle"/>,
 1389        /// <see cref="ManifestResourceHandle"/>,
 1390        /// <see cref="GenericParameterHandle"/>,
 1391        /// <see cref="GenericParameterConstraintHandle"/>,
 1392        /// <see cref="MethodSpecificationHandle"/>,
 1393        /// <see cref="DocumentHandle"/>,
 1394        /// <see cref="LocalScopeHandle"/>,
 1395        /// <see cref="LocalVariableHandle"/>,
 1396        /// <see cref="LocalConstantHandle"/> or
 1397        /// <see cref="ImportScopeHandle"/>.
 1398        /// </param>
 1399        /// <param name="kind">Information kind. Determines the structure of the <paramref name="value"/> blob.</param>
 1400        /// <param name="value">Custom debug information blob.</param>
 1401        /// <exception cref="ArgumentException"><paramref name="parent"/> doesn't have the expected handle kind.</except
 1402        /// <remarks>
 1403        /// Entries may be added in any order. The table is automatically sorted when serialized.
 1404        /// </remarks>
 1405        public CustomDebugInformationHandle AddCustomDebugInformation(EntityHandle parent, GuidHandle kind, BlobHandle v
 01406        {
 01407            _customDebugInformationTable.Add(new CustomDebugInformationRow
 01408            {
 01409                Parent = CodedIndex.HasCustomDebugInformation(parent),
 01410                Kind = kind,
 01411                Value = value
 01412            });
 1413
 01414            return CustomDebugInformationHandle.FromRowId(_customDebugInformationTable.Count);
 01415        }
 1416
 1417        #endregion
 1418
 1419        #region Validation
 1420
 1421        internal void ValidateOrder()
 01422        {
 1423            // Certain tables are required to be sorted by a primary key, as follows:
 1424            //
 1425            // Table                    Keys                                Auto-ordered
 1426            // --------------------------------------------------------------------------
 1427            // ClassLayout              Parent                              No*
 1428            // Constant                 Parent                              Yes
 1429            // CustomAttribute          Parent                              Yes
 1430            // DeclSecurity             Parent                              Yes
 1431            // FieldLayout              Field                               No*
 1432            // FieldMarshal             Parent                              Yes
 1433            // FieldRVA                 Field                               No*
 1434            // GenericParam             Owner, Number                       No**
 1435            // GenericParamConstraint   Owner                               No**
 1436            // ImplMap                  MemberForwarded                     No*
 1437            // InterfaceImpl            Class                               No**
 1438            // MethodImpl               Class                               No*
 1439            // MethodSemantics          Association                         Yes
 1440            // NestedClass              NestedClass                         No*
 1441            // LocalScope               Method, StartOffset, Length (desc)  No**
 1442            // StateMachineMethod       MoveNextMethod                      No*
 1443            // CustomDebugInformation   Parent                              Yes
 1444            //
 1445            // Tables of entities that can't be referenced from other tables or blobs
 1446            // are automatically ordered during serialization and thus don't require validation.
 1447            //
 1448            // * We could potentially auto-order these. These tables are adding extra (optional)
 1449            // information to a primary entity (TypeDef, FiledDef, etc.) and are thus easily emitted
 1450            // in the same order as the parent entity. Hence they would usually be ordered already and
 1451            // it would be extra overhead to order them. Let's just required them ordered.
 1452            //
 1453            // ** We can't easily automatically order these since they represent entities that can be referenced
 1454            // by other tables/blobs (e.g. CustomAttribute and CustomDebugInformation). Ordering these tables
 1455            // would require updating all references.
 1456
 01457            ValidateClassLayoutTable();
 01458            ValidateFieldLayoutTable();
 01459            ValidateFieldRvaTable();
 01460            ValidateGenericParamTable();
 01461            ValidateGenericParamConstaintTable();
 01462            ValidateImplMapTable();
 01463            ValidateInterfaceImplTable();
 01464            ValidateMethodImplTable();
 01465            ValidateNestedClassTable();
 01466            ValidateLocalScopeTable();
 01467            ValidateStateMachineMethodTable();
 01468        }
 1469
 1470        private void ValidateClassLayoutTable()
 01471        {
 01472            for (int i = 1; i < _classLayoutTable.Count; i++)
 01473            {
 01474                if (_classLayoutTable[i - 1].Parent >= _classLayoutTable[i].Parent)
 01475                {
 01476                    Throw.InvalidOperation_TableNotSorted(TableIndex.ClassLayout);
 1477                }
 01478            }
 01479        }
 1480
 1481        private void ValidateFieldLayoutTable()
 01482        {
 01483            for (int i = 1; i < _fieldLayoutTable.Count; i++)
 01484            {
 01485                if (_fieldLayoutTable[i - 1].Field >= _fieldLayoutTable[i].Field)
 01486                {
 01487                    Throw.InvalidOperation_TableNotSorted(TableIndex.FieldLayout);
 1488                }
 01489            }
 01490        }
 1491
 1492        private void ValidateFieldRvaTable()
 01493        {
 01494            for (int i = 1; i < _fieldRvaTable.Count; i++)
 01495            {
 1496                // Spec: each row in the FieldRVA table is an extension to exactly one row in the Field table
 01497                if (_fieldRvaTable[i - 1].Field >= _fieldRvaTable[i].Field)
 01498                {
 01499                    Throw.InvalidOperation_TableNotSorted(TableIndex.FieldRva);
 1500                }
 01501            }
 01502        }
 1503
 1504        private void ValidateGenericParamTable()
 01505        {
 01506            if (_genericParamTable.Count == 0)
 01507            {
 01508                return;
 1509            }
 1510
 01511            GenericParamRow current, previous = _genericParamTable[0];
 01512            for (int i = 1; i < _genericParamTable.Count; i++, previous = current)
 01513            {
 01514                current = _genericParamTable[i];
 1515
 01516                if (current.Owner > previous.Owner)
 01517                {
 01518                    continue;
 1519                }
 1520
 01521                if (previous.Owner == current.Owner && current.Number > previous.Number)
 01522                {
 01523                    continue;
 1524                }
 1525
 01526                Throw.InvalidOperation_TableNotSorted(TableIndex.GenericParam);
 1527            }
 01528        }
 1529
 1530        private void ValidateGenericParamConstaintTable()
 01531        {
 01532            for (int i = 1; i < _genericParamConstraintTable.Count; i++)
 01533            {
 01534                if (_genericParamConstraintTable[i - 1].Owner > _genericParamConstraintTable[i].Owner)
 01535                {
 01536                    Throw.InvalidOperation_TableNotSorted(TableIndex.GenericParamConstraint);
 1537                }
 01538            }
 01539        }
 1540
 1541        private void ValidateImplMapTable()
 01542        {
 01543            for (int i = 1; i < _implMapTable.Count; i++)
 01544            {
 01545                if (_implMapTable[i - 1].MemberForwarded >= _implMapTable[i].MemberForwarded)
 01546                {
 01547                    Throw.InvalidOperation_TableNotSorted(TableIndex.ImplMap);
 1548                }
 01549            }
 01550        }
 1551
 1552        private void ValidateInterfaceImplTable()
 01553        {
 01554            for (int i = 1; i < _interfaceImplTable.Count; i++)
 01555            {
 01556                if (_interfaceImplTable[i - 1].Class > _interfaceImplTable[i].Class)
 01557                {
 01558                    Throw.InvalidOperation_TableNotSorted(TableIndex.InterfaceImpl);
 1559                }
 01560            }
 01561        }
 1562
 1563        private void ValidateMethodImplTable()
 01564        {
 01565            for (int i = 1; i < _methodImplTable.Count; i++)
 01566            {
 01567                if (_methodImplTable[i - 1].Class > _methodImplTable[i].Class)
 01568                {
 01569                    Throw.InvalidOperation_TableNotSorted(TableIndex.MethodImpl);
 1570                }
 01571            }
 01572        }
 1573
 1574        private void ValidateNestedClassTable()
 01575        {
 01576            for (int i = 1; i < _nestedClassTable.Count; i++)
 01577            {
 01578                if (_nestedClassTable[i - 1].NestedClass >= _nestedClassTable[i].NestedClass)
 01579                {
 01580                    Throw.InvalidOperation_TableNotSorted(TableIndex.NestedClass);
 1581                }
 01582            }
 01583        }
 1584
 1585        private void ValidateLocalScopeTable()
 01586        {
 01587            if (_localScopeTable.Count == 0)
 01588            {
 01589                return;
 1590            }
 1591
 1592            // Spec: The table is required to be sorted first by Method in ascending order,
 1593            // then by StartOffset in ascending order, then by Length in descending order.
 01594            LocalScopeRow current, previous = _localScopeTable[0];
 01595            for (int i = 1; i < _localScopeTable.Count; i++, previous = current)
 01596            {
 01597                current = _localScopeTable[i];
 1598
 01599                if (current.Method > previous.Method)
 01600                {
 01601                    continue;
 1602                }
 1603
 01604                if (current.Method == previous.Method)
 01605                {
 01606                    if (current.StartOffset > previous.StartOffset)
 01607                    {
 01608                        continue;
 1609                    }
 1610
 01611                    if (current.StartOffset == previous.StartOffset && previous.Length >= current.Length)
 01612                    {
 01613                        continue;
 1614                    }
 01615                }
 1616
 01617                Throw.InvalidOperation_TableNotSorted(TableIndex.LocalScope);
 1618            }
 01619        }
 1620
 1621        private void ValidateStateMachineMethodTable()
 01622        {
 01623            for (int i = 1; i < _stateMachineMethodTable.Count; i++)
 01624            {
 01625                if (_stateMachineMethodTable[i - 1].MoveNextMethod >= _stateMachineMethodTable[i].MoveNextMethod)
 01626                {
 01627                    Throw.InvalidOperation_TableNotSorted(TableIndex.StateMachineMethod);
 1628                }
 01629            }
 01630        }
 1631
 1632        #endregion
 1633
 1634        #region Serialization
 1635
 1636        internal void SerializeMetadataTables(
 1637            BlobBuilder writer,
 1638            MetadataSizes metadataSizes,
 1639            ImmutableArray<int> stringMap,
 1640            int methodBodyStreamRva,
 1641            int mappedFieldDataStreamRva)
 01642        {
 01643            int startPosition = writer.Count;
 1644
 01645            SerializeTablesHeader(writer, metadataSizes);
 1646
 01647            if (metadataSizes.IsPresent(TableIndex.Module))
 01648            {
 01649                SerializeModuleTable(writer, stringMap, metadataSizes);
 01650            }
 1651
 01652            if (metadataSizes.IsPresent(TableIndex.TypeRef))
 01653            {
 01654                SerializeTypeRefTable(writer, stringMap, metadataSizes);
 01655            }
 1656
 01657            if (metadataSizes.IsPresent(TableIndex.TypeDef))
 01658            {
 01659                SerializeTypeDefTable(writer, stringMap, metadataSizes);
 01660            }
 1661
 01662            if (metadataSizes.IsPresent(TableIndex.Field))
 01663            {
 01664                SerializeFieldTable(writer, stringMap, metadataSizes);
 01665            }
 1666
 01667            if (metadataSizes.IsPresent(TableIndex.MethodDef))
 01668            {
 01669                SerializeMethodDefTable(writer, stringMap, metadataSizes, methodBodyStreamRva);
 01670            }
 1671
 01672            if (metadataSizes.IsPresent(TableIndex.Param))
 01673            {
 01674                SerializeParamTable(writer, stringMap, metadataSizes);
 01675            }
 1676
 01677            if (metadataSizes.IsPresent(TableIndex.InterfaceImpl))
 01678            {
 01679                SerializeInterfaceImplTable(writer, metadataSizes);
 01680            }
 1681
 01682            if (metadataSizes.IsPresent(TableIndex.MemberRef))
 01683            {
 01684                SerializeMemberRefTable(writer, stringMap, metadataSizes);
 01685            }
 1686
 01687            if (metadataSizes.IsPresent(TableIndex.Constant))
 01688            {
 01689                SerializeConstantTable(writer, metadataSizes);
 01690            }
 1691
 01692            if (metadataSizes.IsPresent(TableIndex.CustomAttribute))
 01693            {
 01694                SerializeCustomAttributeTable(writer, metadataSizes);
 01695            }
 1696
 01697            if (metadataSizes.IsPresent(TableIndex.FieldMarshal))
 01698            {
 01699                SerializeFieldMarshalTable(writer, metadataSizes);
 01700            }
 1701
 01702            if (metadataSizes.IsPresent(TableIndex.DeclSecurity))
 01703            {
 01704                SerializeDeclSecurityTable(writer, metadataSizes);
 01705            }
 1706
 01707            if (metadataSizes.IsPresent(TableIndex.ClassLayout))
 01708            {
 01709                SerializeClassLayoutTable(writer, metadataSizes);
 01710            }
 1711
 01712            if (metadataSizes.IsPresent(TableIndex.FieldLayout))
 01713            {
 01714                SerializeFieldLayoutTable(writer, metadataSizes);
 01715            }
 1716
 01717            if (metadataSizes.IsPresent(TableIndex.StandAloneSig))
 01718            {
 01719                SerializeStandAloneSigTable(writer, metadataSizes);
 01720            }
 1721
 01722            if (metadataSizes.IsPresent(TableIndex.EventMap))
 01723            {
 01724                SerializeEventMapTable(writer, metadataSizes);
 01725            }
 1726
 01727            if (metadataSizes.IsPresent(TableIndex.Event))
 01728            {
 01729                SerializeEventTable(writer, stringMap, metadataSizes);
 01730            }
 1731
 01732            if (metadataSizes.IsPresent(TableIndex.PropertyMap))
 01733            {
 01734                SerializePropertyMapTable(writer, metadataSizes);
 01735            }
 1736
 01737            if (metadataSizes.IsPresent(TableIndex.Property))
 01738            {
 01739                SerializePropertyTable(writer, stringMap, metadataSizes);
 01740            }
 1741
 01742            if (metadataSizes.IsPresent(TableIndex.MethodSemantics))
 01743            {
 01744                SerializeMethodSemanticsTable(writer, metadataSizes);
 01745            }
 1746
 01747            if (metadataSizes.IsPresent(TableIndex.MethodImpl))
 01748            {
 01749                SerializeMethodImplTable(writer, metadataSizes);
 01750            }
 1751
 01752            if (metadataSizes.IsPresent(TableIndex.ModuleRef))
 01753            {
 01754                SerializeModuleRefTable(writer, stringMap, metadataSizes);
 01755            }
 1756
 01757            if (metadataSizes.IsPresent(TableIndex.TypeSpec))
 01758            {
 01759                SerializeTypeSpecTable(writer, metadataSizes);
 01760            }
 1761
 01762            if (metadataSizes.IsPresent(TableIndex.ImplMap))
 01763            {
 01764                SerializeImplMapTable(writer, stringMap, metadataSizes);
 01765            }
 1766
 01767            if (metadataSizes.IsPresent(TableIndex.FieldRva))
 01768            {
 01769                SerializeFieldRvaTable(writer, metadataSizes, mappedFieldDataStreamRva);
 01770            }
 1771
 01772            if (metadataSizes.IsPresent(TableIndex.EncLog))
 01773            {
 01774                SerializeEncLogTable(writer);
 01775            }
 1776
 01777            if (metadataSizes.IsPresent(TableIndex.EncMap))
 01778            {
 01779                SerializeEncMapTable(writer);
 01780            }
 1781
 01782            if (metadataSizes.IsPresent(TableIndex.Assembly))
 01783            {
 01784                SerializeAssemblyTable(writer, stringMap, metadataSizes);
 01785            }
 1786
 01787            if (metadataSizes.IsPresent(TableIndex.AssemblyRef))
 01788            {
 01789                SerializeAssemblyRefTable(writer, stringMap, metadataSizes);
 01790            }
 1791
 01792            if (metadataSizes.IsPresent(TableIndex.File))
 01793            {
 01794                SerializeFileTable(writer, stringMap, metadataSizes);
 01795            }
 1796
 01797            if (metadataSizes.IsPresent(TableIndex.ExportedType))
 01798            {
 01799                SerializeExportedTypeTable(writer, stringMap, metadataSizes);
 01800            }
 1801
 01802            if (metadataSizes.IsPresent(TableIndex.ManifestResource))
 01803            {
 01804                SerializeManifestResourceTable(writer, stringMap, metadataSizes);
 01805            }
 1806
 01807            if (metadataSizes.IsPresent(TableIndex.NestedClass))
 01808            {
 01809                SerializeNestedClassTable(writer, metadataSizes);
 01810            }
 1811
 01812            if (metadataSizes.IsPresent(TableIndex.GenericParam))
 01813            {
 01814                SerializeGenericParamTable(writer, stringMap, metadataSizes);
 01815            }
 1816
 01817            if (metadataSizes.IsPresent(TableIndex.MethodSpec))
 01818            {
 01819                SerializeMethodSpecTable(writer, metadataSizes);
 01820            }
 1821
 01822            if (metadataSizes.IsPresent(TableIndex.GenericParamConstraint))
 01823            {
 01824                SerializeGenericParamConstraintTable(writer, metadataSizes);
 01825            }
 1826
 1827            // debug tables
 01828            if (metadataSizes.IsPresent(TableIndex.Document))
 01829            {
 01830                SerializeDocumentTable(writer, metadataSizes);
 01831            }
 1832
 01833            if (metadataSizes.IsPresent(TableIndex.MethodDebugInformation))
 01834            {
 01835                SerializeMethodDebugInformationTable(writer, metadataSizes);
 01836            }
 1837
 01838            if (metadataSizes.IsPresent(TableIndex.LocalScope))
 01839            {
 01840                SerializeLocalScopeTable(writer, metadataSizes);
 01841            }
 1842
 01843            if (metadataSizes.IsPresent(TableIndex.LocalVariable))
 01844            {
 01845                SerializeLocalVariableTable(writer, stringMap, metadataSizes);
 01846            }
 1847
 01848            if (metadataSizes.IsPresent(TableIndex.LocalConstant))
 01849            {
 01850                SerializeLocalConstantTable(writer, stringMap, metadataSizes);
 01851            }
 1852
 01853            if (metadataSizes.IsPresent(TableIndex.ImportScope))
 01854            {
 01855                SerializeImportScopeTable(writer, metadataSizes);
 01856            }
 1857
 01858            if (metadataSizes.IsPresent(TableIndex.StateMachineMethod))
 01859            {
 01860                SerializeStateMachineMethodTable(writer, metadataSizes);
 01861            }
 1862
 01863            if (metadataSizes.IsPresent(TableIndex.CustomDebugInformation))
 01864            {
 01865                SerializeCustomDebugInformationTable(writer, metadataSizes);
 01866            }
 1867
 01868            writer.WriteByte(0);
 01869            writer.Align(4);
 1870
 01871            int endPosition = writer.Count;
 01872            Debug.Assert(metadataSizes.MetadataTableStreamSize == endPosition - startPosition);
 01873        }
 1874
 1875        private static void SerializeTablesHeader(BlobBuilder writer, MetadataSizes metadataSizes)
 01876        {
 01877            int startPosition = writer.Count;
 1878
 01879            HeapSizeFlag heapSizes = 0;
 01880            if (!metadataSizes.StringReferenceIsSmall)
 01881            {
 01882                heapSizes |= HeapSizeFlag.StringHeapLarge;
 01883            }
 1884
 01885            if (!metadataSizes.GuidReferenceIsSmall)
 01886            {
 01887                heapSizes |= HeapSizeFlag.GuidHeapLarge;
 01888            }
 1889
 01890            if (!metadataSizes.BlobReferenceIsSmall)
 01891            {
 01892                heapSizes |= HeapSizeFlag.BlobHeapLarge;
 01893            }
 1894
 01895            if (metadataSizes.IsEncDelta)
 01896            {
 01897                heapSizes |= HeapSizeFlag.EncDeltas | HeapSizeFlag.DeletedMarks;
 01898            }
 1899
 1900            // Custom Attribute table is not sorted in delta metadata:
 01901            ulong sortedTables =
 01902                metadataSizes.IsEncDelta ? MetadataSizes.SortedTypeSystemTables & ~(1UL << (int)TableIndex.CustomAttribu
 01903                metadataSizes.IsStandaloneDebugMetadata ? 0 :
 01904                MetadataSizes.SortedTypeSystemTables;
 1905
 1906            // Consider filtering out type system tables that are not present:
 01907            sortedTables |= metadataSizes.PresentTablesMask & MetadataSizes.SortedDebugTables;
 1908
 01909            writer.WriteUInt32(0); // reserved
 01910            writer.WriteByte(MetadataFormatMajorVersion);
 01911            writer.WriteByte(MetadataFormatMinorVersion);
 01912            writer.WriteByte((byte)heapSizes);
 01913            writer.WriteByte(1); // reserved
 01914            writer.WriteUInt64(metadataSizes.PresentTablesMask);
 01915            writer.WriteUInt64(sortedTables);
 01916            MetadataWriterUtilities.SerializeRowCounts(writer, metadataSizes.RowCounts);
 1917
 01918            int endPosition = writer.Count;
 01919            Debug.Assert(metadataSizes.CalculateTableStreamHeaderSize() == endPosition - startPosition);
 01920        }
 1921
 1922        // internal for testing
 1923        internal void SerializeModuleTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSize
 01924        {
 01925            if (_moduleRow.HasValue)
 01926            {
 01927                writer.WriteUInt16(_moduleRow.Value.Generation);
 01928                writer.WriteReference(SerializeHandle(stringMap, _moduleRow.Value.Name), metadataSizes.StringReferenceIs
 01929                writer.WriteReference(SerializeHandle(_moduleRow.Value.ModuleVersionId), metadataSizes.GuidReferenceIsSm
 01930                writer.WriteReference(SerializeHandle(_moduleRow.Value.EncId), metadataSizes.GuidReferenceIsSmall);
 01931                writer.WriteReference(SerializeHandle(_moduleRow.Value.EncBaseId), metadataSizes.GuidReferenceIsSmall);
 01932            }
 01933        }
 1934
 1935        private void SerializeEncLogTable(BlobBuilder writer)
 01936        {
 01937            foreach (EncLogRow encLog in _encLogTable)
 01938            {
 01939                writer.WriteInt32(encLog.Token);
 01940                writer.WriteUInt32(encLog.FuncCode);
 01941            }
 01942        }
 1943
 1944        private void SerializeEncMapTable(BlobBuilder writer)
 01945        {
 01946            foreach (EncMapRow encMap in _encMapTable)
 01947            {
 01948                writer.WriteInt32(encMap.Token);
 01949            }
 01950        }
 1951
 1952        private void SerializeTypeRefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSize
 01953        {
 01954            foreach (TypeRefRow typeRef in _typeRefTable)
 01955            {
 01956                writer.WriteReference(typeRef.ResolutionScope, metadataSizes.ResolutionScopeCodedIndexIsSmall);
 01957                writer.WriteReference(SerializeHandle(stringMap, typeRef.Name), metadataSizes.StringReferenceIsSmall);
 01958                writer.WriteReference(SerializeHandle(stringMap, typeRef.Namespace), metadataSizes.StringReferenceIsSmal
 01959            }
 01960        }
 1961
 1962        private void SerializeTypeDefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSize
 01963        {
 01964            foreach (TypeDefRow typeDef in _typeDefTable)
 01965            {
 01966                writer.WriteUInt32(typeDef.Flags);
 01967                writer.WriteReference(SerializeHandle(stringMap, typeDef.Name), metadataSizes.StringReferenceIsSmall);
 01968                writer.WriteReference(SerializeHandle(stringMap, typeDef.Namespace), metadataSizes.StringReferenceIsSmal
 01969                writer.WriteReference(typeDef.Extends, metadataSizes.TypeDefOrRefCodedIndexIsSmall);
 01970                writer.WriteReference(typeDef.FieldList, metadataSizes.FieldDefReferenceIsSmall);
 01971                writer.WriteReference(typeDef.MethodList, metadataSizes.MethodDefReferenceIsSmall);
 01972            }
 01973        }
 1974
 1975        private void SerializeFieldTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSizes)
 01976        {
 01977            foreach (FieldDefRow fieldDef in _fieldTable)
 01978            {
 01979                writer.WriteUInt16(fieldDef.Flags);
 01980                writer.WriteReference(SerializeHandle(stringMap, fieldDef.Name), metadataSizes.StringReferenceIsSmall);
 01981                writer.WriteReference(SerializeHandle(fieldDef.Signature), metadataSizes.BlobReferenceIsSmall);
 01982            }
 01983        }
 1984
 1985        private void SerializeMethodDefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSi
 01986        {
 01987            foreach (MethodRow method in _methodDefTable)
 01988            {
 01989                if (method.BodyOffset == -1)
 01990                {
 01991                    writer.WriteUInt32(0);
 01992                }
 1993                else
 01994                {
 01995                    writer.WriteInt32(methodBodyStreamRva + method.BodyOffset);
 01996                }
 1997
 01998                writer.WriteUInt16(method.ImplFlags);
 01999                writer.WriteUInt16(method.Flags);
 02000                writer.WriteReference(SerializeHandle(stringMap, method.Name), metadataSizes.StringReferenceIsSmall);
 02001                writer.WriteReference(SerializeHandle(method.Signature), metadataSizes.BlobReferenceIsSmall);
 02002                writer.WriteReference(method.ParamList, metadataSizes.ParameterReferenceIsSmall);
 02003            }
 02004        }
 2005
 2006        private void SerializeParamTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSizes)
 02007        {
 02008            foreach (ParamRow param in _paramTable)
 02009            {
 02010                writer.WriteUInt16(param.Flags);
 02011                writer.WriteUInt16(param.Sequence);
 02012                writer.WriteReference(SerializeHandle(stringMap, param.Name), metadataSizes.StringReferenceIsSmall);
 02013            }
 02014        }
 2015
 2016        private void SerializeInterfaceImplTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02017        {
 2018            // TODO (bug https://github.com/dotnet/roslyn/issues/3905):
 2019            // We should sort the table by Class and then by Interface.
 02020            foreach (InterfaceImplRow interfaceImpl in _interfaceImplTable)
 02021            {
 02022                writer.WriteReference(interfaceImpl.Class, metadataSizes.TypeDefReferenceIsSmall);
 02023                writer.WriteReference(interfaceImpl.Interface, metadataSizes.TypeDefOrRefCodedIndexIsSmall);
 02024            }
 02025        }
 2026
 2027        private void SerializeMemberRefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSi
 02028        {
 02029            foreach (MemberRefRow memberRef in _memberRefTable)
 02030            {
 02031                writer.WriteReference(memberRef.Class, metadataSizes.MemberRefParentCodedIndexIsSmall);
 02032                writer.WriteReference(SerializeHandle(stringMap, memberRef.Name), metadataSizes.StringReferenceIsSmall);
 02033                writer.WriteReference(SerializeHandle(memberRef.Signature), metadataSizes.BlobReferenceIsSmall);
 02034            }
 02035        }
 2036
 2037        private void SerializeConstantTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02038        {
 2039            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 02040            var ordered = _constantTableNeedsSorting ? _constantTable.OrderBy((x, y) => x.Parent - y.Parent) : _constant
 2041
 02042            foreach (ConstantRow constant in ordered)
 02043            {
 02044                writer.WriteByte(constant.Type);
 02045                writer.WriteByte(0);
 02046                writer.WriteReference(constant.Parent, metadataSizes.HasConstantCodedIndexIsSmall);
 02047                writer.WriteReference(SerializeHandle(constant.Value), metadataSizes.BlobReferenceIsSmall);
 02048            }
 02049        }
 2050
 2051        private void SerializeCustomAttributeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02052        {
 2053            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 2054            // OrderBy performs a stable sort, so multiple attributes with the same parent will be sorted in the order t
 2055            // Avoid sorting the table when emitting EnC delta. Deleted attributes are represented in the table as rows 
 2056            // Sorting the table would move them to the beginning of the table and break mapping specified in EncMap tab
 02057            var ordered = _customAttributeTableNeedsSorting && !metadataSizes.IsEncDelta ? _customAttributeTable.OrderBy
 2058
 02059            foreach (CustomAttributeRow customAttribute in ordered)
 02060            {
 02061                writer.WriteReference(customAttribute.Parent, metadataSizes.HasCustomAttributeCodedIndexIsSmall);
 02062                writer.WriteReference(customAttribute.Type, metadataSizes.CustomAttributeTypeCodedIndexIsSmall);
 02063                writer.WriteReference(SerializeHandle(customAttribute.Value), metadataSizes.BlobReferenceIsSmall);
 02064            }
 02065        }
 2066
 2067        private void SerializeFieldMarshalTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02068        {
 2069            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 02070            var ordered = _fieldMarshalTableNeedsSorting ? _fieldMarshalTable.OrderBy((x, y) => x.Parent - y.Parent) : _
 2071
 02072            foreach (FieldMarshalRow fieldMarshal in ordered)
 02073            {
 02074                writer.WriteReference(fieldMarshal.Parent, metadataSizes.HasFieldMarshalCodedIndexIsSmall);
 02075                writer.WriteReference(SerializeHandle(fieldMarshal.NativeType), metadataSizes.BlobReferenceIsSmall);
 02076            }
 02077        }
 2078
 2079        private void SerializeDeclSecurityTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02080        {
 2081            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 2082            // OrderBy performs a stable sort, so multiple attributes with the same parent will be sorted in the order t
 02083            var ordered = _declSecurityTableNeedsSorting ? _declSecurityTable.OrderBy((x, y) => x.Parent - y.Parent) : _
 2084
 02085            foreach (DeclSecurityRow declSecurity in ordered)
 02086            {
 02087                writer.WriteUInt16(declSecurity.Action);
 02088                writer.WriteReference(declSecurity.Parent, metadataSizes.DeclSecurityCodedIndexIsSmall);
 02089                writer.WriteReference(SerializeHandle(declSecurity.PermissionSet), metadataSizes.BlobReferenceIsSmall);
 02090            }
 02091        }
 2092
 2093        private void SerializeClassLayoutTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02094        {
 02095            foreach (ClassLayoutRow classLayout in _classLayoutTable)
 02096            {
 02097                writer.WriteUInt16(classLayout.PackingSize);
 02098                writer.WriteUInt32(classLayout.ClassSize);
 02099                writer.WriteReference(classLayout.Parent, metadataSizes.TypeDefReferenceIsSmall);
 02100            }
 02101        }
 2102
 2103        private void SerializeFieldLayoutTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02104        {
 02105            foreach (FieldLayoutRow fieldLayout in _fieldLayoutTable)
 02106            {
 02107                writer.WriteInt32(fieldLayout.Offset);
 02108                writer.WriteReference(fieldLayout.Field, metadataSizes.FieldDefReferenceIsSmall);
 02109            }
 02110        }
 2111
 2112        private void SerializeStandAloneSigTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02113        {
 02114            foreach (StandaloneSigRow row in _standAloneSigTable)
 02115            {
 02116                writer.WriteReference(SerializeHandle(row.Signature), metadataSizes.BlobReferenceIsSmall);
 02117            }
 02118        }
 2119
 2120        private void SerializeEventMapTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02121        {
 02122            foreach (EventMapRow eventMap in _eventMapTable)
 02123            {
 02124                writer.WriteReference(eventMap.Parent, metadataSizes.TypeDefReferenceIsSmall);
 02125                writer.WriteReference(eventMap.EventList, metadataSizes.EventDefReferenceIsSmall);
 02126            }
 02127        }
 2128
 2129        private void SerializeEventTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSizes)
 02130        {
 02131            foreach (EventRow eventRow in _eventTable)
 02132            {
 02133                writer.WriteUInt16(eventRow.EventFlags);
 02134                writer.WriteReference(SerializeHandle(stringMap, eventRow.Name), metadataSizes.StringReferenceIsSmall);
 02135                writer.WriteReference(eventRow.EventType, metadataSizes.TypeDefOrRefCodedIndexIsSmall);
 02136            }
 02137        }
 2138
 2139        private void SerializePropertyMapTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02140        {
 02141            foreach (PropertyMapRow propertyMap in _propertyMapTable)
 02142            {
 02143                writer.WriteReference(propertyMap.Parent, metadataSizes.TypeDefReferenceIsSmall);
 02144                writer.WriteReference(propertyMap.PropertyList, metadataSizes.PropertyDefReferenceIsSmall);
 02145            }
 02146        }
 2147
 2148        private void SerializePropertyTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSiz
 02149        {
 02150            foreach (PropertyRow property in _propertyTable)
 02151            {
 02152                writer.WriteUInt16(property.PropFlags);
 02153                writer.WriteReference(SerializeHandle(stringMap, property.Name), metadataSizes.StringReferenceIsSmall);
 02154                writer.WriteReference(SerializeHandle(property.Type), metadataSizes.BlobReferenceIsSmall);
 02155            }
 02156        }
 2157
 2158        private void SerializeMethodSemanticsTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02159        {
 2160            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 2161            // OrderBy performs a stable sort, so multiple attributes with the same parent will be sorted in the order t
 02162            var ordered = _methodSemanticsTableNeedsSorting ? _methodSemanticsTable.OrderBy((x, y) => (int)x.Association
 2163
 02164            foreach (MethodSemanticsRow methodSemantic in ordered)
 02165            {
 02166                writer.WriteUInt16(methodSemantic.Semantic);
 02167                writer.WriteReference(methodSemantic.Method, metadataSizes.MethodDefReferenceIsSmall);
 02168                writer.WriteReference(methodSemantic.Association, metadataSizes.HasSemanticsCodedIndexIsSmall);
 02169            }
 02170        }
 2171
 2172        private void SerializeMethodImplTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02173        {
 02174            foreach (MethodImplRow methodImpl in _methodImplTable)
 02175            {
 02176                writer.WriteReference(methodImpl.Class, metadataSizes.TypeDefReferenceIsSmall);
 02177                writer.WriteReference(methodImpl.MethodBody, metadataSizes.MethodDefOrRefCodedIndexIsSmall);
 02178                writer.WriteReference(methodImpl.MethodDecl, metadataSizes.MethodDefOrRefCodedIndexIsSmall);
 02179            }
 02180        }
 2181
 2182        private void SerializeModuleRefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSi
 02183        {
 02184            foreach (ModuleRefRow moduleRef in _moduleRefTable)
 02185            {
 02186                writer.WriteReference(SerializeHandle(stringMap, moduleRef.Name), metadataSizes.StringReferenceIsSmall);
 02187            }
 02188        }
 2189
 2190        private void SerializeTypeSpecTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02191        {
 02192            foreach (TypeSpecRow typeSpec in _typeSpecTable)
 02193            {
 02194                writer.WriteReference(SerializeHandle(typeSpec.Signature), metadataSizes.BlobReferenceIsSmall);
 02195            }
 02196        }
 2197
 2198        private void SerializeImplMapTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSize
 02199        {
 02200            foreach (ImplMapRow implMap in _implMapTable)
 02201            {
 02202                writer.WriteUInt16(implMap.MappingFlags);
 02203                writer.WriteReference(implMap.MemberForwarded, metadataSizes.MemberForwardedCodedIndexIsSmall);
 02204                writer.WriteReference(SerializeHandle(stringMap, implMap.ImportName), metadataSizes.StringReferenceIsSma
 02205                writer.WriteReference(implMap.ImportScope, metadataSizes.ModuleRefReferenceIsSmall);
 02206            }
 02207        }
 2208
 2209        private void SerializeFieldRvaTable(BlobBuilder writer, MetadataSizes metadataSizes, int mappedFieldDataStreamRv
 02210        {
 02211            foreach (FieldRvaRow fieldRva in _fieldRvaTable)
 02212            {
 02213                writer.WriteInt32(mappedFieldDataStreamRva + fieldRva.Offset);
 02214                writer.WriteReference(fieldRva.Field, metadataSizes.FieldDefReferenceIsSmall);
 02215            }
 02216        }
 2217
 2218        private void SerializeAssemblyTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSiz
 02219        {
 02220            if (_assemblyRow.HasValue)
 02221            {
 02222                var version = _assemblyRow.Value.Version;
 02223                writer.WriteUInt32(_assemblyRow.Value.HashAlgorithm);
 02224                writer.WriteUInt16((ushort)version.Major);
 02225                writer.WriteUInt16((ushort)version.Minor);
 02226                writer.WriteUInt16((ushort)version.Build);
 02227                writer.WriteUInt16((ushort)version.Revision);
 02228                writer.WriteUInt32(_assemblyRow.Value.Flags);
 02229                writer.WriteReference(SerializeHandle(_assemblyRow.Value.AssemblyKey), metadataSizes.BlobReferenceIsSmal
 02230                writer.WriteReference(SerializeHandle(stringMap, _assemblyRow.Value.AssemblyName), metadataSizes.StringR
 02231                writer.WriteReference(SerializeHandle(stringMap, _assemblyRow.Value.AssemblyCulture), metadataSizes.Stri
 02232            }
 02233        }
 2234
 2235        private void SerializeAssemblyRefTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadata
 02236        {
 02237            foreach (AssemblyRefTableRow row in _assemblyRefTable)
 02238            {
 02239                writer.WriteUInt16((ushort)row.Version.Major);
 02240                writer.WriteUInt16((ushort)row.Version.Minor);
 02241                writer.WriteUInt16((ushort)row.Version.Build);
 02242                writer.WriteUInt16((ushort)row.Version.Revision);
 02243                writer.WriteUInt32(row.Flags);
 02244                writer.WriteReference(SerializeHandle(row.PublicKeyToken), metadataSizes.BlobReferenceIsSmall);
 02245                writer.WriteReference(SerializeHandle(stringMap, row.Name), metadataSizes.StringReferenceIsSmall);
 02246                writer.WriteReference(SerializeHandle(stringMap, row.Culture), metadataSizes.StringReferenceIsSmall);
 02247                writer.WriteReference(SerializeHandle(row.HashValue), metadataSizes.BlobReferenceIsSmall);
 02248            }
 02249        }
 2250
 2251        private void SerializeFileTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadataSizes)
 02252        {
 02253            foreach (FileTableRow fileReference in _fileTable)
 02254            {
 02255                writer.WriteUInt32(fileReference.Flags);
 02256                writer.WriteReference(SerializeHandle(stringMap, fileReference.FileName), metadataSizes.StringReferenceI
 02257                writer.WriteReference(SerializeHandle(fileReference.HashValue), metadataSizes.BlobReferenceIsSmall);
 02258            }
 02259        }
 2260
 2261        private void SerializeExportedTypeTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadat
 02262        {
 02263            foreach (ExportedTypeRow exportedType in _exportedTypeTable)
 02264            {
 02265                writer.WriteUInt32(exportedType.Flags);
 02266                writer.WriteInt32(exportedType.TypeDefId);
 02267                writer.WriteReference(SerializeHandle(stringMap, exportedType.TypeName), metadataSizes.StringReferenceIs
 02268                writer.WriteReference(SerializeHandle(stringMap, exportedType.TypeNamespace), metadataSizes.StringRefere
 02269                writer.WriteReference(exportedType.Implementation, metadataSizes.ImplementationCodedIndexIsSmall);
 02270            }
 02271        }
 2272
 2273        private void SerializeManifestResourceTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes met
 02274        {
 02275            foreach (ManifestResourceRow manifestResource in _manifestResourceTable)
 02276            {
 02277                writer.WriteUInt32(manifestResource.Offset);
 02278                writer.WriteUInt32(manifestResource.Flags);
 02279                writer.WriteReference(SerializeHandle(stringMap, manifestResource.Name), metadataSizes.StringReferenceIs
 02280                writer.WriteReference(manifestResource.Implementation, metadataSizes.ImplementationCodedIndexIsSmall);
 02281            }
 02282        }
 2283
 2284        private void SerializeNestedClassTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02285        {
 02286            foreach (NestedClassRow nestedClass in _nestedClassTable)
 02287            {
 02288                writer.WriteReference(nestedClass.NestedClass, metadataSizes.TypeDefReferenceIsSmall);
 02289                writer.WriteReference(nestedClass.EnclosingClass, metadataSizes.TypeDefReferenceIsSmall);
 02290            }
 02291        }
 2292
 2293        private void SerializeGenericParamTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metadat
 02294        {
 02295            foreach (GenericParamRow genericParam in _genericParamTable)
 02296            {
 02297                writer.WriteUInt16(genericParam.Number);
 02298                writer.WriteUInt16(genericParam.Flags);
 02299                writer.WriteReference(genericParam.Owner, metadataSizes.TypeOrMethodDefCodedIndexIsSmall);
 02300                writer.WriteReference(SerializeHandle(stringMap, genericParam.Name), metadataSizes.StringReferenceIsSmal
 02301            }
 02302        }
 2303
 2304        private void SerializeGenericParamConstraintTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02305        {
 02306            foreach (GenericParamConstraintRow genericParamConstraint in _genericParamConstraintTable)
 02307            {
 02308                writer.WriteReference(genericParamConstraint.Owner, metadataSizes.GenericParamReferenceIsSmall);
 02309                writer.WriteReference(genericParamConstraint.Constraint, metadataSizes.TypeDefOrRefCodedIndexIsSmall);
 02310            }
 02311        }
 2312
 2313        private void SerializeMethodSpecTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02314        {
 02315            foreach (MethodSpecRow methodSpec in _methodSpecTable)
 02316            {
 02317                writer.WriteReference(methodSpec.Method, metadataSizes.MethodDefOrRefCodedIndexIsSmall);
 02318                writer.WriteReference(SerializeHandle(methodSpec.Instantiation), metadataSizes.BlobReferenceIsSmall);
 02319            }
 02320        }
 2321
 2322        private void SerializeDocumentTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02323        {
 02324            foreach (var row in _documentTable)
 02325            {
 02326                writer.WriteReference(SerializeHandle(row.Name), metadataSizes.BlobReferenceIsSmall);
 02327                writer.WriteReference(SerializeHandle(row.HashAlgorithm), metadataSizes.GuidReferenceIsSmall);
 02328                writer.WriteReference(SerializeHandle(row.Hash), metadataSizes.BlobReferenceIsSmall);
 02329                writer.WriteReference(SerializeHandle(row.Language), metadataSizes.GuidReferenceIsSmall);
 02330            }
 02331        }
 2332
 2333        private void SerializeMethodDebugInformationTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02334        {
 02335            foreach (var row in _methodDebugInformationTable)
 02336            {
 02337                writer.WriteReference(row.Document, metadataSizes.DocumentReferenceIsSmall);
 02338                writer.WriteReference(SerializeHandle(row.SequencePoints), metadataSizes.BlobReferenceIsSmall);
 02339            }
 02340        }
 2341
 2342        private void SerializeLocalScopeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02343        {
 02344            foreach (var row in _localScopeTable)
 02345            {
 02346                writer.WriteReference(row.Method, metadataSizes.MethodDefReferenceIsSmall);
 02347                writer.WriteReference(row.ImportScope, metadataSizes.ImportScopeReferenceIsSmall);
 02348                writer.WriteReference(row.VariableList, metadataSizes.LocalVariableReferenceIsSmall);
 02349                writer.WriteReference(row.ConstantList, metadataSizes.LocalConstantReferenceIsSmall);
 02350                writer.WriteInt32(row.StartOffset);
 02351                writer.WriteInt32(row.Length);
 02352            }
 02353        }
 2354
 2355        private void SerializeLocalVariableTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metada
 02356        {
 02357            foreach (var row in _localVariableTable)
 02358            {
 02359                writer.WriteUInt16(row.Attributes);
 02360                writer.WriteUInt16(row.Index);
 02361                writer.WriteReference(SerializeHandle(stringMap, row.Name), metadataSizes.StringReferenceIsSmall);
 02362            }
 02363        }
 2364
 2365        private void SerializeLocalConstantTable(BlobBuilder writer, ImmutableArray<int> stringMap, MetadataSizes metada
 02366        {
 02367            foreach (var row in _localConstantTable)
 02368            {
 02369                writer.WriteReference(SerializeHandle(stringMap, row.Name), metadataSizes.StringReferenceIsSmall);
 02370                writer.WriteReference(SerializeHandle(row.Signature), metadataSizes.BlobReferenceIsSmall);
 02371            }
 02372        }
 2373
 2374        private void SerializeImportScopeTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02375        {
 02376            foreach (var row in _importScopeTable)
 02377            {
 02378                writer.WriteReference(row.Parent, metadataSizes.ImportScopeReferenceIsSmall);
 02379                writer.WriteReference(SerializeHandle(row.Imports), metadataSizes.BlobReferenceIsSmall);
 02380            }
 02381        }
 2382
 2383        private void SerializeStateMachineMethodTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02384        {
 02385            foreach (var row in _stateMachineMethodTable)
 02386            {
 02387                writer.WriteReference(row.MoveNextMethod, metadataSizes.MethodDefReferenceIsSmall);
 02388                writer.WriteReference(row.KickoffMethod, metadataSizes.MethodDefReferenceIsSmall);
 02389            }
 02390        }
 2391
 2392        private void SerializeCustomDebugInformationTable(BlobBuilder writer, MetadataSizes metadataSizes)
 02393        {
 2394            // Note: we can sort the table at this point since no other table can reference its rows via RowId or CodedI
 2395            // OrderBy performs a stable sort, so multiple attributes with the same parent and kind will be sorted in th
 02396            foreach (CustomDebugInformationRow row in _customDebugInformationTable.OrderBy((x, y) =>
 02397            {
 02398                int result = x.Parent - y.Parent;
 02399                return (result != 0) ? result : x.Kind.Index - y.Kind.Index;
 02400            }))
 02401            {
 02402                writer.WriteReference(row.Parent, metadataSizes.HasCustomDebugInformationCodedIndexIsSmall);
 02403                writer.WriteReference(SerializeHandle(row.Kind), metadataSizes.GuidReferenceIsSmall);
 02404                writer.WriteReference(SerializeHandle(row.Value), metadataSizes.BlobReferenceIsSmall);
 02405            }
 02406        }
 2407
 2408        #endregion
 2409    }
 2410}
 2411

Methods/Properties

GetSerializedMetadata(System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Int32,System.Boolean)
SerializeMetadataHeader(System.Reflection.Metadata.BlobBuilder,System.String,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeStreamHeader(System.Int32&,System.Int32,System.ReadOnlySpan`1<System.Byte>,System.Reflection.Metadata.BlobBuilder)
.ctor(System.Int32)
AllocateChunk(System.Int32)
SetCapacity(System.Int32)
.ctor(System.Int32,System.Int32,System.Int32,System.Int32)
SetCapacity(System.Reflection.Metadata.Ecma335.HeapIndex,System.Int32)
SerializeHandle(System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.StringHandle)
SerializeHandle(System.Reflection.Metadata.BlobHandle)
SerializeHandle(System.Reflection.Metadata.GuidHandle)
SerializeHandle(System.Reflection.Metadata.UserStringHandle)
GetOrAddBlob(System.Reflection.Metadata.BlobBuilder)
GetOrAddBlob(System.Byte[])
GetOrAddBlob(System.ReadOnlySpan`1<System.Byte>,System.Collections.Immutable.ImmutableArray`1<System.Byte>)
GetOrAddBlob(System.Collections.Immutable.ImmutableArray`1<System.Byte>)
GetOrAddConstantBlob(System.Object)
GetOrAddBlobUTF16(System.String)
GetOrAddBlobUTF8(System.String,System.Boolean)
GetOrAddDocumentName(System.String)
ChooseSeparator(System.String)
GetOrAddGuid(System.Guid)
ReserveGuid()
GetNewGuidHandle()
GetOrAddString(System.String)
ReserveUserString(System.Int32)
GetOrAddUserString(System.String)
GetNewUserStringHandle()
SerializeStringHeap(System.Reflection.Metadata.BlobBuilder,System.Collections.Generic.Dictionary`2<System.String,System.Reflection.Metadata.StringHandle>,System.Int32)
.cctor()
Compare(System.Collections.Generic.KeyValuePair`2<System.String,System.Reflection.Metadata.StringHandle>,System.Collections.Generic.KeyValuePair`2<System.String,System.Reflection.Metadata.StringHandle>)
WriteHeapsTo(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.BlobBuilder)
WriteAlignedBlobHeap(System.Reflection.Metadata.BlobBuilder)
WriteAligned(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.BlobBuilder)
.ctor(System.Int32,System.Int32,System.Int32,System.Int32)
SetCapacity(System.Reflection.Metadata.Ecma335.TableIndex,System.Int32)
SetTableCapacity(System.Collections.Generic.List`1<T>,System.Int32)
GetRowCount(System.Reflection.Metadata.Ecma335.TableIndex)
GetRowCounts()
AddModule(System.Int32,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.GuidHandle,System.Reflection.Metadata.GuidHandle,System.Reflection.Metadata.GuidHandle)
AddAssembly(System.Reflection.Metadata.StringHandle,System.Version,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Reflection.AssemblyFlags,System.Reflection.AssemblyHashAlgorithm)
AddAssemblyReference(System.Reflection.Metadata.StringHandle,System.Version,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Reflection.AssemblyFlags,System.Reflection.Metadata.BlobHandle)
AddTypeDefinition(System.Reflection.TypeAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.FieldDefinitionHandle,System.Reflection.Metadata.MethodDefinitionHandle)
AddTypeLayout(System.Reflection.Metadata.TypeDefinitionHandle,System.UInt16,System.UInt32)
AddInterfaceImplementation(System.Reflection.Metadata.TypeDefinitionHandle,System.Reflection.Metadata.EntityHandle)
AddNestedType(System.Reflection.Metadata.TypeDefinitionHandle,System.Reflection.Metadata.TypeDefinitionHandle)
AddTypeReference(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.StringHandle)
AddTypeSpecification(System.Reflection.Metadata.BlobHandle)
AddStandaloneSignature(System.Reflection.Metadata.BlobHandle)
AddProperty(System.Reflection.PropertyAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle)
AddPropertyMap(System.Reflection.Metadata.TypeDefinitionHandle,System.Reflection.Metadata.PropertyDefinitionHandle)
AddEvent(System.Reflection.EventAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.EntityHandle)
AddEventMap(System.Reflection.Metadata.TypeDefinitionHandle,System.Reflection.Metadata.EventDefinitionHandle)
AddConstant(System.Reflection.Metadata.EntityHandle,System.Object)
AddMethodSemantics(System.Reflection.Metadata.EntityHandle,System.Reflection.MethodSemanticsAttributes,System.Reflection.Metadata.MethodDefinitionHandle)
AddCustomAttribute(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.BlobHandle)
AddMethodSpecification(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.BlobHandle)
AddModuleReference(System.Reflection.Metadata.StringHandle)
AddParameter(System.Reflection.ParameterAttributes,System.Reflection.Metadata.StringHandle,System.Int32)
AddGenericParameter(System.Reflection.Metadata.EntityHandle,System.Reflection.GenericParameterAttributes,System.Reflection.Metadata.StringHandle,System.Int32)
AddGenericParameterConstraint(System.Reflection.Metadata.GenericParameterHandle,System.Reflection.Metadata.EntityHandle)
AddFieldDefinition(System.Reflection.FieldAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle)
AddFieldLayout(System.Reflection.Metadata.FieldDefinitionHandle,System.Int32)
AddMarshallingDescriptor(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.BlobHandle)
AddFieldRelativeVirtualAddress(System.Reflection.Metadata.FieldDefinitionHandle,System.Int32)
AddMethodDefinition(System.Reflection.MethodAttributes,System.Reflection.MethodImplAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Int32,System.Reflection.Metadata.ParameterHandle)
AddMethodImport(System.Reflection.Metadata.MethodDefinitionHandle,System.Reflection.MethodImportAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.ModuleReferenceHandle)
AddMethodImplementation(System.Reflection.Metadata.TypeDefinitionHandle,System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.EntityHandle)
AddMemberReference(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle)
AddManifestResource(System.Reflection.ManifestResourceAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.EntityHandle,System.UInt32)
AddAssemblyFile(System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle,System.Boolean)
AddExportedType(System.Reflection.TypeAttributes,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.EntityHandle,System.Int32)
AddDeclarativeSecurityAttribute(System.Reflection.Metadata.EntityHandle,System.Reflection.DeclarativeSecurityAction,System.Reflection.Metadata.BlobHandle)
AddEncLogEntry(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.Ecma335.EditAndContinueOperation)
AddEncMapEntry(System.Reflection.Metadata.EntityHandle)
AddDocument(System.Reflection.Metadata.BlobHandle,System.Reflection.Metadata.GuidHandle,System.Reflection.Metadata.BlobHandle,System.Reflection.Metadata.GuidHandle)
AddMethodDebugInformation(System.Reflection.Metadata.DocumentHandle,System.Reflection.Metadata.BlobHandle)
AddLocalScope(System.Reflection.Metadata.MethodDefinitionHandle,System.Reflection.Metadata.ImportScopeHandle,System.Reflection.Metadata.LocalVariableHandle,System.Reflection.Metadata.LocalConstantHandle,System.Int32,System.Int32)
AddLocalVariable(System.Reflection.Metadata.LocalVariableAttributes,System.Int32,System.Reflection.Metadata.StringHandle)
AddLocalConstant(System.Reflection.Metadata.StringHandle,System.Reflection.Metadata.BlobHandle)
AddImportScope(System.Reflection.Metadata.ImportScopeHandle,System.Reflection.Metadata.BlobHandle)
AddStateMachineMethod(System.Reflection.Metadata.MethodDefinitionHandle,System.Reflection.Metadata.MethodDefinitionHandle)
AddCustomDebugInformation(System.Reflection.Metadata.EntityHandle,System.Reflection.Metadata.GuidHandle,System.Reflection.Metadata.BlobHandle)
ValidateOrder()
ValidateClassLayoutTable()
ValidateFieldLayoutTable()
ValidateFieldRvaTable()
ValidateGenericParamTable()
ValidateGenericParamConstaintTable()
ValidateImplMapTable()
ValidateInterfaceImplTable()
ValidateMethodImplTable()
ValidateNestedClassTable()
ValidateLocalScopeTable()
ValidateStateMachineMethodTable()
SerializeMetadataTables(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Int32,System.Int32)
SerializeTablesHeader(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeModuleTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeEncLogTable(System.Reflection.Metadata.BlobBuilder)
SerializeEncMapTable(System.Reflection.Metadata.BlobBuilder)
SerializeTypeRefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeTypeDefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeFieldTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMethodDefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes,System.Int32)
SerializeParamTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeInterfaceImplTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMemberRefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeConstantTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeCustomAttributeTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeFieldMarshalTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeDeclSecurityTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeClassLayoutTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeFieldLayoutTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeStandAloneSigTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeEventMapTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeEventTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializePropertyMapTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializePropertyTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMethodSemanticsTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMethodImplTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeModuleRefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeTypeSpecTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeImplMapTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeFieldRvaTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes,System.Int32)
SerializeAssemblyTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeAssemblyRefTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeFileTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeExportedTypeTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeManifestResourceTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeNestedClassTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeGenericParamTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeGenericParamConstraintTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMethodSpecTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeDocumentTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeMethodDebugInformationTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeLocalScopeTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeLocalVariableTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeLocalConstantTable(System.Reflection.Metadata.BlobBuilder,System.Collections.Immutable.ImmutableArray`1<System.Int32>,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeImportScopeTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeStateMachineMethodTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)
SerializeCustomDebugInformationTable(System.Reflection.Metadata.BlobBuilder,System.Reflection.Metadata.Ecma335.MetadataSizes)