internal static bool TryWriteCsdl(IEdmModel model, Func<string, XmlWriter> writerProvider, bool singleFileExpected, out IEnumerable<EdmError> errors) { EdmUtil.CheckArgumentNull(model, "model"); EdmUtil.CheckArgumentNull(writerProvider, "writerProvider"); errors = model.GetSerializationErrors(); if (errors.FirstOrDefault() != null) { return false; } IEnumerable<EdmSchema> schemas = new EdmModelSchemaSeparationSerializationVisitor(model).GetSchemas(); if (schemas.Count() > 1 && singleFileExpected) { errors = new EdmError[] { new EdmError(new CsdlLocation(0, 0), EdmErrorCode.SingleFileExpected, Edm.Strings.Serializer_SingleFileExpected) }; return false; } if (schemas.Count() == 0) { errors = new EdmError[] { new EdmError(new CsdlLocation(0, 0), EdmErrorCode.NoSchemasProduced, Edm.Strings.Serializer_NoSchemasProduced) }; return false; } WriteSchemas(model, schemas, writerProvider); errors = Enumerable.Empty<EdmError>(); return true; }
/// <summary> /// Outputs an EDMX artifact to the provided XmlWriter. /// </summary> /// <param name="model">Model to be written.</param> /// <param name="writer">XmlWriter the generated EDMX will be written to.</param> /// <param name="target">Target implementation of the EDMX being generated.</param> /// <param name="errors">Errors that prevented successful serialization, or no errors if serialization was successfull. </param> /// <returns>A value indicating whether serialization was successful.</returns> public static bool TryWriteEdmx(IEdmModel model, XmlWriter writer, EdmxTarget target, out IEnumerable<EdmError> errors) { EdmUtil.CheckArgumentNull(model, "model"); EdmUtil.CheckArgumentNull(writer, "writer"); errors = model.GetSerializationErrors(); if (errors.FirstOrDefault() != null) { return false; } Version edmxVersion = model.GetEdmxVersion(); if (edmxVersion != null) { if (!CsdlConstants.SupportedEdmxVersions.ContainsKey(edmxVersion)) { errors = new EdmError[] { new EdmError(new CsdlLocation(0, 0), EdmErrorCode.UnknownEdmxVersion, Edm.Strings.Serializer_UnknownEdmxVersion) }; return false; } } else if (!CsdlConstants.EdmToEdmxVersions.TryGetValue(model.GetEdmVersion() ?? EdmConstants.EdmVersionLatest, out edmxVersion)) { errors = new EdmError[] { new EdmError(new CsdlLocation(0, 0), EdmErrorCode.UnknownEdmVersion, Edm.Strings.Serializer_UnknownEdmVersion) }; return false; } IEnumerable<EdmSchema> schemas = new EdmModelSchemaSeparationSerializationVisitor(model).GetSchemas(); EdmxWriter edmxWriter = new EdmxWriter(model, schemas, writer, edmxVersion, target); edmxWriter.WriteEdmx(); errors = Enumerable.Empty<EdmError>(); return true; }
public static bool IsMatch(ExpectedEdmError expectedError, EdmError actualError) { if (expectedError.ErrorCode != actualError.ErrorCode) { return false; } return stringResourceVerifier.IsMatch(expectedError.MessageResourceKey, actualError.ErrorMessage, false, expectedError.MessageArguments.ToArray()); }
public static bool TryParse(IEnumerable<XmlReader> csdlReaders, out CsdlModel entityModel, out IEnumerable<EdmError> errors) { EdmUtil.CheckArgumentNull(csdlReaders, "csdlReaders"); CsdlParser parser = new CsdlParser(); int readerCount = 0; foreach (var inputReader in csdlReaders) { if (inputReader != null) { try { parser.AddReader(inputReader); } catch (XmlException e) { entityModel = null; errors = new EdmError[] { new EdmError(new CsdlLocation(e.LineNumber, e.LinePosition), EdmErrorCode.XmlError, e.Message) }; return false; } } else { entityModel = null; errors = new EdmError[] { new EdmError(null, EdmErrorCode.NullXmlReader, Edm.Strings.CsdlParser_NullXmlReader) }; return false; } readerCount++; } if (readerCount == 0) { entityModel = null; errors = new EdmError[] { new EdmError(null, EdmErrorCode.NoReadersProvided, Edm.Strings.CsdlParser_NoReadersProvided) }; return false; } bool success = parser.GetResult(out entityModel, out errors); if (!success) { entityModel = null; } return success; }
private static bool TryCastBinaryConstantAsType(IEdmBinaryConstantExpression expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsBinary()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return(false); } IEdmBinaryTypeReference binaryType = type.AsBinary(); if (binaryType.MaxLength.HasValue && expression.Value.Length > binaryType.MaxLength.Value) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.BinaryConstantLengthOutOfRange, Edm.Strings.EdmModel_Validator_Semantic_BinaryConstantLengthOutOfRange(expression.Value.Length, binaryType.MaxLength.Value)) }; return(false); } discoveredErrors = Enumerable.Empty <EdmError>(); return(true); }
private static bool TestTypeMatch(this IEdmType expressionType, IEdmType assertedType, EdmLocation location, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { if (matchExactly) { if (!expressionType.IsEquivalentTo(assertedType)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return(false); } } else { // A bad type matches anything (so as to avoid generating spurious errors). if (expressionType.TypeKind == EdmTypeKind.None || expressionType.IsBad()) { discoveredErrors = Enumerable.Empty <EdmError>(); return(true); } if (expressionType.TypeKind == EdmTypeKind.Primitive && assertedType.TypeKind == EdmTypeKind.Primitive) { IEdmPrimitiveType primitiveExpressionType = expressionType as IEdmPrimitiveType; IEdmPrimitiveType primitiveAssertedType = assertedType as IEdmPrimitiveType; if (!primitiveExpressionType.PrimitiveKind.PromotesTo(primitiveAssertedType.PrimitiveKind)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindCannotPromoteToAssertedType(expressionType.ToTraceString(), assertedType.ToTraceString())) }; return(false); } } else { if (!expressionType.IsOrInheritsFrom(assertedType)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return(false); } } } discoveredErrors = Enumerable.Empty <EdmError>(); return(true); }
internal static bool TryCastPrimitiveAsType(this IEdmPrimitiveValue expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsPrimitive()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PrimitiveConstantExpressionNotValidForNonPrimitiveType, Edm.Strings.EdmModel_Validator_Semantic_PrimitiveConstantExpressionNotValidForNonPrimitiveType) }; return(false); } switch (expression.ValueKind) { case EdmValueKind.Binary: return(TryCastBinaryConstantAsType((IEdmBinaryConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Boolean: return(TryCastBooleanConstantAsType((IEdmBooleanConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.DateTimeOffset: return(TryCastDateTimeOffsetConstantAsType((IEdmDateTimeOffsetConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Decimal: return(TryCastDecimalConstantAsType((IEdmDecimalConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Floating: return(TryCastFloatingConstantAsType((IEdmFloatingConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Guid: return(TryCastGuidConstantAsType((IEdmGuidConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Integer: return(TryCastIntegerConstantAsType((IEdmIntegerConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.String: return(TryCastStringConstantAsType((IEdmStringConstantExpression)expression, type, out discoveredErrors)); case EdmValueKind.Duration: return(TryCastDurationConstantAsType((IEdmDurationConstantExpression)expression, type, out discoveredErrors)); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return(false); } }
internal static bool TryCastCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsCollection()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Edm.Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType) }; return(false); } IEdmTypeReference collectionElementType = type.AsCollection().ElementType(); bool success = true; List <EdmError> errors = new List <EdmError>(); IEnumerable <EdmError> recursiveErrors; foreach (IEdmExpression element in expression.Elements) { success = TryCast(element, collectionElementType, context, matchExactly, out recursiveErrors) && success; errors.AddRange(recursiveErrors); } discoveredErrors = errors; return(success); }
private static bool TryCastEnumConstantAsType(IEdmEnumMemberExpression expression, IEdmTypeReference type, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { if (!type.IsEnum()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionEnumKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionEnumKindNotValidForAssertedType) }; return(false); } foreach (var member in expression.EnumMembers) { if (!TestTypeMatch(member.DeclaringType, type.Definition, expression.Location(), matchExactly, out discoveredErrors)) { return(false); } } discoveredErrors = Enumerable.Empty <EdmError>(); return(true); }
private static bool TryCastIntegerConstantAsType(IEdmIntegerConstantExpression expression, IEdmTypeReference type, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsIntegral()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return false; } switch (type.PrimitiveKind()) { case EdmPrimitiveTypeKind.Int64: return TryCastIntegerConstantInRange(expression, Int64.MinValue, Int64.MaxValue, out discoveredErrors); case EdmPrimitiveTypeKind.Int32: return TryCastIntegerConstantInRange(expression, Int32.MinValue, Int32.MaxValue, out discoveredErrors); case EdmPrimitiveTypeKind.Int16: return TryCastIntegerConstantInRange(expression, Int16.MinValue, Int16.MaxValue, out discoveredErrors); case EdmPrimitiveTypeKind.Byte: return TryCastIntegerConstantInRange(expression, Byte.MinValue, Byte.MaxValue, out discoveredErrors); case EdmPrimitiveTypeKind.SByte: return TryCastIntegerConstantInRange(expression, SByte.MinValue, SByte.MaxValue, out discoveredErrors); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return false; } }
private static bool TryCastBooleanConstantAsType(IEdmBooleanConstantExpression expression, IEdmTypeReference type, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsBoolean()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
internal static bool TryCastCollectionAsType(this IEdmCollectionExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsCollection()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.CollectionExpressionNotValidForNonCollectionType, Edm.Strings.EdmModel_Validator_Semantic_CollectionExpressionNotValidForNonCollectionType) }; return false; } IEdmTypeReference collectionElementType = type.AsCollection().ElementType(); bool success = true; List<EdmError> errors = new List<EdmError>(); IEnumerable<EdmError> recursiveErrors; foreach (IEdmExpression element in expression.Elements) { success = TryCast(element, collectionElementType, context, matchExactly, out recursiveErrors) && success; errors.AddRange(recursiveErrors); } discoveredErrors = errors; return success; }
internal static bool TryCastRecordAsType(this IEdmRecordExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable<EdmError> discoveredErrors) { EdmUtil.CheckArgumentNull(expression, "expression"); EdmUtil.CheckArgumentNull(type, "type"); if (!type.IsStructured()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.RecordExpressionNotValidForNonStructuredType, Edm.Strings.EdmModel_Validator_Semantic_RecordExpressionNotValidForNonStructuredType) }; return false; } HashSetInternal<string> foundProperties = new HashSetInternal<string>(); List<EdmError> errors = new List<EdmError>(); IEdmStructuredTypeReference structuredType = type.AsStructured(); foreach (IEdmProperty typeProperty in structuredType.StructuredDefinition().Properties()) { IEdmPropertyConstructor expressionProperty = expression.Properties.FirstOrDefault(p => p.Name == typeProperty.Name); if (expressionProperty == null) { errors.Add(new EdmError(expression.Location(), EdmErrorCode.RecordExpressionMissingRequiredProperty, Edm.Strings.EdmModel_Validator_Semantic_RecordExpressionMissingProperty(typeProperty.Name))); } else { IEnumerable<EdmError> recursiveErrors; if (!expressionProperty.Value.TryCast(typeProperty.Type, context, matchExactly, out recursiveErrors)) { foreach (EdmError error in recursiveErrors) { errors.Add(error); } } foundProperties.Add(typeProperty.Name); } } if (!structuredType.IsOpen()) { foreach (IEdmPropertyConstructor property in expression.Properties) { if (!foundProperties.Contains(property.Name)) { errors.Add(new EdmError(expression.Location(), EdmErrorCode.RecordExpressionHasExtraProperties, Edm.Strings.EdmModel_Validator_Semantic_RecordExpressionHasExtraProperties(property.Name))); } } } if (errors.FirstOrDefault() != null) { discoveredErrors = errors; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
/// <summary> /// Register an error with the validation context. /// </summary> /// <param name="error">Error to register.</param> public void AddError(EdmError error) { this.errors.Add(error); }
private static bool TestNullabilityMatch(this IEdmTypeReference expressionType, IEdmTypeReference assertedType, EdmLocation location, out IEnumerable<EdmError> discoveredErrors) { if (!assertedType.IsNullable && expressionType.IsNullable) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.CannotAssertNullableTypeAsNonNullableType, Edm.Strings.EdmModel_Validator_Semantic_CannotAssertNullableTypeAsNonNullableType(expressionType.FullName())) }; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
/// <summary> /// Determines if the type of an expression is compatible with the provided type /// </summary> /// <param name="expression">The expression to assert the type of.</param> /// <param name="type">The type to assert the expression as.</param> /// <param name="context">The context paths are to be evaluated in.</param> /// <param name="matchExactly">A value indicating whether the expression must match the asserted type exactly, or simply be compatible.</param> /// <param name="discoveredErrors">Errors produced if the expression does not match the specified type.</param> /// <returns>A value indicating whether the expression is valid for the given type or not.</returns> /// <remarks>If the expression has an associated type, this function will check that it matches the expected type and stop looking further. /// If an expression claims a type, it must be validated that the type is valid for the expression. If the expression does not claim a type /// this method will attempt to check the validity of the expression itself with the asserted type.</remarks> public static bool TryCast(this IEdmExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable<EdmError> discoveredErrors) { EdmUtil.CheckArgumentNull(expression, "expression"); type = type.AsActualTypeReference(); // If we don't have a type to assert this passes vacuously. if (type == null || type.TypeKind() == EdmTypeKind.None) { discoveredErrors = Enumerable.Empty<EdmError>(); return true; } switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: case EdmExpressionKind.StringConstant: case EdmExpressionKind.BinaryConstant: case EdmExpressionKind.BooleanConstant: case EdmExpressionKind.DateTimeOffsetConstant: case EdmExpressionKind.DecimalConstant: case EdmExpressionKind.FloatingConstant: case EdmExpressionKind.GuidConstant: case EdmExpressionKind.DurationConstant: case EdmExpressionKind.DateConstant: case EdmExpressionKind.TimeOfDayConstant: IEdmPrimitiveValue primitiveValue = (IEdmPrimitiveValue)expression; if (primitiveValue.Type != null) { return TestTypeReferenceMatch(primitiveValue.Type, type, expression.Location(), matchExactly, out discoveredErrors); } return TryCastPrimitiveAsType(primitiveValue, type, out discoveredErrors); case EdmExpressionKind.Null: return TryCastNullAsType((IEdmNullExpression)expression, type, out discoveredErrors); case EdmExpressionKind.Path: case EdmExpressionKind.PropertyPath: case EdmExpressionKind.NavigationPropertyPath: return TryCastPathAsType((IEdmPathExpression)expression, type, context, matchExactly, out discoveredErrors); case EdmExpressionKind.OperationApplication: IEdmApplyExpression applyExpression = (IEdmApplyExpression)expression; if (applyExpression.AppliedOperation != null) { IEdmOperation operation = applyExpression.AppliedOperation as IEdmOperation; if (operation != null) { return TestTypeReferenceMatch(operation.ReturnType, type, expression.Location(), matchExactly, out discoveredErrors); } } // If we don't have the applied function we just assume that it will work. discoveredErrors = Enumerable.Empty<EdmError>(); return true; case EdmExpressionKind.If: return TryCastIfAsType((IEdmIfExpression)expression, type, context, matchExactly, out discoveredErrors); case EdmExpressionKind.IsType: return TestTypeReferenceMatch(EdmCoreModel.Instance.GetBoolean(false), type, expression.Location(), matchExactly, out discoveredErrors); case EdmExpressionKind.Record: IEdmRecordExpression recordExpression = (IEdmRecordExpression)expression; if (recordExpression.DeclaredType != null) { return TestTypeReferenceMatch(recordExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors); } return TryCastRecordAsType(recordExpression, type, context, matchExactly, out discoveredErrors); case EdmExpressionKind.Collection: IEdmCollectionExpression collectionExpression = (IEdmCollectionExpression)expression; if (collectionExpression.DeclaredType != null) { return TestTypeReferenceMatch(collectionExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors); } return TryCastCollectionAsType(collectionExpression, type, context, matchExactly, out discoveredErrors); case EdmExpressionKind.Labeled: return TryCast(((IEdmLabeledExpression)expression).Expression, type, context, matchExactly, out discoveredErrors); case EdmExpressionKind.Cast: return TestTypeReferenceMatch(((IEdmCastExpression)expression).Type, type, expression.Location(), matchExactly, out discoveredErrors); case EdmExpressionKind.LabeledExpressionReference: return TryCast(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, type, out discoveredErrors); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return false; } }
/// <summary> /// Determines if the type of an expression is compatible with the provided type /// </summary> /// <param name="expression">The expression to assert the type of.</param> /// <param name="type">The type to assert the expression as.</param> /// <param name="context">The context paths are to be evaluated in.</param> /// <param name="matchExactly">A value indicating whether the expression must match the asserted type exactly, or simply be compatible.</param> /// <param name="discoveredErrors">Errors produced if the expression does not match the specified type.</param> /// <returns>A value indicating whether the expression is valid for the given type or not.</returns> /// <remarks>If the expression has an associated type, this function will check that it matches the expected type and stop looking further. /// If an expression claims a type, it must be validated that the type is valid for the expression. If the expression does not claim a type /// this method will attempt to check the validity of the expression itself with the asserted type.</remarks> public static bool TryCast(this IEdmExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable <EdmError> discoveredErrors) { EdmUtil.CheckArgumentNull(expression, "expression"); type = type.AsActualTypeReference(); // If we don't have a type to assert this passes vacuously. if (type == null || type.TypeKind() == EdmTypeKind.None) { discoveredErrors = Enumerable.Empty <EdmError>(); return(true); } switch (expression.ExpressionKind) { case EdmExpressionKind.IntegerConstant: case EdmExpressionKind.StringConstant: case EdmExpressionKind.BinaryConstant: case EdmExpressionKind.BooleanConstant: case EdmExpressionKind.DateTimeOffsetConstant: case EdmExpressionKind.DecimalConstant: case EdmExpressionKind.FloatingConstant: case EdmExpressionKind.GuidConstant: case EdmExpressionKind.DurationConstant: case EdmExpressionKind.DateConstant: case EdmExpressionKind.TimeOfDayConstant: IEdmPrimitiveValue primitiveValue = (IEdmPrimitiveValue)expression; if (primitiveValue.Type != null) { return(TestTypeReferenceMatch(primitiveValue.Type, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryCastPrimitiveAsType(primitiveValue, type, out discoveredErrors)); case EdmExpressionKind.Null: return(TryCastNullAsType((IEdmNullExpression)expression, type, out discoveredErrors)); case EdmExpressionKind.Path: case EdmExpressionKind.PropertyPath: case EdmExpressionKind.NavigationPropertyPath: case EdmExpressionKind.AnnotationPath: return(TryCastPathAsType((IEdmPathExpression)expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.FunctionApplication: IEdmApplyExpression applyExpression = (IEdmApplyExpression)expression; if (applyExpression.AppliedFunction != null) { IEdmOperation operation = applyExpression.AppliedFunction as IEdmOperation; if (operation != null) { return(TestTypeReferenceMatch(operation.ReturnType, type, expression.Location(), matchExactly, out discoveredErrors)); } } // If we don't have the applied function we just assume that it will work. discoveredErrors = Enumerable.Empty <EdmError>(); return(true); case EdmExpressionKind.If: return(TryCastIfAsType((IEdmIfExpression)expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.IsType: return(TestTypeReferenceMatch(EdmCoreModel.Instance.GetBoolean(false), type, expression.Location(), matchExactly, out discoveredErrors)); case EdmExpressionKind.Record: IEdmRecordExpression recordExpression = (IEdmRecordExpression)expression; if (recordExpression.DeclaredType != null) { return(TestTypeReferenceMatch(recordExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryCastRecordAsType(recordExpression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.Collection: IEdmCollectionExpression collectionExpression = (IEdmCollectionExpression)expression; if (collectionExpression.DeclaredType != null) { return(TestTypeReferenceMatch(collectionExpression.DeclaredType, type, expression.Location(), matchExactly, out discoveredErrors)); } return(TryCastCollectionAsType(collectionExpression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.Labeled: return(TryCast(((IEdmLabeledExpression)expression).Expression, type, context, matchExactly, out discoveredErrors)); case EdmExpressionKind.Cast: return(TestTypeReferenceMatch(((IEdmCastExpression)expression).Type, type, expression.Location(), matchExactly, out discoveredErrors)); case EdmExpressionKind.LabeledExpressionReference: return(TryCast(((IEdmLabeledExpressionReferenceExpression)expression).ReferencedLabeledExpression, type, out discoveredErrors)); case EdmExpressionKind.EnumMember: return(TryCastEnumConstantAsType((IEdmEnumMemberExpression)expression, type, matchExactly, out discoveredErrors)); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return(false); } }
internal static bool ValidateValueCanBeWrittenAsXmlElementAnnotation(IEdmValue value, string annotationNamespace, string annotationName, out EdmError error) { IEdmStringValue edmStringValue = value as IEdmStringValue; if (edmStringValue == null) { error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, Edm.Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationNotIEdmStringValue); return(false); } string rawString = edmStringValue.Value; XmlReader reader = XmlReader.Create(new StringReader(rawString)); try { // Skip to root element. if (reader.NodeType != XmlNodeType.Element) { while (reader.Read() && reader.NodeType != XmlNodeType.Element) { } } // The annotation must be an element. if (reader.EOF) { error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, Edm.Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationValueInvalidXml); return(false); } // The root element must corespond to the term of the annotation string elementNamespace = reader.NamespaceURI; string elementName = reader.LocalName; if (EdmUtil.IsNullOrWhiteSpaceInternal(elementNamespace) || EdmUtil.IsNullOrWhiteSpaceInternal(elementName)) { error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, Edm.Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationNullNamespaceOrName); return(false); } if (!((annotationNamespace == null || elementNamespace == annotationNamespace) && (annotationName == null || elementName == annotationName))) { error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, Edm.Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationMismatchedTerm); return(false); } // Parse the entire fragment to determine if the XML is valid while (reader.Read()) { } error = null; return(true); } catch (XmlException) { error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, Edm.Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationValueInvalidXml); return(false); } }
internal static bool IsInterfaceCritical(EdmError error) { return(error.ErrorCode >= EdmErrorCode.InterfaceCriticalPropertyValueMustNotBeNull && error.ErrorCode <= EdmErrorCode.InterfaceCriticalCycleInTypeHierarchy); }
private static bool TryCastIntegerConstantInRange(IEdmIntegerConstantExpression expression, long min, long max, out IEnumerable<EdmError> discoveredErrors) { if (expression.Value < min || expression.Value > max) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.IntegerConstantValueOutOfRange, Edm.Strings.EdmModel_Validator_Semantic_IntegerConstantValueOutOfRange) }; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
internal static bool TryCastPrimitiveAsType(this IEdmPrimitiveValue expression, IEdmTypeReference type, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsPrimitive()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PrimitiveConstantExpressionNotValidForNonPrimitiveType, Edm.Strings.EdmModel_Validator_Semantic_PrimitiveConstantExpressionNotValidForNonPrimitiveType) }; return false; } switch (expression.ValueKind) { case EdmValueKind.Binary: return TryCastBinaryConstantAsType((IEdmBinaryConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Boolean: return TryCastBooleanConstantAsType((IEdmBooleanConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.DateTimeOffset: return TryCastDateTimeOffsetConstantAsType((IEdmDateTimeOffsetConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Decimal: return TryCastDecimalConstantAsType((IEdmDecimalConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Floating: return TryCastFloatingConstantAsType((IEdmFloatingConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Guid: return TryCastGuidConstantAsType((IEdmGuidConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Integer: return TryCastIntegerConstantAsType((IEdmIntegerConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.String: return TryCastStringConstantAsType((IEdmStringConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Duration: return TryCastDurationConstantAsType((IEdmDurationConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.Date: return TryCastDateConstantAsType((IEdmDateConstantExpression)expression, type, out discoveredErrors); case EdmValueKind.TimeOfDay: return TryCastTimeOfDayConstantAsType((IEdmTimeOfDayConstantExpression)expression, type, out discoveredErrors); default: discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return false; } }
private static bool TryCastBinaryConstantAsType(IEdmBinaryConstantExpression expression, IEdmTypeReference type, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsBinary()) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindNotValidForAssertedType) }; return false; } IEdmBinaryTypeReference binaryType = type.AsBinary(); if (binaryType.MaxLength.HasValue && expression.Value.Length > binaryType.MaxLength.Value) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.BinaryConstantLengthOutOfRange, Edm.Strings.EdmModel_Validator_Semantic_BinaryConstantLengthOutOfRange(expression.Value.Length, binaryType.MaxLength.Value)) }; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
internal static bool TryCastNullAsType(this IEdmNullExpression expression, IEdmTypeReference type, out IEnumerable<EdmError> discoveredErrors) { if (!type.IsNullable) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.NullCannotBeAssertedToBeANonNullableType, Edm.Strings.EdmModel_Validator_Semantic_NullCannotBeAssertedToBeANonNullableType) }; return false; } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
private static bool TestTypeMatch(this IEdmType expressionType, IEdmType assertedType, EdmLocation location, bool matchExactly, out IEnumerable<EdmError> discoveredErrors) { if (matchExactly) { if (!expressionType.IsEquivalentTo(assertedType)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return false; } } else { // A bad type matches anything (so as to avoid generating spurious errors). if (expressionType.TypeKind == EdmTypeKind.None || expressionType.IsBad()) { discoveredErrors = Enumerable.Empty<EdmError>(); return true; } if (expressionType.TypeKind == EdmTypeKind.Primitive && assertedType.TypeKind == EdmTypeKind.Primitive) { IEdmPrimitiveType primitiveExpressionType = expressionType as IEdmPrimitiveType; IEdmPrimitiveType primitiveAssertedType = assertedType as IEdmPrimitiveType; if (!primitiveExpressionType.PrimitiveKind.PromotesTo(primitiveAssertedType.PrimitiveKind)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindCannotPromoteToAssertedType(expressionType.ToTraceString(), assertedType.ToTraceString())) }; return false; } } else { if (!expressionType.IsOrInheritsFrom(assertedType)) { discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionNotValidForTheAssertedType, Edm.Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) }; return false; } } } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
internal static bool TryCastPathAsType(this IEdmPathExpression expression, IEdmTypeReference type, IEdmType context, bool matchExactly, out IEnumerable<EdmError> discoveredErrors) { IEdmStructuredType structuredContext = context as IEdmStructuredType; if (structuredContext != null) { IEdmType result = context; // [EdmLib] Need to handle paths that bind to things other than properties. foreach (string segment in expression.Path) { IEdmStructuredType structuredResult = result as IEdmStructuredType; if (structuredResult == null) { discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.PathIsNotValidForTheGivenContext, Edm.Strings.EdmModel_Validator_Semantic_PathIsNotValidForTheGivenContext(segment)) }; return false; } IEdmProperty resultProperty = structuredResult.FindProperty(segment); result = (resultProperty != null) ? resultProperty.Type.Definition : null; // If the path is not resolved, it could refer to an open type, and we cannot make an assertion about its type. if (result == null) { discoveredErrors = Enumerable.Empty<EdmError>(); return true; } } return TestTypeMatch(result, type.Definition, expression.Location(), matchExactly, out discoveredErrors); } discoveredErrors = Enumerable.Empty<EdmError>(); return true; }
internal static bool SignificantToSerialization(EdmError error) { if (ValidationHelper.IsInterfaceCritical(error)) { return true; } switch (error.ErrorCode) { case EdmErrorCode.InvalidName: case EdmErrorCode.NameTooLong: case EdmErrorCode.InvalidNamespaceName: case EdmErrorCode.SystemNamespaceEncountered: case EdmErrorCode.ReferencedTypeMustHaveValidName: case EdmErrorCode.OperationImportEntitySetExpressionIsInvalid: case EdmErrorCode.OperationImportParameterIncorrectType: case EdmErrorCode.InvalidOperationImportParameterMode: case EdmErrorCode.TypeMustNotHaveKindOfNone: case EdmErrorCode.PrimitiveTypeMustNotHaveKindOfNone: case EdmErrorCode.PropertyMustNotHaveKindOfNone: case EdmErrorCode.TermMustNotHaveKindOfNone: case EdmErrorCode.SchemaElementMustNotHaveKindOfNone: case EdmErrorCode.EntityContainerElementMustNotHaveKindOfNone: case EdmErrorCode.BinaryValueCannotHaveEmptyValue: case EdmErrorCode.EnumMustHaveIntegerUnderlyingType: case EdmErrorCode.EnumMemberTypeMustMatchEnumUnderlyingType: return true; } return false; }