private static bool TryCastBinaryConstantAsType(IEdmBinaryConstantExpression expression, IEdmTypeReference type, out IEnumerable <EdmError> discoveredErrors)
        {
            if (!type.IsBinary())
            {
                discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionPrimitiveKindNotValidForAssertedType, 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, 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, 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, Strings.EdmModel_Validator_Semantic_ExpressionPrimitiveKindCannotPromoteToAssertedType(expressionType.ToTraceString(), assertedType.ToTraceString())) };
                        return(false);
                    }
                }
                else
                {
                    if (!expressionType.IsOrInheritsFrom(assertedType))
                    {
                        discoveredErrors = new EdmError[] { new EdmError(location, EdmErrorCode.ExpressionNotValidForTheAssertedType, Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) };
                        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, 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);
        }
Esempio n. 4
0
        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, 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, 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, Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationNullNamespaceOrName);
                    return(false);
                }

                if (!((annotationNamespace == null || elementNamespace == annotationNamespace) && (annotationName == null || elementName == annotationName)))
                {
                    error = new EdmError(value.Location(), EdmErrorCode.InvalidElementAnnotation, 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, Strings.EdmModel_Validator_Semantic_InvalidElementAnnotationValueInvalidXml);
                return(false);
            }
        }
Esempio n. 5
0
 internal static bool IsInterfaceCritical(EdmError error)
 {
     return(error.ErrorCode >= EdmErrorCode.InterfaceCriticalPropertyValueMustNotBeNull && error.ErrorCode <= EdmErrorCode.InterfaceCriticalCycleInTypeHierarchy);
 }
        /// <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.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));

            default:
                discoveredErrors = new EdmError[] { new EdmError(expression.Location(), EdmErrorCode.ExpressionNotValidForTheAssertedType, Strings.EdmModel_Validator_Semantic_ExpressionNotValidForTheAssertedType) };
                return(false);
            }
        }
Esempio n. 7
0
 /// <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);
 }