Function.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / Function.cs / 1305376 / Function.cs

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

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; 
using System.Globalization;
using System.Xml; 
using System.Xml.Schema; 
using System.Data;
using System.IO; 
using System.Data.Metadata.Edm;
using System.Data.Entity;

namespace System.Data.EntityModel.SchemaObjectModel 
{
    ///  
    /// class representing the Schema element in the schema 
    /// 
    internal class Function : SchemaType 
    {
        #region Instance Fields
        // if adding properties also add to InitializeObject()!
        private bool _isAggregate = false; 
        private bool _isBuiltIn = false;
        private bool _isNiladicFunction = false; 
        protected bool _isComposable = true; 
        private string _unresolvedEntitySet = null;
        protected FunctionCommandText _commandText = null; 
        private string _storeFunctionName = null;
        protected SchemaType _type = null;
        private string _unresolvedType = null;
        protected bool _isRefType = false; 
        // both are not specified
        protected SchemaElementLookUpTable _parameters = null; 
        protected ReturnType _returnType = null; 
        private CollectionKind _returnTypeCollectionKind = CollectionKind.None;
        private ParameterTypeSemantics _parameterTypeSemantics; 
        private EntityContainer _container = null; // container is known only for function imports
        private EntityContainerEntitySet _entitySet = null;
        private string _schema;
 
        private string _functionStrongName;
        #endregion 
 
        #region Static Fields
 
        private static System.Text.RegularExpressions.Regex s_typeParser = new System.Text.RegularExpressions.Regex(@"^(?((Collection)|(Ref)))\s*\(\s*(?\S*)\s*\)$", System.Text.RegularExpressions.RegexOptions.Compiled);

        /// 
        /// 
        /// 
        ///  
        ///  
        internal static void RemoveTypeModifier(ref string type, out TypeModifier typeModifier, out bool isRefType)
        { 
            isRefType = false;
            typeModifier = TypeModifier.None;

            System.Text.RegularExpressions.Match match = s_typeParser.Match(type); 
            if (match.Success)
            { 
                type = match.Groups["typeName"].Value; 
                switch (match.Groups["modifier"].Value)
                { 
                    case "Collection":
                        typeModifier = TypeModifier.Array;
                        return;
                    case "Ref": 
                        isRefType = true;
                        return; 
                    default: 
                        Debug.Assert(false, "Unexpected modifier: " + match.Groups["modifier"].Value);
                        break; 
                }
            }

        } 
        #endregion
 
        #region Public Methods 
        /// 
        /// ctor for a schema function 
        /// 
        public Function(Schema parentElement)
            :
            base(parentElement) 
        {
        } 
 
        /// 
        /// ctor for a function import, which is scoped to the entity container 
        /// 
        /// Parent container; must not be null.
        protected Function(EntityContainer container)
            : 
            base(container.Schema)
        { 
            if (Schema.DataModel == SchemaDataModelOption.EntityDataModel) 
                OtherContent.Add(Schema.SchemaSource);
 
            Debug.Assert(null != container);
            _container = container;

            // override defaults for function imports 
            _isComposable = false;
        } 
        #endregion 

        #region Public Properties 

        public bool IsAggregate
        {
            get 
            {
                return _isAggregate; 
            } 
            internal set
            { 
                _isAggregate = value;
            }
        }
 
        public bool IsBuiltIn
        { 
            get 
            {
                return _isBuiltIn; 
            }
            internal set
            {
                _isBuiltIn = value; 
            }
        } 
 
        public bool IsNiladicFunction
        { 
            get
            {
                return _isNiladicFunction;
            } 
            internal set
            { 
                _isNiladicFunction = value; 
            }
        } 

        public bool IsComposable
        {
            get 
            {
                return _isComposable; 
            } 
            internal set
            { 
                _isComposable = value;
            }
        }
 
        public string CommandText
        { 
            get 
            {
                if (_commandText != null) 
                {
                    return _commandText.CommandText;
                }
                return null; 
            }
        } 
 
        public ParameterTypeSemantics ParameterTypeSemantics
        { 
            get
            {
                return _parameterTypeSemantics;
            } 
            internal set
            { 
                _parameterTypeSemantics = value; 
            }
        } 

        public string StoreFunctionName
        {
            get 
            {
                return _storeFunctionName; 
            } 
            internal set
            { 
                Debug.Assert(value != null, "StoreFunctionName should never be set null value");
                _storeFunctionName = value;
            }
        } 

        public virtual SchemaType Type 
        { 
            get
            { 
                if (null != this.ReturnType)
                {
                    return this.ReturnType.Type;
                } 
                else return this._type;
            } 
        } 

        public ReturnType ReturnType 
        {
            get
            {
                return this._returnType; 
            }
        } 
 
        public SchemaElementLookUpTable Parameters
        { 
            get
            {
                if (_parameters == null)
                { 
                    _parameters = new SchemaElementLookUpTable();
                } 
                return _parameters; 
            }
        } 

        public CollectionKind CollectionKind
        {
            get 
            {
                return _returnTypeCollectionKind; 
            } 
            internal set
            { 
                _returnTypeCollectionKind = value;
            }
        }
 
        public override string Identity
        { 
            get 
            {
                if (String.IsNullOrEmpty(_functionStrongName)) 
                {
                    string name = this.FQName;
                    System.Text.StringBuilder stringBuilder = new Text.StringBuilder(name);
                    bool first = true; 
                    stringBuilder.Append('(');
                    foreach (Parameter parameter in this.Parameters) 
                    { 
                        if (!first)
                        { 
                            stringBuilder.Append(',');
                        }
                        else
                        { 
                            first = false;
                        } 
                        stringBuilder.Append(Helper.ToString(parameter.ParameterDirection)); 
                        stringBuilder.Append(' ');
                        // we don't include the facets in the identity, since we are *not* 
                        // taking them into consideration inside the
                        // RankFunctionParameters method of TypeResolver.cs

                        parameter.WriteIdentity(stringBuilder); 
                    }
                    stringBuilder.Append(')'); 
                    _functionStrongName = stringBuilder.ToString(); 
                }
                return _functionStrongName; 
            }
        }

        public bool IsReturnAttributeReftype 
        {
            get 
            { 
                return _isRefType;
            } 
        }

