File: System\Reflection\Metadata\Internal\MetadataFlags.cs
Web Access
Project: src\src\libraries\System.Reflection.Metadata\src\System.Reflection.Metadata.csproj (System.Reflection.Metadata)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics;
 
namespace System.Reflection.Metadata.Ecma335
{
    internal enum MetadataStreamKind
    {
        Illegal,
        Compressed,
        Uncompressed,
    }
 
    [Flags]
    internal enum TableMask : ulong
    {
        Module = 1UL << TableIndex.Module,
        TypeRef = 1UL << TableIndex.TypeRef,
        TypeDef = 1UL << TableIndex.TypeDef,
        FieldPtr = 1UL << TableIndex.FieldPtr,
        Field = 1UL << TableIndex.Field,
        MethodPtr = 1UL << TableIndex.MethodPtr,
        MethodDef = 1UL << TableIndex.MethodDef,
        ParamPtr = 1UL << TableIndex.ParamPtr,
        Param = 1UL << TableIndex.Param,
        InterfaceImpl = 1UL << TableIndex.InterfaceImpl,
        MemberRef = 1UL << TableIndex.MemberRef,
        Constant = 1UL << TableIndex.Constant,
        CustomAttribute = 1UL << TableIndex.CustomAttribute,
        FieldMarshal = 1UL << TableIndex.FieldMarshal,
        DeclSecurity = 1UL << TableIndex.DeclSecurity,
        ClassLayout = 1UL << TableIndex.ClassLayout,
        FieldLayout = 1UL << TableIndex.FieldLayout,
        StandAloneSig = 1UL << TableIndex.StandAloneSig,
        EventMap = 1UL << TableIndex.EventMap,
        EventPtr = 1UL << TableIndex.EventPtr,
        Event = 1UL << TableIndex.Event,
        PropertyMap = 1UL << TableIndex.PropertyMap,
        PropertyPtr = 1UL << TableIndex.PropertyPtr,
        Property = 1UL << TableIndex.Property,
        MethodSemantics = 1UL << TableIndex.MethodSemantics,
        MethodImpl = 1UL << TableIndex.MethodImpl,
        ModuleRef = 1UL << TableIndex.ModuleRef,
        TypeSpec = 1UL << TableIndex.TypeSpec,
        ImplMap = 1UL << TableIndex.ImplMap,
        FieldRva = 1UL << TableIndex.FieldRva,
        EnCLog = 1UL << TableIndex.EncLog,
        EnCMap = 1UL << TableIndex.EncMap,
        Assembly = 1UL << TableIndex.Assembly,
        // AssemblyProcessor = 1UL << TableIndices.AssemblyProcessor,
        // AssemblyOS = 1UL << TableIndices.AssemblyOS,
        AssemblyRef = 1UL << TableIndex.AssemblyRef,
        // AssemblyRefProcessor = 1UL << TableIndices.AssemblyRefProcessor,
        // AssemblyRefOS = 1UL << TableIndices.AssemblyRefOS,
        File = 1UL << TableIndex.File,
        ExportedType = 1UL << TableIndex.ExportedType,
        ManifestResource = 1UL << TableIndex.ManifestResource,
        NestedClass = 1UL << TableIndex.NestedClass,
        GenericParam = 1UL << TableIndex.GenericParam,
        MethodSpec = 1UL << TableIndex.MethodSpec,
        GenericParamConstraint = 1UL << TableIndex.GenericParamConstraint,
 
        Document = 1UL << TableIndex.Document,
        MethodDebugInformation = 1UL << TableIndex.MethodDebugInformation,
        LocalScope = 1UL << TableIndex.LocalScope,
        LocalVariable = 1UL << TableIndex.LocalVariable,
        LocalConstant = 1UL << TableIndex.LocalConstant,
        ImportScope = 1UL << TableIndex.ImportScope,
        StateMachineMethod = 1UL << TableIndex.StateMachineMethod,
        CustomDebugInformation = 1UL << TableIndex.CustomDebugInformation,
 
        PtrTables =
            FieldPtr
          | MethodPtr
          | ParamPtr
          | EventPtr
          | PropertyPtr,
 
        EncTables =
            EnCLog
          | EnCMap,
 
