Skip to content
Closed
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
23 changes: 23 additions & 0 deletions src/Microsoft.OpenApi.Readers/OpenApiReaderSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Readers.ParseNodes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.OpenApi.Readers
{
/// <summary>
/// Configuration settings to control how OpenAPI documents are parsed
/// </summary>
public class OpenApiReaderSettings
{
/// <summary>
/// Dictionary of parsers for converting extensions into strongly typed classes
/// </summary>
public Dictionary<string, Func<IOpenApiAny , IOpenApiExtension>> ExtensionParsers { get; set; } = new Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>>();

}
}
15 changes: 14 additions & 1 deletion src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,17 @@ namespace Microsoft.OpenApi.Readers
/// </summary>
public class OpenApiStreamReader : IOpenApiReader<Stream, OpenApiDiagnostic>
{
private OpenApiReaderSettings _settings;

/// <summary>
///
/// </summary>
/// <param name="settings"></param>
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 @@ -38,7 +48,10 @@ public OpenApiDocument Read(Stream input, out OpenApiDiagnostic diagnostic)
return new OpenApiDocument();
}

context = new ParsingContext();
context = new ParsingContext
{
ExtensionParsers = _settings.ExtensionParsers
};
return context.Parse(yamlDocument, diagnostic);
}

Expand Down
13 changes: 12 additions & 1 deletion src/Microsoft.OpenApi.Readers/OpenApiStringReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ namespace Microsoft.OpenApi.Readers
/// </summary>
public class OpenApiStringReader : IOpenApiReader<string, OpenApiDiagnostic>
{
private readonly OpenApiReaderSettings _settings;

/// <summary>
/// Constructor tha allows reader to use non-default settings
/// </summary>
/// <param name="settings"></param>
public OpenApiStringReader(OpenApiReaderSettings settings = null)
{
_settings = settings ?? new OpenApiReaderSettings();
}

/// <summary>
/// Reads the string input and parses it into an Open API document.
/// </summary>
Expand All @@ -24,7 +35,7 @@ public OpenApiDocument Read(string input, out OpenApiDiagnostic diagnostic)
writer.Flush();
memoryStream.Position = 0;

return new OpenApiStreamReader().Read(memoryStream, out diagnostic);
return new OpenApiStreamReader(_settings).Read(memoryStream, out diagnostic);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Microsoft.OpenApi.Readers/ParsingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.Interface;
Expand All @@ -23,6 +24,9 @@ public class ParsingContext
private readonly Dictionary<string, IOpenApiReferenceable> _referenceStore = new Dictionary<string, IOpenApiReferenceable>();
private readonly Dictionary<string, object> _tempStorage = new Dictionary<string, object>();
private IOpenApiVersionService _versionService;

internal Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>> ExtensionParsers { get; set; } = new Dictionary<string, Func<IOpenApiAny, IOpenApiExtension>>();

internal RootNode RootNode { get; set; }
internal List<OpenApiTag> Tags { get; private set; } = new List<OpenApiTag>();

Expand Down Expand Up @@ -61,6 +65,7 @@ internal OpenApiDocument Parse(YamlDocument yamlDocument, OpenApiDiagnostic diag
return doc;
}


/// <summary>
/// Gets the version of the Open API document.
/// </summary>
Expand Down
14 changes: 14 additions & 0 deletions src/Microsoft.OpenApi.Readers/V3/OpenApiDocumentDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Licensed under the MIT license.

using System.Collections.Generic;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers.ParseNodes;

Expand Down Expand Up @@ -50,5 +52,17 @@ public static OpenApiDocument LoadOpenApi(RootNode rootNode)

return openApidoc;
}


public static IOpenApiExtension LoadExtension(string name, ParseNode node)
{
if (node.Context.ExtensionParsers.TryGetValue(name, out var parser)) {
return parser(node.CreateAny());
}
else
{
return node.CreateAny();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal static partial class OpenApiV3Deserializer

public static PatternFieldMap<OpenApiInfo> InfoPatternFields = new PatternFieldMap<OpenApiInfo>
{
{s => s.StartsWith("x-"), (o, k, n) => o.AddExtension(k, n.CreateAny())}
{s => s.StartsWith("x-"), (o, k, n) => o.Extensions.Add(k,LoadExtension(k, n))}
};

public static OpenApiInfo LoadInfo(ParseNode node)
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Any/IOpenApiAny.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.OpenApi.Any
/// <summary>
/// Base interface for all the types that represent Open API Any.
/// </summary>
public interface IOpenApiAny : IOpenApiElement
public interface IOpenApiAny : IOpenApiElement, IOpenApiExtension
{
/// <summary>
/// Type of an <see cref="IOpenApiAny"/>.
Expand Down
18 changes: 18 additions & 0 deletions src/Microsoft.OpenApi/Any/OpenApiArray.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Writers;
using System.Collections.Generic;

namespace Microsoft.OpenApi.Any
Expand All @@ -14,5 +15,22 @@ public class OpenApiArray : List<IOpenApiAny>, IOpenApiAny
/// The type of <see cref="IOpenApiAny"/>
/// </summary>
public AnyType AnyType { get; } = AnyType.Array;

/// <summary>
/// Write out contents of OpenApiArray to passed writer
/// </summary>
/// <param name="writer">Instance of JSON or YAML writer.</param>
public void Write(IOpenApiWriter writer)
{
writer.WriteStartArray();

foreach (var item in this)
{
writer.WriteAny(item);
}

writer.WriteEndArray();

}
}
}
11 changes: 11 additions & 0 deletions src/Microsoft.OpenApi/Any/OpenApiNull.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.Any
{
/// <summary>
Expand All @@ -12,5 +14,14 @@ public class OpenApiNull : IOpenApiAny
/// The type of <see cref="IOpenApiAny"/>
/// </summary>
public AnyType AnyType { get; } = AnyType.Null;

/// <summary>
/// Write out null representation
/// </summary>
/// <param name="writer"></param>
public void Write(IOpenApiWriter writer)
{
writer.WriteAny(this);
}
}
}
19 changes: 19 additions & 0 deletions src/Microsoft.OpenApi/Any/OpenApiObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT license.