        public virtual bool IsFunctionImport { get { return false; } }
 
        public EntityContainerEntitySet EntitySet { get { return _entitySet; } }
 
        public string DbSchema 
        {
            get 
            {
                return _schema;
            }
        } 

        #endregion 
 
        #region Protected Properties
        protected override bool HandleElement(XmlReader reader) 
        {
            if (base.HandleElement(reader))
            {
                return true; 
            }
            else if (CanHandleElement(reader, XmlConstants.CommandText)) 
            { 
                HandleCommandTextFunctionElment(reader);
                return true; 
            }
            else if (CanHandleElement(reader, XmlConstants.Parameter))
            {
                HandleParameterElement(reader); 
                return true;
            } 
            else if (CanHandleElement(reader, XmlConstants.ReturnTypeElement)) 
            {
                if (ParentElement.Schema.DataModel == SchemaDataModelOption.ProviderManifestModel || ParentElement.Schema.DataModel == SchemaDataModelOption.EntityDataModel) 
                {
                    HandleReturnTypeElement(reader);
                }
                else 
                {
                    SkipThroughElement(reader); 
                } 
                return true;
            } 
            return false;
        }

        protected override bool HandleAttribute(XmlReader reader) 
        {
            if (base.HandleAttribute(reader)) 
            { 
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.ReturnType))
            {
                HandleReturnTypeAttribute(reader);
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.AggregateAttribute)) 
            { 
                HandleAggregateAttribute(reader);
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.BuiltInAttribute))
            {
                HandleBuiltInAttribute(reader); 
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.StoreFunctionName)) 
            {
                HandleStoreFunctionNameAttribute(reader); 
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.NiladicFunction))
            { 
                HandleNiladicFunctionAttribute(reader);
                return true; 
            } 
            else if (CanHandleAttribute(reader, XmlConstants.IsComposable))
            { 
                HandleIsComposableFunctionAttribute(reader);
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.ParameterTypeSemantics)) 
            {
                HandleParameterTypeSemanticsAttribute(reader); 
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.Schema)) 
            {
                HandleDbSchemaAttribute(reader);
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.EntitySet))
            { 
                HandleEntitySetAttribute(reader); 
                return true;
            } 


            return false;
        } 
        #endregion
 
        #region Internal Methods 

        internal override void ResolveTopLevelNames() 
        {
            base.ResolveTopLevelNames();

            if (ReturnType != null) 
            {
                // provider manifest 
                Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderManifestModel, 
                                "Only ProviderManifest will allow ReturnType elements");
                ReturnType.ResolveTopLevelNames(); 
            }
            else
            {
                // if resolved, then the _type is not null any more 
                Debug.Assert(this._type == null, "This must be resolved exactly once");
 
                if (null != UnresolvedReturnType) 
                {
                    Debug.Assert(Schema.DataModel != SchemaDataModelOption.ProviderManifestModel, 
                                    "ProviderManifest cannot have ReturnType as an attribute");
                    if (Schema.ResolveTypeName(this, UnresolvedReturnType, out _type))
                    {
                        if (this.IsFunctionImport) 
                        {
                            //csdl 
                            if (!MeetsFunctionImportReturnTypeRequirements(_type)) 
                            {
                                AddError(ErrorCode.FunctionImportUnsupportedReturnType, 
                                    EdmSchemaErrorSeverity.Error,
                                    this,
                                    GetReturnTypeErrorMessage(Schema.SchemaVersion, this.Name)
                                    ); 
                            }
                        } 
                        else if(Schema.DataModel == SchemaDataModelOption.ProviderDataModel) 
                        {
                            // ssdl 
                            if (!(_type is ScalarType))
                            {
                                AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported,
                                         EdmSchemaErrorSeverity.Error, 
                                         this,
                                         System.Data.Entity.Strings.FunctionWithNonScalarTypeNotSupported(_type.FQName, this.FQName)); 
                            } 
                        }
                    } 
                }
            }

            if (IsFunctionImport) 
            {
                Debug.Assert(null != _container, "function imports must know container"); 
                // resolve entity set 
                if (null == _entitySet && null != _unresolvedEntitySet)
                { 
                    _entitySet = _container.FindEntitySet(_unresolvedEntitySet);

                    if (null == _entitySet)
                    { 
                        AddError(ErrorCode.FunctionImportUnknownEntitySet,
                            EdmSchemaErrorSeverity.Error, 
                            System.Data.Entity.Strings.FunctionImportUnknownEntitySet(_unresolvedEntitySet, this.Name)); 
                    }
                } 
            }

            foreach (Parameter parameter in this.Parameters)
            { 
                parameter.ResolveTopLevelNames();
            } 
        } 

        private bool MeetsFunctionImportReturnTypeRequirements(SchemaType type) 
        {
            if (_type is ScalarType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            if (_type is SchemaEntityType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
 
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1_1)
            { 
                if (_type is ScalarType && _returnTypeCollectionKind == CollectionKind.None) return true; 
                if (_type is SchemaEntityType && _returnTypeCollectionKind == CollectionKind.None) return true;
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.None) return true; 
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            }
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV2)
            { 
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            } 
 
            return false;
        } 

        private string GetReturnTypeErrorMessage(double schemaVersion, string functionName)
        {
            string errorMessage; 
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1)
            { 
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV1(functionName); 
            }
            else if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1_1) 
            {
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV1_1(functionName);
            }
            else 
            {
                Debug.Assert( 
                    XmlConstants.EdmVersionForV2 == XmlConstants.SchemaVersionLatest, 
                    "Please update the error message accordingly");
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV2(functionName); 
            }
            return errorMessage;
        }
 

        ///  
        /// Perform local validation on function definition. 
        /// 
        internal override void Validate() 
        {
            base.Validate();

            if (_returnType != null && _type != null) 
            {
                AddError(ErrorCode.ReturnTypeDeclaredAsAttributeAndElement, EdmSchemaErrorSeverity.Error, Strings.ReturnTypeDeclaredAsAttributeAndElement); 
            } 

            if (_commandText != null) 
            {
                _commandText.Validate();
            }
 
            if (Schema.DataModel != SchemaDataModelOption.EntityDataModel)
            { 
                if (null == this.Type) 
                {
                    // only non-composable types can omit return type 
                    if (this.IsComposable)
                    {
                        AddError(ErrorCode.ComposableFunctionWithoutReturnType, EdmSchemaErrorSeverity.Error,
                            Strings.ComposableFunctionMustDeclareReturnType); 
                    }
                } 
                else 
                {
                    // non-composable functions may not declare a return type (except for function imports) 
                    if (!this.IsComposable && !this.IsFunctionImport)
                    {
                        AddError(ErrorCode.NonComposableFunctionWithReturnType, EdmSchemaErrorSeverity.Error,
                            Strings.NonComposableFunctionMustNotDeclareReturnType); 
                    }
                } 
 

                if (IsAggregate) 
                {

                    // Make sure that the function has exactly one parameter and that takes
                    // a collection type 
                    if (Parameters.Count != 1)
                    { 
                        AddError(ErrorCode.InvalidNumberOfParametersForAggregateFunction, 
                                 EdmSchemaErrorSeverity.Error,
                                 this, 
                                 System.Data.Entity.Strings.InvalidNumberOfParametersForAggregateFunction(FQName));
                    }
                    else if (Parameters.GetElementAt(0).CollectionKind == CollectionKind.None)
                    { 
                        // Since we have already checked that there should be exactly one parameter, it should be safe to get the
                        // first parameter for the function 
                        Parameter param = Parameters.GetElementAt(0); 

                        AddError(ErrorCode.InvalidParameterTypeForAggregateFunction, 
                                 EdmSchemaErrorSeverity.Error,
                                 this,
                                 System.Data.Entity.Strings.InvalidParameterTypeForAggregateFunction(param.Name, FQName));
                    } 

                } 
 

                if (!this.IsComposable) 
                {
                    // non-composable functions do not permit aggregate, build-in, or niladic attribute
                    if (this.IsAggregate ||
                        this.IsNiladicFunction || 
                        this.IsBuiltIn)
                    { 
                        AddError(ErrorCode.NonComposableFunctionAttributesNotValid, EdmSchemaErrorSeverity.Error, 
                            Strings.NonComposableFunctionHasDisallowedAttribute);
                    } 
                }

                if (null != this.CommandText)
                { 
                    // functions with command text are not composable
                    if (this.IsComposable) 
                    { 
                        AddError(ErrorCode.ComposableFunctionWithCommandText, EdmSchemaErrorSeverity.Error,
                            Strings.CommandTextFunctionsNotComposable); 
                    }

                    // functions with command text cannot declare store function name
                    if (null != this.StoreFunctionName) 
                    {
                        AddError(ErrorCode.FunctionDeclaresCommandTextAndStoreFunctionName, EdmSchemaErrorSeverity.Error, 
                            Strings.CommandTextFunctionsCannotDeclareStoreFunctionName); 
                    }
                } 
            }

            if (this.IsFunctionImport)
            { 
                ValidateReturnType(this.Type);
            } 
        } 

        internal override void ResolveSecondLevelNames() 
        {
            foreach (var parameter in _parameters)
            {
                parameter.ResolveSecondLevelNames(); 
            }
        } 
 
        /// 
        /// validate the following negative scenarios: 
        /// ReturnType="Collection(EntityTypeA)"
        /// ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
        /// EntitySet="A"
        /// ReturnType="Collection(ComplexTypeA)" EntitySet="something" 
        /// ReturnType="Collection(ComplexTypeA)", but the ComplexTypeA has a nested complexType property, this scenario will be handle in the runtime
        ///  
        ///  
        private void ValidateReturnType(SchemaType returnType)
        { 
            // if entity type, verify specification of entity set and that the type is appropriate
            // for the entity set
            SchemaEntityType entityType = returnType as SchemaEntityType;
 
            if (null != entityType)
            { 
                // entity type 
                if (null == this.EntitySet)
                { 
                    // ReturnType="Collection(EntityTypeA)"
                    AddError(ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        System.Data.Entity.Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(this.Name)); 
                }
                else if (null != this.EntitySet.EntityType && 
                    !entityType.IsOfType(this.EntitySet.EntityType)) 
                {
                    // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA" 
                    AddError(ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        System.Data.Entity.Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                        this.FQName, this.EntitySet.EntityType.FQName, this.EntitySet.Name, this.ParentElement.FQName)); 
                }
            } 
            else 
            {
                // complex type 
                SchemaComplexType complexType = returnType as SchemaComplexType;
                if (null != complexType)
                {
                    if (null != EntitySet) 
                    {
                        // ReturnType="Collection(ComplexTypeA)" EntitySet="something" 
                        AddError( 
                            ErrorCode.ComplexTypeAsReturnTypeAndDefinedEntitySet,
                            EdmSchemaErrorSeverity.Error, 
                            this.LineNumber,
                            this.LinePosition,
                            System.Data.Entity.Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(
                                this.Name, complexType.Name, EntitySet.Name)); 
                    }
                } 
                else 
                {
                    // scalar type or no return type 
                    if (null != EntitySet)
                    {
                        // EntitySet="A"
                        AddError(ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType, 
                            EdmSchemaErrorSeverity.Error,
                            System.Data.Entity.Strings.FunctionImportSpecifiesEntitySetButNotEntityType(this.Name, this.ParentElement.FQName)); 
                    } 
                }
            } 
        }

        internal override SchemaElement Clone(SchemaElement parentElement)
        { 
            Debug.Assert(IsFunctionImport, "we only support clone for FunctionImports");
            Function function = new FunctionImportElement((EntityContainer)parentElement); 
            function._isAggregate = _isAggregate; 
            function._isBuiltIn = _isBuiltIn;
            function._isNiladicFunction = _isNiladicFunction; 
            function._isComposable = _isComposable;
            function._entitySet = _entitySet;
            function._commandText = _commandText;
            function._storeFunctionName = _storeFunctionName; 
            function._type = _type;
            function._returnType = _returnType; 
            function._returnTypeCollectionKind = _returnTypeCollectionKind; 
            function._parameterTypeSemantics = _parameterTypeSemantics;
            function._schema = _schema; 
            function.Name = this.Name;

            // Clone all the parameters
            foreach (Parameter parameter in this.Parameters) 
            {
                AddErrorKind error = function.Parameters.TryAdd((Parameter)parameter.Clone(function)); 
                Debug.Assert(error == AddErrorKind.Succeeded, "Since we are cloning a validated function, this should never fail"); 
            }
 
            return function;
        }
        #endregion
 
        #region Internal Properties
        ///  
        /// 
        /// 
        ///  
        internal string UnresolvedReturnType
        {
            get
            { 
                return _unresolvedType;
            } 
            set 
            {
                _unresolvedType = value; 
            }
        }
        #endregion //Internal Properties
 
        #region Private Methods
 
        ///  
        /// The method that is called when a DbSchema attribute is encountered.
        ///  
        /// An XmlReader positioned at the Type attribute.
        private void HandleDbSchemaAttribute(XmlReader reader)
        {
            Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl"); 
            Debug.Assert(reader != null);
 
            _schema = reader.Value; 
        }
 
        /// 
        /// Handler for the Version attribute
        /// 
        /// xml reader currently positioned at Version attribute 
        private void HandleAggregateAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null); 
            bool isAggregate = false;
            HandleBoolAttribute(reader, ref isAggregate); 
            IsAggregate = isAggregate;
        }

        ///  
        /// Handler for the Namespace attribute
        ///  
        /// xml reader currently positioned at Namespace attribute 
        private void HandleBuiltInAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null);
            bool isBuiltIn = false;
            HandleBoolAttribute(reader, ref isBuiltIn);
            IsBuiltIn = isBuiltIn; 
        }
 
        ///  
        /// Handler for the Alias attribute
        ///  
        /// xml reader currently positioned at Alias attribute
        private void HandleStoreFunctionNameAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            string value = reader.Value.ToString();
            if (!String.IsNullOrEmpty(value)) 
            { 
                value = value.Trim();
                StoreFunctionName = value; 
            }
        }

        ///  
        /// Handler for the NiladicFunction attribute
        ///  
        /// xml reader currently positioned at Namespace attribute 
        private void HandleNiladicFunctionAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null);
            bool isNiladicFunction = false;
            HandleBoolAttribute(reader, ref isNiladicFunction);
            IsNiladicFunction = isNiladicFunction; 
        }
 
        ///  
        /// Handler for the IsComposable attribute
        ///  
        /// xml reader currently positioned at Namespace attribute
        private void HandleIsComposableFunctionAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            bool isComposable = true;
            HandleBoolAttribute(reader, ref isComposable); 
            IsComposable = isComposable; 
        }
 
        private void HandleCommandTextFunctionElment(XmlReader reader)
        {
            Debug.Assert(reader != null);
 
            FunctionCommandText commandText = new FunctionCommandText(this);
            commandText.Parse(reader); 
            _commandText = commandText; 
        }
 
        protected virtual void HandleReturnTypeAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null);
            Debug.Assert(UnresolvedReturnType == null); 

            string type; 
            if (!Utils.GetString(Schema, reader, out type)) 
                return;
 
            TypeModifier typeModifier;

            RemoveTypeModifier(ref type, out typeModifier, out _isRefType);
 
            switch (typeModifier)
            { 
                case TypeModifier.Array: 
                    CollectionKind = CollectionKind.Bag;
                    break; 
                case TypeModifier.None:
                    break;
                default:
                    Debug.Assert(false, "RemoveTypeModifier already checks for this"); 
                    break;
            } 
 
            if (!Utils.ValidateDottedName(Schema, reader, type))
                return; 

            UnresolvedReturnType = type;
        }
 
        /// 
        /// Handler for the Parameter Element 
        ///  
        /// xml reader currently positioned at Parameter Element
        protected void HandleParameterElement(XmlReader reader) 
        {
            Debug.Assert(reader != null);

            Parameter parameter = new Parameter(this); 

            parameter.Parse(reader); 
 
            Parameters.Add(parameter, true, Strings.ParameterNameAlreadyDefinedDuplicate);
        } 

        /// 
        /// Handler for the ReturnType element
        ///  
        /// xml reader currently positioned at ReturnType element
        protected void HandleReturnTypeElement(XmlReader reader) 
        { 
            Debug.Assert(reader != null);
 
            ReturnType returnType = new ReturnType(this);

            returnType.Parse(reader);
 
            this._returnType = returnType;
 
        } 

 
        /// 
        /// Handles ParameterTypeSemantics attribute
        /// 
        ///  
        private void HandleParameterTypeSemanticsAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null); 

            string value = reader.Value; 

            if (String.IsNullOrEmpty(value))
            {
                return; 
            }
 
            value = value.Trim(); 

            if (!String.IsNullOrEmpty(value)) 
            {
                switch (value)
                {
                    case "ExactMatchOnly": 
                        ParameterTypeSemantics = ParameterTypeSemantics.ExactMatchOnly;
                        break; 
                    case "AllowImplicitPromotion": 
                        ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitPromotion;
                        break; 
                    case "AllowImplicitConversion":
                        ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion;
                        break;
                    default: 
                        // don't try to use the name of the function, because we are still parsing the
                        // attributes, and we may not be to the name attribute yet. 
                        AddError(ErrorCode.InvalidValueForParameterTypeSemantics, EdmSchemaErrorSeverity.Error, reader, 
                            System.Data.Entity.Strings.InvalidValueForParameterTypeSemanticsAttribute(
                                          value)); 

                        break;
                }
            } 
        }
 
        ///  
        /// Handler for the EntitySet attribute
        ///  
        /// xml reader currently positioned at EntitySet attribute
        private void HandleEntitySetAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            string entitySetName;
            if (Utils.GetString(Schema, reader, out entitySetName)) 
            { 
                _unresolvedEntitySet = entitySetName;
            } 
        }

        #endregion
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; 
using System.Globalization;
using System.Xml; 
using System.Xml.Schema; 
using System.Data;
using System.IO; 
using System.Data.Metadata.Edm;
using System.Data.Entity;