        TypeSystemTables =
            PtrTables
          | EncTables
          | Module
          | TypeRef
          | TypeDef
          | Field
          | MethodDef
          | Param
          | InterfaceImpl
          | MemberRef
          | Constant
          | CustomAttribute
          | FieldMarshal
          | DeclSecurity
          | ClassLayout
          | FieldLayout
          | StandAloneSig
          | EventMap
          | Event
          | PropertyMap
          | Property
          | MethodSemantics
          | MethodImpl
          | ModuleRef
          | TypeSpec
          | ImplMap
          | FieldRva
          | Assembly
          | AssemblyRef
          | File
          | ExportedType
          | ManifestResource
          | NestedClass
          | GenericParam
          | MethodSpec
          | GenericParamConstraint,
 
        DebugTables =
            Document
          | MethodDebugInformation
          | LocalScope
          | LocalVariable
          | LocalConstant
          | ImportScope
          | StateMachineMethod
          | CustomDebugInformation,
 
        AllTables =
            TypeSystemTables |
            DebugTables,
 
        ValidPortablePdbExternalTables =
            TypeSystemTables & ~PtrTables & ~EncTables
    }
 
    internal enum HeapSizes : byte
    {
        StringHeapLarge = 0x01, // 4 byte uint indexes used for string heap offsets
        GuidHeapLarge = 0x02,   // 4 byte uint indexes used for GUID heap offsets
        BlobHeapLarge = 0x04,   // 4 byte uint indexes used for Blob heap offsets
        ExtraData = 0x40,       // Indicates that there is an extra 4 bytes of data immediately after the row counts
    }
 
    internal enum StringKind : byte
    {
        Plain = (byte)(StringHandleType.String >> HeapHandleType.OffsetBitCount),
        Virtual = (byte)(StringHandleType.VirtualString >> HeapHandleType.OffsetBitCount),
        WinRTPrefixed = (byte)(StringHandleType.WinRTPrefixedString >> HeapHandleType.OffsetBitCount),
        DotTerminated = (byte)(StringHandleType.DotTerminatedString >> HeapHandleType.OffsetBitCount),
    }
 
    internal static class StringHandleType
    {
        // The 3 high bits above the offset that specify the full string type (including virtual bit)
        internal const uint TypeMask = ~(HeapHandleType.OffsetMask);
 
        // The string type bits excluding the virtual bit.
        internal const uint NonVirtualTypeMask = TypeMask & ~(HeapHandleType.VirtualBit);
 
        // NUL-terminated UTF8 string on a #String heap.
        internal const uint String = (0 << HeapHandleType.OffsetBitCount);
 
        // String on #String heap whose terminator is NUL and '.', whichever comes first.
        internal const uint DotTerminatedString = (1 << HeapHandleType.OffsetBitCount);
 
        // Reserved values that can be used for future strings:
        internal const uint ReservedString1 = (2 << HeapHandleType.OffsetBitCount);
        internal const uint ReservedString2 = (3 << HeapHandleType.OffsetBitCount);
 
        // Virtual string identified by a virtual index
        internal const uint VirtualString = HeapHandleType.VirtualBit | (0 << HeapHandleType.OffsetBitCount);
 
        // Virtual string whose value is a "<WinRT>" prefixed string found at the specified heap offset.
        internal const uint WinRTPrefixedString = HeapHandleType.VirtualBit | (1 << HeapHandleType.OffsetBitCount);
 
        // Reserved virtual strings that can be used in future:
        internal const uint ReservedVirtualString1 = HeapHandleType.VirtualBit | (2 << HeapHandleType.OffsetBitCount);
        internal const uint ReservedVirtualString2 = HeapHandleType.VirtualBit | (3 << HeapHandleType.OffsetBitCount);
    }
 
    internal static class HeapHandleType
    {
        // Heap offset values are limited to 29 bits (max compressed integer)
        internal const int OffsetBitCount = 29;
        internal const uint OffsetMask = (1 << OffsetBitCount) - 1;
        internal const uint VirtualBit = 0x80000000;
 
        internal static bool IsValidHeapOffset(uint offset)
        {
            return (offset & ~OffsetMask) == 0;
        }
    }
 
