1 //--------------------------------------------------------------------- 2 // <copyright file="EdmProviderManifestFunctionBuilder.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // 6 // @owner Microsoft 7 // @backupOwner Microsoft 8 //--------------------------------------------------------------------- 9 10 using System.Collections.Generic; 11 using System.Diagnostics; 12 using System.Linq; 13 14 namespace System.Data.Metadata.Edm 15 { 16 internal sealed class EdmProviderManifestFunctionBuilder 17 { 18 private readonly List<EdmFunction> functions = new List<EdmFunction>(); 19 private readonly TypeUsage[] primitiveTypes; 20 EdmProviderManifestFunctionBuilder(System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> edmPrimitiveTypes)21 internal EdmProviderManifestFunctionBuilder(System.Collections.ObjectModel.ReadOnlyCollection<PrimitiveType> edmPrimitiveTypes) 22 { 23 Debug.Assert(edmPrimitiveTypes != null, "Primitive types should not be null"); 24 25 // Initialize all the various parameter types. We do not want to create new instance of parameter types 26 // again and again for perf reasons 27 TypeUsage[] primitiveTypeUsages = new TypeUsage[edmPrimitiveTypes.Count]; 28 foreach (PrimitiveType edmType in edmPrimitiveTypes) 29 { 30 Debug.Assert((int)edmType.PrimitiveTypeKind < primitiveTypeUsages.Length && (int)edmType.PrimitiveTypeKind >= 0, "Invalid PrimitiveTypeKind value?"); 31 Debug.Assert(primitiveTypeUsages[(int)edmType.PrimitiveTypeKind] == null, "Duplicate PrimitiveTypeKind value in EDM primitive types?"); 32 33 primitiveTypeUsages[(int)edmType.PrimitiveTypeKind] = TypeUsage.Create(edmType); 34 } 35 36 this.primitiveTypes = primitiveTypeUsages; 37 } 38 ToFunctionCollection()39 internal System.Collections.ObjectModel.ReadOnlyCollection<EdmFunction> ToFunctionCollection() 40 { 41 return this.functions.AsReadOnly(); 42 } 43 ForAllTypes(Action<PrimitiveTypeKind> forEachType)44 internal void ForAllTypes(Action<PrimitiveTypeKind> forEachType) 45 { 46 for (int idx = 0; idx < EdmConstants.NumPrimitiveTypes; idx++) 47 { 48 forEachType((PrimitiveTypeKind)idx); 49 } 50 } 51 ForAllBasePrimitiveTypes(Action<PrimitiveTypeKind> forEachType)52 internal void ForAllBasePrimitiveTypes(Action<PrimitiveTypeKind> forEachType) 53 { 54 for (int idx = 0; idx < EdmConstants.NumPrimitiveTypes; idx++) 55 { 56 PrimitiveTypeKind typeKind = (PrimitiveTypeKind)idx; 57 if (!Helper.IsStrongSpatialTypeKind(typeKind)) 58 { 59 forEachType(typeKind); 60 } 61 } 62 } 63 ForTypes(IEnumerable<PrimitiveTypeKind> typeKinds, Action<PrimitiveTypeKind> forEachType)64 internal void ForTypes(IEnumerable<PrimitiveTypeKind> typeKinds, Action<PrimitiveTypeKind> forEachType) 65 { 66 foreach (PrimitiveTypeKind kind in typeKinds) 67 { 68 forEachType(kind); 69 } 70 } 71 AddAggregate(string aggregateFunctionName, PrimitiveTypeKind collectionArgumentElementTypeKind)72 internal void AddAggregate(string aggregateFunctionName, PrimitiveTypeKind collectionArgumentElementTypeKind) 73 { 74 this.AddAggregate(collectionArgumentElementTypeKind, aggregateFunctionName, collectionArgumentElementTypeKind); 75 } 76 AddAggregate(PrimitiveTypeKind returnTypeKind, string aggregateFunctionName, PrimitiveTypeKind collectionArgumentElementTypeKind)77 internal void AddAggregate(PrimitiveTypeKind returnTypeKind, string aggregateFunctionName, PrimitiveTypeKind collectionArgumentElementTypeKind) 78 { 79 Debug.Assert(!string.IsNullOrEmpty(aggregateFunctionName) && !string.IsNullOrWhiteSpace(aggregateFunctionName), "Aggregate function name should be valid"); 80 81 FunctionParameter returnParameter = CreateReturnParameter(returnTypeKind); 82 FunctionParameter collectionParameter = CreateAggregateParameter(collectionArgumentElementTypeKind); 83 84 EdmFunction function = new EdmFunction(aggregateFunctionName, 85 EdmConstants.EdmNamespace, 86 DataSpace.CSpace, 87 new EdmFunctionPayload 88 { 89 IsAggregate = true, 90 IsBuiltIn = true, 91 ReturnParameters = new FunctionParameter[] {returnParameter}, 92 Parameters = new FunctionParameter[1] { collectionParameter }, 93 IsFromProviderManifest = true, 94 }); 95 96 function.SetReadOnly(); 97 98 this.functions.Add(function); 99 } 100 AddFunction(PrimitiveTypeKind returnType, string functionName)101 internal void AddFunction(PrimitiveTypeKind returnType, string functionName) 102 { 103 this.AddFunction(returnType, functionName, new KeyValuePair<string, PrimitiveTypeKind>[] { }); 104 } 105 AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argumentTypeKind, string argumentName)106 internal void AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argumentTypeKind, string argumentName) 107 { 108 this.AddFunction(returnType, functionName, new[] { new KeyValuePair<string, PrimitiveTypeKind>(argumentName, argumentTypeKind) }); 109 } 110 AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name)111 internal void AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name) 112 { 113 this.AddFunction(returnType, functionName, 114 new[] { new KeyValuePair<string, PrimitiveTypeKind>(argument1Name, argument1TypeKind), 115 new KeyValuePair<string, PrimitiveTypeKind>(argument2Name, argument2TypeKind)}); 116 } 117 AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name, PrimitiveTypeKind argument3TypeKind, string argument3Name)118 internal void AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name, PrimitiveTypeKind argument3TypeKind, string argument3Name) 119 { 120 this.AddFunction(returnType, functionName, 121 new[] { new KeyValuePair<string, PrimitiveTypeKind>(argument1Name, argument1TypeKind), 122 new KeyValuePair<string, PrimitiveTypeKind>(argument2Name, argument2TypeKind), 123 new KeyValuePair<string, PrimitiveTypeKind>(argument3Name, argument3TypeKind)}); 124 } 125 AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name, PrimitiveTypeKind argument3TypeKind, string argument3Name, PrimitiveTypeKind argument4TypeKind, string argument4Name, PrimitiveTypeKind argument5TypeKind, string argument5Name, PrimitiveTypeKind argument6TypeKind, string argument6Name)126 internal void AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, 127 PrimitiveTypeKind argument2TypeKind, string argument2Name, 128 PrimitiveTypeKind argument3TypeKind, string argument3Name, 129 PrimitiveTypeKind argument4TypeKind, string argument4Name, 130 PrimitiveTypeKind argument5TypeKind, string argument5Name, 131 PrimitiveTypeKind argument6TypeKind, string argument6Name) 132 { 133 this.AddFunction(returnType, functionName, 134 new[] { new KeyValuePair<string, PrimitiveTypeKind>(argument1Name, argument1TypeKind), 135 new KeyValuePair<string, PrimitiveTypeKind>(argument2Name, argument2TypeKind), 136 new KeyValuePair<string, PrimitiveTypeKind>(argument3Name, argument3TypeKind), 137 new KeyValuePair<string, PrimitiveTypeKind>(argument4Name, argument4TypeKind), 138 new KeyValuePair<string, PrimitiveTypeKind>(argument5Name, argument5TypeKind), 139 new KeyValuePair<string, PrimitiveTypeKind>(argument6Name, argument6TypeKind)}); 140 } 141 AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, PrimitiveTypeKind argument2TypeKind, string argument2Name, PrimitiveTypeKind argument3TypeKind, string argument3Name, PrimitiveTypeKind argument4TypeKind, string argument4Name, PrimitiveTypeKind argument5TypeKind, string argument5Name, PrimitiveTypeKind argument6TypeKind, string argument6Name, PrimitiveTypeKind argument7TypeKind, string argument7Name)142 internal void AddFunction(PrimitiveTypeKind returnType, string functionName, PrimitiveTypeKind argument1TypeKind, string argument1Name, 143 PrimitiveTypeKind argument2TypeKind, string argument2Name, 144 PrimitiveTypeKind argument3TypeKind, string argument3Name, 145 PrimitiveTypeKind argument4TypeKind, string argument4Name, 146 PrimitiveTypeKind argument5TypeKind, string argument5Name, 147 PrimitiveTypeKind argument6TypeKind, string argument6Name, 148 PrimitiveTypeKind argument7TypeKind, string argument7Name) 149 { 150 this.AddFunction(returnType, functionName, 151 new[] { new KeyValuePair<string, PrimitiveTypeKind>(argument1Name, argument1TypeKind), 152 new KeyValuePair<string, PrimitiveTypeKind>(argument2Name, argument2TypeKind), 153 new KeyValuePair<string, PrimitiveTypeKind>(argument3Name, argument3TypeKind), 154 new KeyValuePair<string, PrimitiveTypeKind>(argument4Name, argument4TypeKind), 155 new KeyValuePair<string, PrimitiveTypeKind>(argument5Name, argument5TypeKind), 156 new KeyValuePair<string, PrimitiveTypeKind>(argument6Name, argument6TypeKind), 157 new KeyValuePair<string, PrimitiveTypeKind>(argument7Name, argument7TypeKind)}); 158 } 159 AddFunction(PrimitiveTypeKind returnType, string functionName, KeyValuePair<string, PrimitiveTypeKind>[] parameterDefinitions)160 private void AddFunction(PrimitiveTypeKind returnType, string functionName, KeyValuePair<string, PrimitiveTypeKind>[] parameterDefinitions) 161 { 162 FunctionParameter returnParameter = CreateReturnParameter(returnType); 163 FunctionParameter[] parameters = parameterDefinitions.Select(paramDef => CreateParameter(paramDef.Value, paramDef.Key)).ToArray(); 164 165 EdmFunction function = new EdmFunction(functionName, 166 EdmConstants.EdmNamespace, 167 DataSpace.CSpace, 168 new EdmFunctionPayload 169 { 170 IsBuiltIn = true, 171 ReturnParameters = new FunctionParameter[] {returnParameter}, 172 Parameters = parameters, 173 IsFromProviderManifest = true, 174 }); 175 176 function.SetReadOnly(); 177 178 this.functions.Add(function); 179 } 180 CreateParameter(PrimitiveTypeKind primitiveParameterType, string parameterName)181 private FunctionParameter CreateParameter(PrimitiveTypeKind primitiveParameterType, string parameterName) 182 { 183 return new FunctionParameter(parameterName, this.primitiveTypes[(int)primitiveParameterType], ParameterMode.In); 184 } 185 CreateAggregateParameter(PrimitiveTypeKind collectionParameterTypeElementTypeKind)186 private FunctionParameter CreateAggregateParameter(PrimitiveTypeKind collectionParameterTypeElementTypeKind) 187 { 188 return new FunctionParameter("collection", TypeUsage.Create(this.primitiveTypes[(int)collectionParameterTypeElementTypeKind].EdmType.GetCollectionType()), ParameterMode.In); 189 } 190 CreateReturnParameter(PrimitiveTypeKind primitiveReturnType)191 private FunctionParameter CreateReturnParameter(PrimitiveTypeKind primitiveReturnType) 192 { 193 return new FunctionParameter(EdmConstants.ReturnType, this.primitiveTypes[(int)primitiveReturnType], ParameterMode.ReturnValue); 194 } 195 } 196 } 197