namespace System.Data.EntityModel.SchemaObjectModel 
{
    ///  
    /// class representing the Schema element in the schema 
    /// 
    internal class Function : SchemaType 
    {
        #region Instance Fields
        // if adding properties also add to InitializeObject()!
        private bool _isAggregate = false; 
        private bool _isBuiltIn = false;
        private bool _isNiladicFunction = false; 
        protected bool _isComposable = true; 
        private string _unresolvedEntitySet = null;
        protected FunctionCommandText _commandText = null; 
        private string _storeFunctionName = null;
        protected SchemaType _type = null;
        private string _unresolvedType = null;
        protected bool _isRefType = false; 
        // both are not specified
        protected SchemaElementLookUpTable _parameters = null; 
        protected ReturnType _returnType = null; 
        private CollectionKind _returnTypeCollectionKind = CollectionKind.None;
        private ParameterTypeSemantics _parameterTypeSemantics; 
        private EntityContainer _container = null; // container is known only for function imports
        private EntityContainerEntitySet _entitySet = null;
        private string _schema;
 
        private string _functionStrongName;
        #endregion 
 
        #region Static Fields
 
        private static System.Text.RegularExpressions.Regex s_typeParser = new System.Text.RegularExpressions.Regex(@"^(?((Collection)|(Ref)))\s*\(\s*(?\S*)\s*\)$", System.Text.RegularExpressions.RegexOptions.Compiled);

