TypeInfo.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / TypeInfo.cs / 1305376 / TypeInfo.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections.Generic;
//using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class...
using System.Globalization;
 
using System.Data.Common;
using md = System.Data.Metadata.Edm; 
using System.Data.Query.InternalTrees; 

namespace System.Data.Query.PlanCompiler 
{

    /// 
    /// The kind of type-id in use 
    /// 
    internal enum TypeIdKind 
    { 
        UserSpecified = 0,
        Generated 
    }

    /// 
    /// The TypeInfo class encapsulates various pieces of information about a type. 
    /// The most important of these include the "flattened" record type - corresponding
    /// to the type, and the TypeId field for nominal types 
    ///  
    internal class TypeInfo
    { 

        #region private state
        private readonly md.TypeUsage m_type;    // the type
        private object m_typeId;            // the type's Id, assigned by the StructuredTypeInfo processing. 
        private List m_immediateSubTypes;  // the list of children below this type in it's type hierarchy.
        private readonly TypeInfo m_superType;       // the type one level up in this types type hierarchy -- the base type. 
        private readonly RootTypeInfo m_rootType;    // the top-most type in this types type hierarchy 
        #endregion
 
        #region Constructors and factory methods

        /// 
        /// Creates type information for a type 
        /// 
        ///  
        ///  
        /// 
        internal static TypeInfo Create(md.TypeUsage type, TypeInfo superTypeInfo, ExplicitDiscriminatorMap discriminatorMap) 
        {
            TypeInfo result;
            if (superTypeInfo == null)
            { 
                result = new RootTypeInfo(type, discriminatorMap);
            } 
            else 
            {
                result = new TypeInfo(type, superTypeInfo); 
            }
            return result;
        }
 
        protected TypeInfo(md.TypeUsage type, TypeInfo superType)
        { 
            m_type = type; 
            m_immediateSubTypes = new List();
            m_superType = superType; 
            if (superType != null)
            {
                // Add myself to my supertype's list of subtypes
                superType.m_immediateSubTypes.Add(this); 
                // my supertype's root type is mine as well
                m_rootType = superType.RootType; 
            } 
        }
 
        #endregion

        #region "public" properties for all types
 
        /// 
        /// Is this the root type? 
        /// True for entity, complex types and ref types, if this is the root of the 
        /// hierarchy.
        /// Always true for Record types 
        /// 
        internal bool IsRootType
        {
            get 
            {
                return m_rootType == null; 
            } 
        }
 
        /// 
        /// the types that derive from this type
        /// 
        internal List ImmediateSubTypes 
        {
            get 
            { 
                return m_immediateSubTypes;
            } 
        }

        /// 
        /// the immediate parent type of this type. 
        /// 
        internal TypeInfo SuperType 
        { 
            get
            { 
                return m_superType;
            }
        }
 
        /// 
        /// the top most type in the hierarchy. 
        ///  
        internal RootTypeInfo RootType
        { 
            get
            {
                return m_rootType ?? (RootTypeInfo)this;
            } 
        }
        ///  
        /// The metadata type 
        /// 
        internal md.TypeUsage Type 
        {
            get
            {
                return m_type; 
            }
        } 
 
        /// 
        /// The typeid value for this type - only applies to nominal types 
        /// 
        internal object TypeId
        {
            get 
            {
                return m_typeId; 
            } 
            set
            { 
                m_typeId = value;
            }
        }
 
        #endregion
 
        #region "public" properties for root types 

        // These properties are actually stored on the RootType but we let 
        // let folks use the TypeInfo class as the proxy to get to them.
        // Essentially, they are mostly sugar to simplify coding.
        //
        // For example: 
        //
        // You could either write: 
        // 
        //      typeinfo.RootType.FlattenedType
        // 
        // or you can write:
        //
        //      typeinfo.FlattenedType
        // 

        ///  
        /// Flattened record version of the type 
        /// 
        internal virtual md.RowType FlattenedType 
        {
            get
            {
                return RootType.FlattenedType; 
            }
        } 
 
        /// 
        /// TypeUsage that encloses the Flattened record version of the type 
        /// 
        internal virtual md.TypeUsage FlattenedTypeUsage
        {
            get 
            {
                return RootType.FlattenedTypeUsage; 
            } 
        }
 
        /// 
        /// Get the property describing the entityset (if any)
        /// 
        internal virtual md.EdmProperty EntitySetIdProperty 
        {
            get 
            { 
                return RootType.EntitySetIdProperty;
            } 
        }

        /// 
        /// Does this type have an entitySetId property 
        /// 
        internal bool HasEntitySetIdProperty 
        { 
            get
            { 
                return RootType.EntitySetIdProperty != null;
            }
        }
 
        /// 
        /// Get the nullSentinel property (if any) 
        ///  
        internal virtual md.EdmProperty NullSentinelProperty
        { 
            get
            {
                return RootType.NullSentinelProperty;
            } 
        }
 
