File: System\Reflection\Metadata\TypeSystem\AssemblyReference.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;
using System.Reflection.Metadata.Ecma335;
 
namespace System.Reflection.Metadata
{
    public readonly partial struct AssemblyReference
    {
        private readonly MetadataReader _reader;
 
        // Workaround: JIT doesn't generate good code for nested structures, so use raw uint.
        private readonly uint _treatmentAndRowId;
 
        private static readonly Version s_version_4_0_0_0 = new Version(4, 0, 0, 0);
 
        internal AssemblyReference(MetadataReader reader, uint treatmentAndRowId)
        {
            Debug.Assert(reader != null);
            Debug.Assert(treatmentAndRowId != 0);
 
            // only virtual bit can be set in highest byte:
            Debug.Assert((treatmentAndRowId & ~(TokenTypeIds.VirtualBit | TokenTypeIds.RIDMask)) == 0);
 
            _reader = reader;
            _treatmentAndRowId = treatmentAndRowId;
        }
 
        private int RowId
        {
            get { return (int)(_treatmentAndRowId & TokenTypeIds.RIDMask); }
        }
 
        private bool IsVirtual
        {
            get { return (_treatmentAndRowId & TokenTypeIds.VirtualBit) != 0; }
        }
 
        public Version Version
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualVersion();
                }
 
                // change mscorlib version:
                if (RowId == _reader.WinMDMscorlibRef)
                {
                    return s_version_4_0_0_0;
                }
 
                return _reader.AssemblyRefTable.GetVersion(RowId);
            }
        }
 
        public AssemblyFlags Flags
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualFlags();
                }
 
                return _reader.AssemblyRefTable.GetFlags(RowId);
            }
        }
 
        public StringHandle Name
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualName();
                }
 
                return _reader.AssemblyRefTable.GetName(RowId);
            }
        }
 
        public StringHandle Culture
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualCulture();
                }
 
                return _reader.AssemblyRefTable.GetCulture(RowId);
            }
        }
 
        public BlobHandle PublicKeyOrToken
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualPublicKeyOrToken();
                }
 
                return _reader.AssemblyRefTable.GetPublicKeyOrToken(RowId);
            }
        }
 
        public BlobHandle HashValue
        {
            get
            {
                if (IsVirtual)
                {
                    return GetVirtualHashValue();
                }
 
                return _reader.AssemblyRefTable.GetHashValue(RowId);
            }
        }
 
        public CustomAttributeHandleCollection GetCustomAttributes()
        {
            if (IsVirtual)
            {
                return GetVirtualCustomAttributes();
            }
 
            return new CustomAttributeHandleCollection(_reader, AssemblyReferenceHandle.FromRowId(RowId));
        }
 
        #region Virtual Rows
        private static Version GetVirtualVersion()
        {
            // currently all projected assembly references have version 4.0.0.0
            return s_version_4_0_0_0;
        }
 
        private AssemblyFlags GetVirtualFlags()
        {
            // use flags from mscorlib ref (specifically PublicKey flag):
            return _reader.AssemblyRefTable.GetFlags(_reader.WinMDMscorlibRef);
        }
 
        private StringHandle GetVirtualName()
        {
            return StringHandle.FromVirtualIndex(GetVirtualNameIndex((AssemblyReferenceHandle.VirtualIndex)RowId));
        }
 
        private static StringHandle.VirtualIndex GetVirtualNameIndex(AssemblyReferenceHandle.VirtualIndex index)
        {
            switch (index)
            {
                case AssemblyReferenceHandle.VirtualIndex.System_ObjectModel:
                    return StringHandle.VirtualIndex.System_ObjectModel;
 
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime:
                    return StringHandle.VirtualIndex.System_Runtime;
 
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime_InteropServices_WindowsRuntime:
                    return StringHandle.VirtualIndex.System_Runtime_InteropServices_WindowsRuntime;
 
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime:
                    return StringHandle.VirtualIndex.System_Runtime_WindowsRuntime;
 
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_Xaml:
                    return StringHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_Xaml;
 
                case AssemblyReferenceHandle.VirtualIndex.System_Numerics_Vectors:
                    return StringHandle.VirtualIndex.System_Numerics_Vectors;
            }
 
            Debug.Fail("Unexpected virtual index value");
            return 0;
        }
 
        private static StringHandle GetVirtualCulture()
        {
            return default(StringHandle);
        }
 
        private BlobHandle GetVirtualPublicKeyOrToken()
        {
            switch ((AssemblyReferenceHandle.VirtualIndex)RowId)
            {
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime:
                case AssemblyReferenceHandle.VirtualIndex.System_Runtime_WindowsRuntime_UI_Xaml:
                    // use key or token from mscorlib ref:
                    return _reader.AssemblyRefTable.GetPublicKeyOrToken(_reader.WinMDMscorlibRef);
 
                default:
                    // use contract assembly key or token:
                    var hasFullKey = (_reader.AssemblyRefTable.GetFlags(_reader.WinMDMscorlibRef) & AssemblyFlags.PublicKey) != 0;
                    return BlobHandle.FromVirtualIndex(hasFullKey ? BlobHandle.VirtualIndex.ContractPublicKey : BlobHandle.VirtualIndex.ContractPublicKeyToken, 0);
            }
        }
 
        private static BlobHandle GetVirtualHashValue()
        {
            return default(BlobHandle);
        }
 
        private CustomAttributeHandleCollection GetVirtualCustomAttributes()
        {
            // return custom attributes applied on mscorlib ref
            return new CustomAttributeHandleCollection(_reader, AssemblyReferenceHandle.FromRowId(_reader.WinMDMscorlibRef));
        }
        #endregion
    }
}