/// <summary> /// Load and parse the referenced model but ignored any further referenced model. /// </summary> /// <param name="csdlModel">The main CSDL model.</param> /// <param name="context">The parser context.</param> /// <returns>A list of CsdlModel (no semantics) of the referenced models.</returns> private static List <CsdlModel> LoadReferencedCsdl(CsdlModel csdlModel, JsonParserContext context) { List <CsdlModel> referencedAstModels = new List <CsdlModel>(); if (context.Settings.JsonSchemaReaderFactory == null) { // don't try to load CSDL-JSON doc, but this.edmReferences's namespace-alias need to be used later. return(referencedAstModels); } foreach (var edmReference in csdlModel.CurrentModelReferences) { // If nothing included, why does it exist? if (!edmReference.Includes.Any() && !edmReference.IncludeAnnotations.Any()) { continue; } // Skip the built-in vocabulary annotation model if (edmReference.Uri != null && (edmReference.Uri.OriginalString.EndsWith("/Org.OData.Core.V1.json", StringComparison.Ordinal) || edmReference.Uri.OriginalString.EndsWith("/Org.OData.Capabilities.V1.json", StringComparison.Ordinal) || edmReference.Uri.OriginalString.EndsWith("/Org.OData.Authorization.V1.json", StringComparison.Ordinal) || edmReference.Uri.OriginalString.EndsWith("/Org.OData.Validation.V1.json", StringComparison.Ordinal) || edmReference.Uri.OriginalString.EndsWith("/Org.OData.Community.V1.json", StringComparison.Ordinal) || edmReference.Uri.OriginalString.EndsWith("/OData.Community.Keys.V1.json", StringComparison.Ordinal))) { continue; } Utf8JsonReader referencedJsonReader = context.Settings.JsonSchemaReaderFactory(edmReference.Uri, out bool skip); if (!skip) { string source = edmReference.Uri != null ? edmReference.Uri.OriginalString : null; CsdlJsonReaderSettings newSettings = context.Settings.Clone(); // set it to null to make sure stop the next level reference parsing. newSettings.JsonSchemaReaderFactory = null; JsonParserContext subContext = new JsonParserContext(newSettings, source); CsdlModel subCsdlModel = CsdlJsonParser.ParseCsdlDocument(ref referencedJsonReader, subContext); if (subCsdlModel != null && subContext.IsSucceeded()) { // Should we compare the referenced version with the main CSDL version and report error if mismatching? // So far, it's fine to ignore, because there may be scenarios where referenced schemas are at a different version. subCsdlModel.AddParentModelReferences(edmReference); referencedAstModels.Add(subCsdlModel); } context.AddRange(subContext.Errors); } } return(referencedAstModels); }
/// <summary> /// Returns an IEdmModel for the given CSDL-JSON artifact. /// </summary> /// <param name="reader">The given JSON reader containing the CSDL artifact.</param> /// <param name="settings">The CSDL-JSON reader settings.</param> /// <returns>The model generated by parsing.</returns> public static IEdmModel Parse(ref Utf8JsonReader reader, CsdlJsonReaderSettings settings) { IEdmModel model; IEnumerable <EdmError> parseErrors; if (!TryParse(ref reader, settings, out model, out parseErrors)) { throw new EdmParseException(parseErrors); } return(model); }
/// <summary> /// Tries parsing the given CSDL-JSON artifact for an IEdmModel. /// </summary> /// <param name="reader">The given JSON reader containing the CSDL artifact.</param> /// <param name="settings">CSDL-JSON reader settings for current parser.</param> /// <param name="model">The model generated by parsing</param> /// <param name="errors">Errors reported while parsing.</param> /// <returns>Success of the parse operation.</returns> public static bool TryParse(ref Utf8JsonReader reader, CsdlJsonReaderSettings settings, out IEdmModel model, out IEnumerable <EdmError> errors) { EdmUtil.CheckArgumentNull(settings, nameof(settings)); model = null; JsonParserContext context = new JsonParserContext(settings, source: null); CsdlModel mainModel = CsdlJsonParser.ParseCsdlDocument(ref reader, context); if (mainModel != null && !context.HasIntolerableError()) { Debug.Assert(mainModel.CsdlVersion != null, "csdlVersion != null"); List <CsdlModel> referencedAstModels = LoadReferencedCsdl(mainModel, context); if (!context.HasIntolerableError()) { CsdlSemanticsModel tmp = new CsdlSemanticsModel(mainModel, new CsdlSemanticsDirectValueAnnotationsManager(), referencedAstModels, settings.IncludeDefaultVocabularies); // add more referenced IEdmModels in addition to the above loaded CsdlModels. if (settings.ReferencedModels != null) { tmp.AddToReferencedModels(settings.ReferencedModels); } model = tmp; model.SetEdmxVersion(mainModel.CsdlVersion); Version edmVersion; if (CsdlConstants.EdmxToEdmVersions.TryGetValue(mainModel.CsdlVersion, out edmVersion)) { model.SetEdmVersion(edmVersion); } } } errors = context.Errors; return(!context.HasIntolerableError()); }