        ///  
        /// Does this type have a nullSentinel property?
        ///  
        internal bool HasNullSentinelProperty
        {
            get
            { 
                return RootType.NullSentinelProperty != null;
            } 
        } 

        ///  
        /// The typeid property in the flattened type - applies only to nominal types
        /// this will be used as the type discriminator column.
        /// 
        internal virtual md.EdmProperty TypeIdProperty 
        {
            get 
            { 
                return RootType.TypeIdProperty;
            } 
        }

        /// 
        /// Does this type need a typeid property? (Needed for complex types and entity types in general) 
        /// 
        internal bool HasTypeIdProperty 
        { 
            get
            { 
                return RootType.TypeIdProperty != null;
            }
        }
 
        /// 
        /// All the properties of this type. 
        ///  
        internal virtual IEnumerable PropertyRefList
        { 
            get
            {
                return RootType.PropertyRefList;
            } 
        }
 
        ///  
        /// Get the new property for the supplied propertyRef
        ///  
        /// property reference (on the old type)
        /// 
        internal md.EdmProperty GetNewProperty(PropertyRef propertyRef)
        { 
            return this.RootType.GetNewProperty(propertyRef);
        } 
 
        /// 
        /// Get the list of "key" properties (in the flattened type) 
        /// 
        /// the key property equivalents in the flattened type
        internal IEnumerable GetKeyPropertyRefs()
        { 
            md.EntityTypeBase entityType = null;
            md.RefType refType = null; 
            if (TypeHelpers.TryGetEdmType(m_type, out refType)) 
            {
                entityType = refType.ElementType; 
            }
            else
            {
                entityType = TypeHelpers.GetEdmType(m_type); 
            }
 
            // Walk through the list of keys of the entity type, and find their analogs in the 
            // "flattened" type
            foreach (md.EdmMember p in entityType.KeyMembers) 
            {
                // Eventually this could be RelationshipEndMember, but currently only properties are suppported as key members
                PlanCompiler.Assert(p is md.EdmProperty, "Non-EdmProperty key members are not supported");
                SimplePropertyRef spr = new SimplePropertyRef(p); 
                yield return spr;
            } 
        } 

        ///  
        /// Get the list of "identity" properties in the flattened type.
        /// The identity properties include the entitysetid property, followed by the
        /// key properties
        ///  
        /// List of identity properties
        internal IEnumerable GetIdentityPropertyRefs() 
        { 
            if (this.HasEntitySetIdProperty)
            { 
                yield return EntitySetIdPropertyRef.Instance;
            }
            foreach (PropertyRef p in this.GetKeyPropertyRefs())
            { 
                yield return p;
            } 
        } 

        ///  
        /// Get the list of all properties in the flattened type
        /// 
        /// 
        internal IEnumerable GetAllPropertyRefs() 
        {
            foreach (PropertyRef p in this.PropertyRefList) 
            { 
                yield return p;
            } 
        }

        /// 
        /// Get the list of all properties in the flattened type 
        /// 
        ///  
        internal IEnumerable GetAllProperties() 
        {
            foreach (md.EdmProperty m in this.FlattenedType.Properties) 
            {
                yield return m;
            }
        } 

        ///  
        /// Gets all types in the hierarchy rooted at this. 
        /// 
        internal List GetTypeHierarchy() 
        {
            List result = new List();
            GetTypeHierarchy(result);
            return result; 
        }
 
        ///  
        /// Adds all types in the hierarchy to the given list.
        ///  
        private void GetTypeHierarchy(List result)
        {
            result.Add(this);
            foreach (TypeInfo subType in this.ImmediateSubTypes) 
            {
                subType.GetTypeHierarchy(result); 
            } 
        }
        #endregion 
    }

    /// 
    /// A subclass of the TypeInfo class above that only represents information 
    /// about "root" types
    ///  
    internal class RootTypeInfo : TypeInfo 
    {
 
        #region private state
        private readonly List m_propertyRefList;
        private readonly Dictionary m_propertyMap;
        private md.EdmProperty m_nullSentinelProperty; 
        private md.EdmProperty m_typeIdProperty;
        private TypeIdKind m_typeIdKind; 
        private md.TypeUsage m_typeIdType; 
        private readonly ExplicitDiscriminatorMap m_discriminatorMap;
        private md.EdmProperty m_entitySetIdProperty; 
        private md.RowType m_flattenedType;
        private md.TypeUsage m_flattenedTypeUsage;
        #endregion
 
        #region Constructor
 
        ///  
        /// Constructor for a root type
        ///  
        /// 
        internal RootTypeInfo(md.TypeUsage type, ExplicitDiscriminatorMap discriminatorMap)
            : base(type, null)
        { 
            PlanCompiler.Assert(type.EdmType.BaseType == null, "only root types allowed here");
 
            m_propertyMap = new Dictionary(); 
            m_propertyRefList = new List();
            m_discriminatorMap = discriminatorMap; 
            m_typeIdKind = TypeIdKind.Generated;
        }