        /// 
        /// 
        /// 
        ///  
        ///  
        internal static void RemoveTypeModifier(ref string type, out TypeModifier typeModifier, out bool isRefType)
        { 
            isRefType = false;
            typeModifier = TypeModifier.None;

            System.Text.RegularExpressions.Match match = s_typeParser.Match(type); 
            if (match.Success)
            { 
                type = match.Groups["typeName"].Value; 
                switch (match.Groups["modifier"].Value)
                { 
                    case "Collection":
                        typeModifier = TypeModifier.Array;
                        return;
                    case "Ref": 
                        isRefType = true;
                        return; 
                    default: 
                        Debug.Assert(false, "Unexpected modifier: " + match.Groups["modifier"].Value);
                        break; 
                }
            }

        } 
        #endregion
 
        #region Public Methods 
        /// 
        /// ctor for a schema function 
        /// 
        public Function(Schema parentElement)
            :
            base(parentElement) 
        {
        } 
 
        /// 
        /// ctor for a function import, which is scoped to the entity container 
        /// 
        /// Parent container; must not be null.
        protected Function(EntityContainer container)
            : 
            base(container.Schema)
        { 
            if (Schema.DataModel == SchemaDataModelOption.EntityDataModel) 
                OtherContent.Add(Schema.SchemaSource);
 
            Debug.Assert(null != container);
            _container = container;

            // override defaults for function imports 
            _isComposable = false;
        } 
        #endregion 