    /// <summary>
    /// These constants are all in the byte range and apply to the interpretation of <see cref="Handle.VType"/>,
    /// </summary>
    internal static class HandleType
    {
        internal const uint Module = (uint)TableIndex.Module;
        internal const uint TypeRef = (uint)TableIndex.TypeRef;
        internal const uint TypeDef = (uint)TableIndex.TypeDef;
        internal const uint FieldDef = (uint)TableIndex.Field;
        internal const uint MethodDef = (uint)TableIndex.MethodDef;
        internal const uint ParamDef = (uint)TableIndex.Param;
        internal const uint InterfaceImpl = (uint)TableIndex.InterfaceImpl;
        internal const uint MemberRef = (uint)TableIndex.MemberRef;
        internal const uint Constant = (uint)TableIndex.Constant;
        internal const uint CustomAttribute = (uint)TableIndex.CustomAttribute;
        internal const uint DeclSecurity = (uint)TableIndex.DeclSecurity;
        internal const uint Signature = (uint)TableIndex.StandAloneSig;
        internal const uint EventMap = (uint)TableIndex.EventMap;
        internal const uint Event = (uint)TableIndex.Event;
        internal const uint PropertyMap = (uint)TableIndex.PropertyMap;
        internal const uint Property = (uint)TableIndex.Property;
        internal const uint MethodSemantics = (uint)TableIndex.MethodSemantics;
        internal const uint MethodImpl = (uint)TableIndex.MethodImpl;
        internal const uint ModuleRef = (uint)TableIndex.ModuleRef;
        internal const uint TypeSpec = (uint)TableIndex.TypeSpec;
        internal const uint Assembly = (uint)TableIndex.Assembly;
        internal const uint AssemblyRef = (uint)TableIndex.AssemblyRef;
        internal const uint File = (uint)TableIndex.File;
        internal const uint ExportedType = (uint)TableIndex.ExportedType;
        internal const uint ManifestResource = (uint)TableIndex.ManifestResource;
        internal const uint NestedClass = (uint)TableIndex.NestedClass;
        internal const uint GenericParam = (uint)TableIndex.GenericParam;
        internal const uint MethodSpec = (uint)TableIndex.MethodSpec;
        internal const uint GenericParamConstraint = (uint)TableIndex.GenericParamConstraint;
 
        // debug tables:
        internal const uint Document = (uint)TableIndex.Document;
        internal const uint MethodDebugInformation = (uint)TableIndex.MethodDebugInformation;
        internal const uint LocalScope = (uint)TableIndex.LocalScope;
        internal const uint LocalVariable = (uint)TableIndex.LocalVariable;
        internal const uint LocalConstant = (uint)TableIndex.LocalConstant;
        internal const uint ImportScope = (uint)TableIndex.ImportScope;
        internal const uint AsyncMethod = (uint)TableIndex.StateMachineMethod;
        internal const uint CustomDebugInformation = (uint)TableIndex.CustomDebugInformation;
 
        internal const uint UserString = 0x70;     // #UserString heap
 
        // The following values never appear in a token stored in metadata,
        // they are just helper values to identify the type of a handle.
        // Note, however, that even though they do not come from the spec,
        // they are surfaced as public constants via HandleKind enum and
        // therefore cannot change!
 
        internal const uint Blob = 0x71;        // #Blob heap
        internal const uint Guid = 0x72;        // #Guid heap
 
        // #String heap and its modifications
        //
        // Multiple values are reserved for string handles so that we can encode special
        // handling with more than just the virtual bit. See StringHandleType for how
        // the two extra bits are actually interpreted. The extra String1,2,3 values here are
        // not used directly, but serve as a reminder that they are not available for use
        // by another handle type.
        internal const uint String  = 0x78;
        internal const uint String1 = 0x79;
        internal const uint String2 = 0x7a;
        internal const uint String3 = 0x7b;
 
        // Namespace handles also have offsets into the #String heap (when non-virtual)
        // to their full name. However, this is an implementation detail and they are
        // surfaced with first-class HandleKind.Namespace and strongly-typed NamespaceHandle.
        internal const uint Namespace = 0x7c;
 
        internal const uint HeapMask = 0x70;
        internal const uint TypeMask = 0x7F;
 
        /// <summary>
        /// Use the highest bit to mark tokens that are virtual (synthesized).
        /// We create virtual tokens to represent projected WinMD entities.
        /// </summary>
        internal const uint VirtualBit = 0x80;
 
        /// <summary>
        /// In the case of string handles, the two lower bits that (in addition to the
        /// virtual bit not included in this mask) encode how to obtain the string value.
        /// </summary>
        internal const uint NonVirtualStringTypeMask = 0x03;
    }
 