        #endregion 

        #region "public" surface area 
 
        /// 
        /// Kind of the typeid column (if any) 
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal TypeIdKind TypeIdKind
        { 
            get { return m_typeIdKind; }
            set { m_typeIdKind = value; } 
        } 

        ///  
        /// Datatype of the typeid column (if any)
        /// 
        internal md.TypeUsage TypeIdType
        { 
            get { return m_typeIdType; }
            set { m_typeIdType = value; } 
        } 
        /// 
        /// Add a mapping from the propertyRef (of the old type) to the 
        /// corresponding property in the new type.
        ///
        /// NOTE: Only to be used by StructuredTypeInfo
        ///  
        /// 
        ///  
        internal void AddPropertyMapping(PropertyRef propertyRef, md.EdmProperty newProperty) 
        {
            m_propertyMap[propertyRef] = newProperty; 
            if (propertyRef is TypeIdPropertyRef)
            {
                m_typeIdProperty = newProperty;
            } 
            else if (propertyRef is EntitySetIdPropertyRef)
            { 
                m_entitySetIdProperty = newProperty; 
            }
            else if (propertyRef is NullSentinelPropertyRef) 
            {
                m_nullSentinelProperty = newProperty;
            }
        } 

        ///  
        /// Adds a new property reference to the list of desired properties 
        /// NOTE: Only to be used by StructuredTypeInfo
        ///  
        /// 
        internal void AddPropertyRef(PropertyRef propertyRef)
        {
            m_propertyRefList.Add(propertyRef); 
        }
 
        ///  
        /// Flattened record version of the type
        ///  
        internal new md.RowType FlattenedType
        {
            get
            { 
                return m_flattenedType;
            } 
            set 
            {
                m_flattenedType = value; 
                m_flattenedTypeUsage = md.TypeUsage.Create(value);
            }
        }
 
        /// 
        /// TypeUsage that encloses the Flattened record version of the type 
        ///  
        internal new md.TypeUsage FlattenedTypeUsage
        { 
            get
            {
                return m_flattenedTypeUsage;
            } 
        }
 
        ///  
        /// Gets map information for types mapped using simple discriminator pattern.
        ///  
        internal ExplicitDiscriminatorMap DiscriminatorMap
        {
            get
            { 
                return m_discriminatorMap;
            } 
        } 

        ///  
        /// Get the property describing the entityset (if any)
        /// 
        internal new md.EdmProperty EntitySetIdProperty
        { 
            get
            { 
                return m_entitySetIdProperty; 
            }
        } 

        internal new md.EdmProperty NullSentinelProperty
        {
            get 
            {
                return m_nullSentinelProperty; 
            } 
        }
 
        /// 
        /// Get the list of property refs for this type
        /// 
        internal new IEnumerable PropertyRefList 
        {
            get 
            { 
                return m_propertyRefList;
            } 
        }

        /// 
        /// Determines the offset for structured types in Flattened type. For instance, if the original type is of the form: 
        ///
        ///     { int X, ComplexType Y } 
        /// 
        /// and the flattened type is of the form:
        /// 
        ///     { int X, Y_ComplexType_Prop1, Y_ComplexType_Prop2 }
        ///
        /// GetNestedStructureOffset(Y) returns 1
        ///  
        /// Complex property.
        /// Offset. 
        internal int GetNestedStructureOffset(PropertyRef property) 
        {
            // m_propertyRefList contains every element of the flattened type 
            for (int i = 0; i < m_propertyRefList.Count; i++)
            {
                NestedPropertyRef nestedPropertyRef = m_propertyRefList[i] as NestedPropertyRef;
 
                // match offset of the first element of the complex type property
                if (null != nestedPropertyRef && nestedPropertyRef.InnerProperty.Equals(property)) 
                { 
                    return i;
                } 
            }
            PlanCompiler.Assert(false, "no complex structure " + property + " found in TypeInfo");
            // return something so that the compiler doesn't complain
            return default(int); 
        }
 
 
        /// 
        /// Get the new property for the supplied propertyRef 
        /// 
        /// property reference (on the old type)
        /// 
        internal new md.EdmProperty GetNewProperty(PropertyRef propertyRef) 
        {
            md.EdmProperty property; 
 
            if (m_propertyMap.TryGetValue(propertyRef, out property))
            { 
                return property;
            }

            PlanCompiler.Assert(false, "Unable to find property " + propertyRef.ToString() + " in type " + this.Type.EdmType.Identity); 
            return null;
        } 
 
        /// 
        /// The typeid property in the flattened type - applies only to nominal types 
        /// this will be used as the type discriminator column.
        /// 
        internal new md.EdmProperty TypeIdProperty
        { 
            get
            { 
                return m_typeIdProperty; 
            }
        } 

        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK