Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 6 additions & 128 deletions src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.IO;
using System.Linq;
using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.Interface;
using Microsoft.OpenApi.Readers.Services;
using Microsoft.OpenApi.Services;
using SharpYaml;
using SharpYaml.Serialization;

namespace Microsoft.OpenApi.Readers
{
Expand All @@ -21,7 +13,7 @@ namespace Microsoft.OpenApi.Readers
/// </summary>
public class OpenApiStreamReader : IOpenApiReader<Stream, OpenApiDiagnostic>
{
private OpenApiReaderSettings _settings;
private readonly OpenApiReaderSettings _settings;

/// <summary>
/// Create stream reader with custom settings if desired.
Expand All @@ -30,8 +22,8 @@ public class OpenApiStreamReader : IOpenApiReader<Stream, OpenApiDiagnostic>
public OpenApiStreamReader(OpenApiReaderSettings settings = null)
{
_settings = settings ?? new OpenApiReaderSettings();

}

/// <summary>
/// Reads the stream input and parses it into an Open API document.
/// </summary>
Expand All @@ -40,68 +32,10 @@ public OpenApiStreamReader(OpenApiReaderSettings settings = null)
/// <returns>Instance of newly created OpenApiDocument</returns>
public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic)
{
ParsingContext context;
YamlDocument yamlDocument;
diagnostic = new OpenApiDiagnostic();

// Parse the YAML/JSON
try
{
yamlDocument = LoadYamlDocument(input);
}
catch (YamlException ex)
{
diagnostic.Errors.Add(new OpenApiError($"#char={ex.Start.Line}", ex.Message));
return new OpenApiDocument();
}

context = new ParsingContext
{
ExtensionParsers = _settings.ExtensionParsers,
BaseUrl = _settings.BaseUrl
};

OpenApiDocument document = null;

try
{
// Parse the OpenAPI Document
document = context.Parse(yamlDocument, diagnostic);

// Resolve References if requested
switch (_settings.ReferenceResolution)
{
case ReferenceResolutionSetting.ResolveAllReferences:
throw new ArgumentException(Properties.SRResource.CannotResolveRemoteReferencesSynchronously);
case ReferenceResolutionSetting.ResolveLocalReferences:
var resolver = new OpenApiReferenceResolver(document);
var walker = new OpenApiWalker(resolver);
walker.Walk(document);
foreach (var item in resolver.Errors)
{
diagnostic.Errors.Add(item);
}
break;
case ReferenceResolutionSetting.DoNotResolveReferences:
break;
}
}
catch (OpenApiException ex)
{
diagnostic.Errors.Add(new OpenApiError(ex));
}

// Validate the document
if (_settings.RuleSet != null && _settings.RuleSet.Rules.Count > 0)
using (var reader = new StreamReader(input))
{
var errors = document.Validate(_settings.RuleSet);
foreach (var item in errors)
{
diagnostic.Errors.Add(item);
}
return new OpenApiTextReaderReader(_settings).Read(reader, out diagnostic);
}

return document;
}

/// <summary>
Expand All @@ -113,66 +47,10 @@ public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic)
/// <returns>Instance of newly created OpenApiDocument</returns>
public T ReadFragment<T>(Stream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiElement
{
ParsingContext context;
YamlDocument yamlDocument;
diagnostic = new OpenApiDiagnostic();

// Parse the YAML/JSON
try
{
yamlDocument = LoadYamlDocument(input);
}
catch (YamlException ex)
{
diagnostic.Errors.Add(new OpenApiError($"#line={ex.Start.Line}", ex.Message));
return default(T);
}

context = new ParsingContext
{
ExtensionParsers = _settings.ExtensionParsers
};

IOpenApiElement element = null;

try
{
// Parse the OpenAPI element
element = context.ParseFragment<T>(yamlDocument, version, diagnostic);
}
catch (OpenApiException ex)
{
diagnostic.Errors.Add(new OpenApiError(ex));
}

// Validate the element
if (_settings.RuleSet != null && _settings.RuleSet.Rules.Count > 0)
{
var errors = element.Validate(_settings.RuleSet);
foreach (var item in errors)
{
diagnostic.Errors.Add(item);
}
}

return (T)element;
}

/// <summary>
/// Helper method to turn streams into YamlDocument
/// </summary>
/// <param name="input">Stream containing YAML formatted text</param>
/// <returns>Instance of a YamlDocument</returns>
internal static YamlDocument LoadYamlDocument(Stream input)
{
YamlDocument yamlDocument;
using (var streamReader = new StreamReader(input))
using (var reader = new StreamReader(input))
{
var yamlStream = new YamlStream();
yamlStream.Load(streamReader);
yamlDocument = yamlStream.Documents.First();
return new OpenApiTextReaderReader(_settings).ReadFragment<T>(reader, version, out diagnostic);
}
return yamlDocument;
}
}
}
18 changes: 4 additions & 14 deletions src/Microsoft.OpenApi.Readers/OpenApiStringReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,9 @@ public OpenApiStringReader(OpenApiReaderSettings settings = null)
/// </summary>
public OpenApiDocument Read(string input, out OpenApiDiagnostic diagnostic)
{
using (var memoryStream = new MemoryStream())
using (var reader = new StringReader(input))
{
var writer = new StreamWriter(memoryStream);
writer.Write(input);
writer.Flush();
memoryStream.Position = 0;

return new OpenApiStreamReader(_settings).Read(memoryStream, out diagnostic);
return new OpenApiTextReaderReader(_settings).Read(reader, out diagnostic);
}
}

Expand All @@ -45,14 +40,9 @@ public OpenApiDocument Read(string input, out OpenApiDiagnostic diagnostic)
/// </summary>
public T ReadFragment<T>(string input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiElement
{
using (var memoryStream = new MemoryStream())
using (var reader = new StringReader(input))
{
var writer = new StreamWriter(memoryStream);
writer.Write(input);
writer.Flush();
memoryStream.Position = 0;

return new OpenApiStreamReader(_settings).ReadFragment<T>(memoryStream, version, out diagnostic);
return new OpenApiTextReaderReader(_settings).ReadFragment<T>(reader, version, out diagnostic);
}
}
}
Expand Down
92 changes: 92 additions & 0 deletions src/Microsoft.OpenApi.Readers/OpenApiTextReaderReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System.IO;
using System.Linq;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.Interface;
using SharpYaml;
using SharpYaml.Serialization;

namespace Microsoft.OpenApi.Readers
{
/// <summary>
/// Service class for converting contents of TextReader into OpenApiDocument instances
/// </summary>
public class OpenApiTextReaderReader : IOpenApiReader<TextReader, OpenApiDiagnostic>
{
private readonly OpenApiReaderSettings _settings;

/// <summary>
/// Create stream reader with custom settings if desired.
/// </summary>
/// <param name="settings"></param>
public OpenApiTextReaderReader(OpenApiReaderSettings settings = null)
{
_settings = settings ?? new OpenApiReaderSettings();
}

/// <summary>
/// Reads the stream input and parses it into an Open API document.
/// </summary>
/// <param name="input">TextReader containing OpenAPI description to parse.</param>
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
/// <returns>Instance of newly created OpenApiDocument</returns>
public OpenApiDocument Read(TextReader input, out OpenApiDiagnostic diagnostic)
{
YamlDocument yamlDocument;

// Parse the YAML/JSON
try
{
yamlDocument = LoadYamlDocument(input);
}
catch (YamlException ex)
{
diagnostic = new OpenApiDiagnostic();
diagnostic.Errors.Add(new OpenApiError($"#char={ex.Start.Line}", ex.Message));
return new OpenApiDocument();
}

return new OpenApiYamlDocumentReader(this._settings).Read(yamlDocument, out diagnostic);
}
/// <summary>
/// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
/// </summary>
/// <param name="input">TextReader containing OpenAPI description to parse.</param>
/// <param name="version">Version of the OpenAPI specification that the fragment conforms to.</param>
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
/// <returns>Instance of newly created OpenApiDocument</returns>
public T ReadFragment<T>(TextReader input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiElement
{
YamlDocument yamlDocument;

// Parse the YAML/JSON
try
{
yamlDocument = LoadYamlDocument(input);
}
catch (YamlException ex)
{
diagnostic = new OpenApiDiagnostic();
diagnostic.Errors.Add(new OpenApiError($"#line={ex.Start.Line}", ex.Message));
return default(T);
}

return new OpenApiYamlDocumentReader(this._settings).ReadFragment<T>(yamlDocument, version, out diagnostic);
}

/// <summary>
/// Helper method to turn streams into YamlDocument
/// </summary>
/// <param name="input">Stream containing YAML formatted text</param>
/// <returns>Instance of a YamlDocument</returns>
static YamlDocument LoadYamlDocument(TextReader input)
{
var yamlStream = new YamlStream();
yamlStream.Load(input);
return yamlStream.Documents.First();
}
}
}
Loading