    internal static class TokenTypeIds
    {
        internal const uint Module = HandleType.Module << RowIdBitCount;
        internal const uint TypeRef = HandleType.TypeRef << RowIdBitCount;
        internal const uint TypeDef = HandleType.TypeDef << RowIdBitCount;
        internal const uint FieldDef = HandleType.FieldDef << RowIdBitCount;
        internal const uint MethodDef = HandleType.MethodDef << RowIdBitCount;
        internal const uint ParamDef = HandleType.ParamDef << RowIdBitCount;
        internal const uint InterfaceImpl = HandleType.InterfaceImpl << RowIdBitCount;
        internal const uint MemberRef = HandleType.MemberRef << RowIdBitCount;
        internal const uint Constant = HandleType.Constant << RowIdBitCount;
        internal const uint CustomAttribute = HandleType.CustomAttribute << RowIdBitCount;
        internal const uint DeclSecurity = HandleType.DeclSecurity << RowIdBitCount;
        internal const uint Signature = HandleType.Signature << RowIdBitCount;
        internal const uint EventMap = HandleType.EventMap << RowIdBitCount;
        internal const uint Event = HandleType.Event << RowIdBitCount;
        internal const uint PropertyMap = HandleType.PropertyMap << RowIdBitCount;
        internal const uint Property = HandleType.Property << RowIdBitCount;
        internal const uint MethodSemantics = HandleType.MethodSemantics << RowIdBitCount;
        internal const uint MethodImpl = HandleType.MethodImpl << RowIdBitCount;
        internal const uint ModuleRef = HandleType.ModuleRef << RowIdBitCount;
        internal const uint TypeSpec = HandleType.TypeSpec << RowIdBitCount;
        internal const uint Assembly = HandleType.Assembly << RowIdBitCount;
        internal const uint AssemblyRef = HandleType.AssemblyRef << RowIdBitCount;
        internal const uint File = HandleType.File << RowIdBitCount;
        internal const uint ExportedType = HandleType.ExportedType << RowIdBitCount;
        internal const uint ManifestResource = HandleType.ManifestResource << RowIdBitCount;
        internal const uint NestedClass = HandleType.NestedClass << RowIdBitCount;
        internal const uint GenericParam = HandleType.GenericParam << RowIdBitCount;
        internal const uint MethodSpec = HandleType.MethodSpec << RowIdBitCount;
        internal const uint GenericParamConstraint = HandleType.GenericParamConstraint << RowIdBitCount;
 
        // debug tables:
        internal const uint Document = HandleType.Document << RowIdBitCount;
        internal const uint MethodDebugInformation = HandleType.MethodDebugInformation << RowIdBitCount;
        internal const uint LocalScope = HandleType.LocalScope << RowIdBitCount;
        internal const uint LocalVariable = HandleType.LocalVariable << RowIdBitCount;
        internal const uint LocalConstant = HandleType.LocalConstant << RowIdBitCount;
        internal const uint ImportScope = HandleType.ImportScope << RowIdBitCount;
        internal const uint AsyncMethod = HandleType.AsyncMethod << RowIdBitCount;
        internal const uint CustomDebugInformation = HandleType.CustomDebugInformation << RowIdBitCount;
 
        internal const uint UserString = HandleType.UserString << RowIdBitCount;
 
        internal const int RowIdBitCount = 24;
        internal const uint RIDMask = (1 << RowIdBitCount) - 1;
        internal const uint TypeMask = HandleType.TypeMask << RowIdBitCount;
 
        /// <summary>
        /// Use the highest bit to mark tokens that are virtual (synthesized).
        /// We create virtual tokens to represent projected WinMD entities.
        /// </summary>
        internal const uint VirtualBit = 0x80000000;
 
        /// <summary>
        /// Returns true if the token value can escape the metadata reader.
        /// We don't allow virtual tokens and heap tokens other than UserString to escape
        /// since the token type ids are internal to the reader and not specified by ECMA spec.
        ///
        /// Spec (Partition III, 1.9 Metadata tokens):
        /// Many CIL instructions are followed by a "metadata token". This is a 4-byte value, that specifies a row in a
        /// metadata table, or a starting byte offset in the User String heap.
        ///
        /// For example, a value of 0x02 specifies the TypeDef table; a value of 0x70 specifies the User
        /// String heap.The value corresponds to the number assigned to that metadata table (see Partition II for the full
        /// list of tables) or to 0x70 for the User String heap.The least-significant 3 bytes specify the target row within that
        /// metadata table, or starting byte offset within the User String heap.
        /// </summary>
        internal static bool IsEntityOrUserStringToken(uint vToken)
        {
            return (vToken & TypeMask) <= UserString;
        }
 
        internal static bool IsEntityToken(uint vToken)
        {
            return (vToken & TypeMask) < UserString;
        }
 
        internal static bool IsValidRowId(uint rowId)
        {
            return (rowId & ~RIDMask) == 0;
        }
 
        internal static bool IsValidRowId(int rowId)
        {
            return (rowId & ~RIDMask) == 0;
        }
    }
}