using System.Collections.Generic;
using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.Any
{
Expand All @@ -14,5 +15,23 @@ public class OpenApiObject : Dictionary<string, IOpenApiAny>, IOpenApiAny
/// Type of <see cref="IOpenApiAny"/>.
/// </summary>
public AnyType AnyType { get; } = AnyType.Object;

/// <summary>
///
/// </summary>
/// <param name="writer"></param>
public void Write(IOpenApiWriter writer)
{
writer.WriteStartObject();

foreach (var item in this)
{
writer.WritePropertyName(item.Key);
writer.WriteAny(item.Value);
}

writer.WriteEndObject();

}
}
}
76 changes: 76 additions & 0 deletions src/Microsoft.OpenApi/Any/OpenApiPrimitive.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Properties;
using Microsoft.OpenApi.Writers;

namespace Microsoft.OpenApi.Any
{
/// <summary>
Expand Down Expand Up @@ -32,5 +36,77 @@ public OpenApiPrimitive(T value)
/// Value of this <see cref="IOpenApiPrimitive"/>
/// </summary>
public T Value { get; }

/// <summary>
/// Write out content of primitive element
/// </summary>
/// <param name="writer"></param>
public void Write(IOpenApiWriter writer)
{
switch (this.PrimitiveType)
{
case PrimitiveType.Integer:
var intValue = (OpenApiInteger)(IOpenApiPrimitive)this;
writer.WriteValue(intValue.Value);
break;

case PrimitiveType.Long:
var longValue = (OpenApiLong)(IOpenApiPrimitive)this;
writer.WriteValue(longValue.Value);
break;

case PrimitiveType.Float:
var floatValue = (OpenApiFloat)(IOpenApiPrimitive)this;
writer.WriteValue(floatValue.Value);
break;

case PrimitiveType.Double:
var doubleValue = (OpenApiDouble)(IOpenApiPrimitive)this;
writer.WriteValue(doubleValue.Value);
break;

case PrimitiveType.String:
var stringValue = (OpenApiString)(IOpenApiPrimitive)this;
writer.WriteValue(stringValue.Value);
break;

case PrimitiveType.Byte:
var byteValue = (OpenApiByte)(IOpenApiPrimitive)this;
writer.WriteValue(byteValue.Value);
break;

case PrimitiveType.Binary:
var binaryValue = (OpenApiBinary)(IOpenApiPrimitive)this;
writer.WriteValue(binaryValue.Value);
break;

case PrimitiveType.Boolean:
var boolValue = (OpenApiBoolean)(IOpenApiPrimitive)this;
writer.WriteValue(boolValue.Value);
break;

case PrimitiveType.Date:
var dateValue = (OpenApiDate)(IOpenApiPrimitive)this;
writer.WriteValue(dateValue.Value);
break;

case PrimitiveType.DateTime:
var dateTimeValue = (OpenApiDateTime)(IOpenApiPrimitive)this;
writer.WriteValue(dateTimeValue.Value);
break;

case PrimitiveType.Password:
var passwordValue = (OpenApiPassword)(IOpenApiPrimitive)this;
writer.WriteValue(passwordValue.Value);
break;

default:
throw new OpenApiWriterException(
string.Format(
SRResource.PrimitiveTypeNotSupported,
this.PrimitiveType));
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ public static void AddExtension<T>(this T element, string name, IOpenApiAny any)

element.Extensions[name] = any ?? throw Error.ArgumentNull(nameof(any));
}

}
}
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Interfaces/IOpenApiExtensible.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public interface IOpenApiExtensible : IOpenApiElement
/// <summary>
/// Specification extensions.
/// </summary>
IDictionary<string, IOpenApiAny> Extensions { get; set; }
IDictionary<string, IOpenApiExtension> Extensions { get; set; }
}
}
21 changes: 21 additions & 0 deletions src/Microsoft.OpenApi/Interfaces/IOpenApiExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.OpenApi.Writers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.OpenApi.Interfaces
{
/// <summary>
/// Interface requuired for implementing any custom extension
/// </summary>
public interface IOpenApiExtension
{
/// <summary>
/// Write out contents of custom extension
/// </summary>
/// <param name="writer"></param>
void Write(IOpenApiWriter writer);
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class OpenApiCallback : IOpenApiSerializable, IOpenApiReferenceable, IOpe
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiAny> Extensions { get; set; } = new Dictionary<string, IOpenApiAny>();
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();

/// <summary>
/// Add a <see cref="OpenApiPathItem"/> into the <see cref="PathItems"/>.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiAny> Extensions { get; set; } = new Dictionary<string, IOpenApiAny>();
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();

/// <summary>
/// Serialize <see cref="OpenApiComponents"/> to Open Api v3.0.
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi/Models/OpenApiContact.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class OpenApiContact : IOpenApiSerializable, IOpenApiExtensible
/// <summary>
/// This object MAY be extended with Specification Extensions.
/// </summary>
public IDictionary<string, IOpenApiAny> Extensions { get; set; } = new Dictionary<string, IOpenApiAny>();
public IDictionary<string, IOpenApiExtension> Extensions { get; set; } = new Dictionary<string, IOpenApiExtension>();

/// <summary>
/// Serialize <see cref="OpenApiContact"/> to Open Api v3.0
Expand Down
Loading