        #region Public Properties 

        public bool IsAggregate
        {
            get 
            {
                return _isAggregate; 
            } 
            internal set
            { 
                _isAggregate = value;
            }
        }
 
        public bool IsBuiltIn
        { 
            get 
            {
                return _isBuiltIn; 
            }
            internal set
            {
                _isBuiltIn = value; 
            }
        } 
 
        public bool IsNiladicFunction
        { 
            get
            {
                return _isNiladicFunction;
            } 
            internal set
            { 
                _isNiladicFunction = value; 
            }
        } 

        public bool IsComposable
        {
            get 
            {
                return _isComposable; 
            } 
            internal set
            { 
                _isComposable = value;
            }
        }
 
        public string CommandText
        { 
            get 
            {
                if (_commandText != null) 
                {
                    return _commandText.CommandText;
                }
                return null; 
            }
        } 
 
        public ParameterTypeSemantics ParameterTypeSemantics
        { 
            get
            {
                return _parameterTypeSemantics;
            } 
            internal set
            { 
                _parameterTypeSemantics = value; 
            }
        } 

        public string StoreFunctionName
        {
            get 
            {
                return _storeFunctionName; 
            } 
            internal set
            { 
                Debug.Assert(value != null, "StoreFunctionName should never be set null value");
                _storeFunctionName = value;
            }
        } 

        public virtual SchemaType Type 
        { 
            get
            { 
                if (null != this.ReturnType)
                {
                    return this.ReturnType.Type;
                } 
                else return this._type;
            } 
        } 

        public ReturnType ReturnType 
        {
            get
            {
                return this._returnType; 
            }
        } 
 
        public SchemaElementLookUpTable Parameters
        { 
            get
            {
                if (_parameters == null)
                { 
                    _parameters = new SchemaElementLookUpTable();
                } 
                return _parameters; 
            }
        } 

        public CollectionKind CollectionKind
        {
            get 
            {
                return _returnTypeCollectionKind; 
            } 
            internal set
            { 
                _returnTypeCollectionKind = value;
            }
        }
 
        public override string Identity
        { 
            get 
            {
                if (String.IsNullOrEmpty(_functionStrongName)) 
                {
                    string name = this.FQName;
                    System.Text.StringBuilder stringBuilder = new Text.StringBuilder(name);
                    bool first = true; 
                    stringBuilder.Append('(');
                    foreach (Parameter parameter in this.Parameters) 
                    { 
                        if (!first)
                        { 
                            stringBuilder.Append(',');
                        }
                        else
                        { 
                            first = false;
                        } 
                        stringBuilder.Append(Helper.ToString(parameter.ParameterDirection)); 
                        stringBuilder.Append(' ');
                        // we don't include the facets in the identity, since we are *not* 
                        // taking them into consideration inside the
                        // RankFunctionParameters method of TypeResolver.cs

                        parameter.WriteIdentity(stringBuilder); 
                    }
                    stringBuilder.Append(')'); 
                    _functionStrongName = stringBuilder.ToString(); 
                }
                return _functionStrongName; 
            }
        }

        public bool IsReturnAttributeReftype 
        {
            get 
            { 
                return _isRefType;
            } 
        }

        public virtual bool IsFunctionImport { get { return false; } }
 
        public EntityContainerEntitySet EntitySet { get { return _entitySet; } }
 
        public string DbSchema 
        {
            get 
            {
                return _schema;
            }
        } 

        #endregion 
 
        #region Protected Properties
        protected override bool HandleElement(XmlReader reader) 
        {
            if (base.HandleElement(reader))
            {
                return true; 
            }
            else if (CanHandleElement(reader, XmlConstants.CommandText)) 
            { 
                HandleCommandTextFunctionElment(reader);
                return true; 
            }
            else if (CanHandleElement(reader, XmlConstants.Parameter))
            {
                HandleParameterElement(reader); 
                return true;
            } 
            else if (CanHandleElement(reader, XmlConstants.ReturnTypeElement)) 
            {
                if (ParentElement.Schema.DataModel == SchemaDataModelOption.ProviderManifestModel || ParentElement.Schema.DataModel == SchemaDataModelOption.EntityDataModel) 
                {
                    HandleReturnTypeElement(reader);
                }
                else 
                {
                    SkipThroughElement(reader); 
                } 
                return true;
            } 
            return false;
        }

        protected override bool HandleAttribute(XmlReader reader) 
        {
            if (base.HandleAttribute(reader)) 
            { 
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.ReturnType))
            {
                HandleReturnTypeAttribute(reader);
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.AggregateAttribute)) 
            { 
                HandleAggregateAttribute(reader);
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.BuiltInAttribute))
            {
                HandleBuiltInAttribute(reader); 
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.StoreFunctionName)) 
            {
                HandleStoreFunctionNameAttribute(reader); 
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.NiladicFunction))
            { 
                HandleNiladicFunctionAttribute(reader);
                return true; 
            } 
            else if (CanHandleAttribute(reader, XmlConstants.IsComposable))
            { 
                HandleIsComposableFunctionAttribute(reader);
                return true;
            }
            else if (CanHandleAttribute(reader, XmlConstants.ParameterTypeSemantics)) 
            {
                HandleParameterTypeSemanticsAttribute(reader); 
                return true; 
            }
            else if (CanHandleAttribute(reader, XmlConstants.Schema)) 
            {
                HandleDbSchemaAttribute(reader);
                return true;
            } 
            else if (CanHandleAttribute(reader, XmlConstants.EntitySet))
            { 
                HandleEntitySetAttribute(reader); 
                return true;
            } 


            return false;
        } 
        #endregion
 
        #region Internal Methods 

        internal override void ResolveTopLevelNames() 
        {
            base.ResolveTopLevelNames();

            if (ReturnType != null) 
            {
                // provider manifest 
                Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderManifestModel, 
                                "Only ProviderManifest will allow ReturnType elements");
                ReturnType.ResolveTopLevelNames(); 
            }
            else
            {
                // if resolved, then the _type is not null any more 
                Debug.Assert(this._type == null, "This must be resolved exactly once");
 
                if (null != UnresolvedReturnType) 
                {
                    Debug.Assert(Schema.DataModel != SchemaDataModelOption.ProviderManifestModel, 
                                    "ProviderManifest cannot have ReturnType as an attribute");
                    if (Schema.ResolveTypeName(this, UnresolvedReturnType, out _type))
                    {
                        if (this.IsFunctionImport) 
                        {
                            //csdl 
                            if (!MeetsFunctionImportReturnTypeRequirements(_type)) 
                            {
                                AddError(ErrorCode.FunctionImportUnsupportedReturnType, 
                                    EdmSchemaErrorSeverity.Error,
                                    this,
                                    GetReturnTypeErrorMessage(Schema.SchemaVersion, this.Name)
                                    ); 
                            }
                        } 
                        else if(Schema.DataModel == SchemaDataModelOption.ProviderDataModel) 
                        {
                            // ssdl 
                            if (!(_type is ScalarType))
                            {
                                AddError(ErrorCode.FunctionWithNonScalarTypeNotSupported,
                                         EdmSchemaErrorSeverity.Error, 
                                         this,
                                         System.Data.Entity.Strings.FunctionWithNonScalarTypeNotSupported(_type.FQName, this.FQName)); 
                            } 
                        }
                    } 
                }
            }

            if (IsFunctionImport) 
            {
                Debug.Assert(null != _container, "function imports must know container"); 
                // resolve entity set 
                if (null == _entitySet && null != _unresolvedEntitySet)
                { 
                    _entitySet = _container.FindEntitySet(_unresolvedEntitySet);

                    if (null == _entitySet)
                    { 
                        AddError(ErrorCode.FunctionImportUnknownEntitySet,
                            EdmSchemaErrorSeverity.Error, 
                            System.Data.Entity.Strings.FunctionImportUnknownEntitySet(_unresolvedEntitySet, this.Name)); 
                    }
                } 
            }

            foreach (Parameter parameter in this.Parameters)
            { 
                parameter.ResolveTopLevelNames();
            } 
        } 

        private bool MeetsFunctionImportReturnTypeRequirements(SchemaType type) 
        {
            if (_type is ScalarType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            if (_type is SchemaEntityType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
 
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1_1)
            { 
                if (_type is ScalarType && _returnTypeCollectionKind == CollectionKind.None) return true; 
                if (_type is SchemaEntityType && _returnTypeCollectionKind == CollectionKind.None) return true;
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.None) return true; 
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            }
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV2)
            { 
                if (_type is SchemaComplexType && _returnTypeCollectionKind == CollectionKind.Bag) return true;
            } 
 
            return false;
        } 

        private string GetReturnTypeErrorMessage(double schemaVersion, string functionName)
        {
            string errorMessage; 
            if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1)
            { 
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV1(functionName); 
            }
            else if (Schema.SchemaVersion == XmlConstants.EdmVersionForV1_1) 
            {
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV1_1(functionName);
            }
            else 
            {
                Debug.Assert( 
                    XmlConstants.EdmVersionForV2 == XmlConstants.SchemaVersionLatest, 
                    "Please update the error message accordingly");
                errorMessage = Strings.FunctionImportWithUnsupportedReturnTypeV2(functionName); 
            }
            return errorMessage;
        }
 

        ///  
        /// Perform local validation on function definition. 
        /// 
        internal override void Validate() 
        {
            base.Validate();

            if (_returnType != null && _type != null) 
            {
                AddError(ErrorCode.ReturnTypeDeclaredAsAttributeAndElement, EdmSchemaErrorSeverity.Error, Strings.ReturnTypeDeclaredAsAttributeAndElement); 
            } 

            if (_commandText != null) 
            {
                _commandText.Validate();
            }
 
            if (Schema.DataModel != SchemaDataModelOption.EntityDataModel)
            { 
                if (null == this.Type) 
                {
                    // only non-composable types can omit return type 
                    if (this.IsComposable)
                    {
                        AddError(ErrorCode.ComposableFunctionWithoutReturnType, EdmSchemaErrorSeverity.Error,
                            Strings.ComposableFunctionMustDeclareReturnType); 
                    }
                } 
                else 
                {
                    // non-composable functions may not declare a return type (except for function imports) 
                    if (!this.IsComposable && !this.IsFunctionImport)
                    {
                        AddError(ErrorCode.NonComposableFunctionWithReturnType, EdmSchemaErrorSeverity.Error,
                            Strings.NonComposableFunctionMustNotDeclareReturnType); 
                    }
                } 
 

                if (IsAggregate) 
                {

                    // Make sure that the function has exactly one parameter and that takes
                    // a collection type 
                    if (Parameters.Count != 1)
                    { 
                        AddError(ErrorCode.InvalidNumberOfParametersForAggregateFunction, 
                                 EdmSchemaErrorSeverity.Error,
                                 this, 
                                 System.Data.Entity.Strings.InvalidNumberOfParametersForAggregateFunction(FQName));
                    }
                    else if (Parameters.GetElementAt(0).CollectionKind == CollectionKind.None)
                    { 
                        // Since we have already checked that there should be exactly one parameter, it should be safe to get the
                        // first parameter for the function 
                        Parameter param = Parameters.GetElementAt(0); 

                        AddError(ErrorCode.InvalidParameterTypeForAggregateFunction, 
                                 EdmSchemaErrorSeverity.Error,
                                 this,
                                 System.Data.Entity.Strings.InvalidParameterTypeForAggregateFunction(param.Name, FQName));
                    } 

                } 
 

                if (!this.IsComposable) 
                {
                    // non-composable functions do not permit aggregate, build-in, or niladic attribute
                    if (this.IsAggregate ||
                        this.IsNiladicFunction || 
                        this.IsBuiltIn)
                    { 
                        AddError(ErrorCode.NonComposableFunctionAttributesNotValid, EdmSchemaErrorSeverity.Error, 
                            Strings.NonComposableFunctionHasDisallowedAttribute);
                    } 
                }

                if (null != this.CommandText)
                { 
                    // functions with command text are not composable
                    if (this.IsComposable) 
                    { 
                        AddError(ErrorCode.ComposableFunctionWithCommandText, EdmSchemaErrorSeverity.Error,
                            Strings.CommandTextFunctionsNotComposable); 
                    }

                    // functions with command text cannot declare store function name
                    if (null != this.StoreFunctionName) 
                    {
                        AddError(ErrorCode.FunctionDeclaresCommandTextAndStoreFunctionName, EdmSchemaErrorSeverity.Error, 
                            Strings.CommandTextFunctionsCannotDeclareStoreFunctionName); 
                    }
                } 
            }

            if (this.IsFunctionImport)
            { 
                ValidateReturnType(this.Type);
            } 
        } 

        internal override void ResolveSecondLevelNames() 
        {
            foreach (var parameter in _parameters)
            {
                parameter.ResolveSecondLevelNames(); 
            }
        } 
 
        /// 
        /// validate the following negative scenarios: 
        /// ReturnType="Collection(EntityTypeA)"
        /// ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA"
        /// EntitySet="A"
        /// ReturnType="Collection(ComplexTypeA)" EntitySet="something" 
        /// ReturnType="Collection(ComplexTypeA)", but the ComplexTypeA has a nested complexType property, this scenario will be handle in the runtime
        ///  
        ///  
        private void ValidateReturnType(SchemaType returnType)
        { 
            // if entity type, verify specification of entity set and that the type is appropriate
            // for the entity set
            SchemaEntityType entityType = returnType as SchemaEntityType;
 
            if (null != entityType)
            { 
                // entity type 
                if (null == this.EntitySet)
                { 
                    // ReturnType="Collection(EntityTypeA)"
                    AddError(ErrorCode.FunctionImportReturnsEntitiesButDoesNotSpecifyEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        System.Data.Entity.Strings.FunctionImportReturnEntitiesButDoesNotSpecifyEntitySet(this.Name)); 
                }
                else if (null != this.EntitySet.EntityType && 
                    !entityType.IsOfType(this.EntitySet.EntityType)) 
                {
                    // ReturnType="Collection(EntityTypeA)" EntitySet="ESet.EType is not oftype EntityTypeA" 
                    AddError(ErrorCode.FunctionImportEntityTypeDoesNotMatchEntitySet,
                        EdmSchemaErrorSeverity.Error,
                        System.Data.Entity.Strings.FunctionImportEntityTypeDoesNotMatchEntitySet(
                        this.FQName, this.EntitySet.EntityType.FQName, this.EntitySet.Name, this.ParentElement.FQName)); 
                }
            } 
            else 
            {
                // complex type 
                SchemaComplexType complexType = returnType as SchemaComplexType;
                if (null != complexType)
                {
                    if (null != EntitySet) 
                    {
                        // ReturnType="Collection(ComplexTypeA)" EntitySet="something" 
                        AddError( 
                            ErrorCode.ComplexTypeAsReturnTypeAndDefinedEntitySet,
                            EdmSchemaErrorSeverity.Error, 
                            this.LineNumber,
                            this.LinePosition,
                            System.Data.Entity.Strings.ComplexTypeAsReturnTypeAndDefinedEntitySet(
                                this.Name, complexType.Name, EntitySet.Name)); 
                    }
                } 
                else 
                {
                    // scalar type or no return type 
                    if (null != EntitySet)
                    {
                        // EntitySet="A"
                        AddError(ErrorCode.FunctionImportSpecifiesEntitySetButDoesNotReturnEntityType, 
                            EdmSchemaErrorSeverity.Error,
                            System.Data.Entity.Strings.FunctionImportSpecifiesEntitySetButNotEntityType(this.Name, this.ParentElement.FQName)); 
                    } 
                }
            } 
        }

        internal override SchemaElement Clone(SchemaElement parentElement)
        { 
            Debug.Assert(IsFunctionImport, "we only support clone for FunctionImports");
            Function function = new FunctionImportElement((EntityContainer)parentElement); 
            function._isAggregate = _isAggregate; 
            function._isBuiltIn = _isBuiltIn;
            function._isNiladicFunction = _isNiladicFunction; 
            function._isComposable = _isComposable;
            function._entitySet = _entitySet;
            function._commandText = _commandText;
            function._storeFunctionName = _storeFunctionName; 
            function._type = _type;
            function._returnType = _returnType; 
            function._returnTypeCollectionKind = _returnTypeCollectionKind; 
            function._parameterTypeSemantics = _parameterTypeSemantics;
            function._schema = _schema; 
            function.Name = this.Name;

            // Clone all the parameters
            foreach (Parameter parameter in this.Parameters) 
            {
                AddErrorKind error = function.Parameters.TryAdd((Parameter)parameter.Clone(function)); 
                Debug.Assert(error == AddErrorKind.Succeeded, "Since we are cloning a validated function, this should never fail"); 
            }
 
            return function;
        }
        #endregion
 
        #region Internal Properties
        ///  
        /// 
        /// 
        ///  
        internal string UnresolvedReturnType
        {
            get
            { 
                return _unresolvedType;
            } 
            set 
            {
                _unresolvedType = value; 
            }
        }
        #endregion //Internal Properties
 
        #region Private Methods
 
        ///  
        /// The method that is called when a DbSchema attribute is encountered.
        ///  
        /// An XmlReader positioned at the Type attribute.
        private void HandleDbSchemaAttribute(XmlReader reader)
        {
            Debug.Assert(Schema.DataModel == SchemaDataModelOption.ProviderDataModel, "We shouldn't see this attribute unless we are parsing ssdl"); 
            Debug.Assert(reader != null);
 
            _schema = reader.Value; 
        }
 
        /// 
        /// Handler for the Version attribute
        /// 
        /// xml reader currently positioned at Version attribute 
        private void HandleAggregateAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null); 
            bool isAggregate = false;
            HandleBoolAttribute(reader, ref isAggregate); 
            IsAggregate = isAggregate;
        }

        ///  
        /// Handler for the Namespace attribute
        ///  
        /// xml reader currently positioned at Namespace attribute 
        private void HandleBuiltInAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null);
            bool isBuiltIn = false;
            HandleBoolAttribute(reader, ref isBuiltIn);
            IsBuiltIn = isBuiltIn; 
        }
 
        ///  
        /// Handler for the Alias attribute
        ///  
        /// xml reader currently positioned at Alias attribute
        private void HandleStoreFunctionNameAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            string value = reader.Value.ToString();
            if (!String.IsNullOrEmpty(value)) 
            { 
                value = value.Trim();
                StoreFunctionName = value; 
            }
        }

        ///  
        /// Handler for the NiladicFunction attribute
        ///  
        /// xml reader currently positioned at Namespace attribute 
        private void HandleNiladicFunctionAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null);
            bool isNiladicFunction = false;
            HandleBoolAttribute(reader, ref isNiladicFunction);
            IsNiladicFunction = isNiladicFunction; 
        }
 
        ///  
        /// Handler for the IsComposable attribute
        ///  
        /// xml reader currently positioned at Namespace attribute
        private void HandleIsComposableFunctionAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            bool isComposable = true;
            HandleBoolAttribute(reader, ref isComposable); 
            IsComposable = isComposable; 
        }
 
        private void HandleCommandTextFunctionElment(XmlReader reader)
        {
            Debug.Assert(reader != null);
 
            FunctionCommandText commandText = new FunctionCommandText(this);
            commandText.Parse(reader); 
            _commandText = commandText; 
        }
 
        protected virtual void HandleReturnTypeAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null);
            Debug.Assert(UnresolvedReturnType == null); 

            string type; 
            if (!Utils.GetString(Schema, reader, out type)) 
                return;
 
            TypeModifier typeModifier;

            RemoveTypeModifier(ref type, out typeModifier, out _isRefType);
 
            switch (typeModifier)
            { 
                case TypeModifier.Array: 
                    CollectionKind = CollectionKind.Bag;
                    break; 
                case TypeModifier.None:
                    break;
                default:
                    Debug.Assert(false, "RemoveTypeModifier already checks for this"); 
                    break;
            } 
 
            if (!Utils.ValidateDottedName(Schema, reader, type))
                return; 

            UnresolvedReturnType = type;
        }
 
        /// 
        /// Handler for the Parameter Element 
        ///  
        /// xml reader currently positioned at Parameter Element
        protected void HandleParameterElement(XmlReader reader) 
        {
            Debug.Assert(reader != null);

            Parameter parameter = new Parameter(this); 

            parameter.Parse(reader); 
 
            Parameters.Add(parameter, true, Strings.ParameterNameAlreadyDefinedDuplicate);
        } 

        /// 
        /// Handler for the ReturnType element
        ///  
        /// xml reader currently positioned at ReturnType element
        protected void HandleReturnTypeElement(XmlReader reader) 
        { 
            Debug.Assert(reader != null);
 
            ReturnType returnType = new ReturnType(this);

            returnType.Parse(reader);
 
            this._returnType = returnType;
 
        } 

 
        /// 
        /// Handles ParameterTypeSemantics attribute
        /// 
        ///  
        private void HandleParameterTypeSemanticsAttribute(XmlReader reader)
        { 
            Debug.Assert(reader != null); 

            string value = reader.Value; 

            if (String.IsNullOrEmpty(value))
            {
                return; 
            }
 
            value = value.Trim(); 

            if (!String.IsNullOrEmpty(value)) 
            {
                switch (value)
                {
                    case "ExactMatchOnly": 
                        ParameterTypeSemantics = ParameterTypeSemantics.ExactMatchOnly;
                        break; 
                    case "AllowImplicitPromotion": 
                        ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitPromotion;
                        break; 
                    case "AllowImplicitConversion":
                        ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion;
                        break;
                    default: 
                        // don't try to use the name of the function, because we are still parsing the
                        // attributes, and we may not be to the name attribute yet. 
                        AddError(ErrorCode.InvalidValueForParameterTypeSemantics, EdmSchemaErrorSeverity.Error, reader, 
                            System.Data.Entity.Strings.InvalidValueForParameterTypeSemanticsAttribute(
                                          value)); 

                        break;
                }
            } 
        }
 
        ///  
        /// Handler for the EntitySet attribute
        ///  
        /// xml reader currently positioned at EntitySet attribute
        private void HandleEntitySetAttribute(XmlReader reader)
        {
            Debug.Assert(reader != null); 
            string entitySetName;
            if (Utils.GetString(Schema, reader, out entitySetName)) 
            { 
                _unresolvedEntitySet = entitySetName;
            } 
        }

        #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