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
2 changes: 1 addition & 1 deletion Common.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- Common Properties used by all assemblies -->
<PropertyGroup>
<LangVersion>10</LangVersion>
<TargetFrameworks>netstandard2.0;net8</TargetFrameworks>
<TargetFrameworks>netstandard2.1;net8</TargetFrameworks>
<ImplicitUsings>disable</ImplicitUsings>
<Company>ByteBard</Company>
<PackageProjectUrl>https://github.com/ByteBardOrg/AsyncAPI.NET</PackageProjectUrl>
Expand Down
5 changes: 0 additions & 5 deletions src/ByteBard.AsyncAPI.Readers/AsyncApiReaderSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,5 @@ public ICollection<IBindingParser<IBinding>>
/// External reference reader implementation provided by users for reading external resources.
/// </summary>
public IStreamLoader ExternalReferenceLoader { get; set; } = null;

/// <summary>
/// URL where relative references should be resolved from if.
/// </summary>
public Uri BaseUrl { get; set; }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
<PackageId>ByteBard.AsyncAPI.NET.Readers</PackageId>
<AssemblyName>ByteBard.AsyncAPI.Readers</AssemblyName>
<RootNamespace>ByteBard.AsyncAPI.Readers</RootNamespace>
<TargetFrameworks>netstandard2.0;net8</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="JsonPointer.Net" Version="5.0.2" />
<PackageReference Include="JsonPointer.Net" Version="5.3.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.5" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageReference Include="System.Text.Json" Version="9.0.1" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
<PackageReference Include="YamlDotNet" Version="13.0.1" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ public static IAsyncApiExtension LoadExtension(string name, ParseNode node)
return node.CreateAny();
}
}
}
}
11 changes: 11 additions & 0 deletions src/ByteBard.AsyncAPI.Readers/ParseNodes/ListNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ public override List<T> CreateSimpleList<T>(Func<ValueNode, T> map)
return this.nodeList.Select(n => map(new ValueNode(this.Context, n))).ToList();
}

public override HashSet<T> CreateSimpleSet<T>(Func<ValueNode, T> map)
{
if (this.nodeList == null)
{
throw new AsyncApiReaderException(
$"Expected list while parsing {typeof(T).Name}");
}

return this.nodeList.Select(n => map(new ValueNode(this.Context, n))).ToHashSet();
}

public IEnumerator<ParseNode> GetEnumerator()
{
return this.nodeList.Select(n => Create(this.Context, n)).ToList().GetEnumerator();
Expand Down
47 changes: 46 additions & 1 deletion src/ByteBard.AsyncAPI.Readers/ParseNodes/MapNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,42 @@ public PropertyNode this[string key]
}
}

public override Dictionary<string, T> CreateMap<T>(Func<string, string> keySelector, Func<MapNode, string, T> map)
{
var jsonMap = this.node;
if (jsonMap == null)
{
throw new AsyncApiReaderException($"Expected map while parsing {typeof(T).Name}", this.Context);
}

var nodes = jsonMap.Select(
n =>
{
var originalKey = n.Key;
var newKey = keySelector(originalKey);
T value;
try
{
this.Context.StartObject(originalKey);
value = n.Value is JsonObject
? map(new MapNode(this.Context, n.Value), originalKey)
: default(T);
}
finally
{
this.Context.EndObject();
}

return new
{
key = newKey,
value,
};
});

return nodes.ToDictionary(k => k.key, v => v.value);
}

public override Dictionary<string, T> CreateMap<T>(Func<MapNode, T> map)
{
var jsonMap = this.node;
Expand Down Expand Up @@ -207,14 +243,23 @@ public override AsyncApiAny CreateAny()
return new AsyncApiAny(this.node);
}

public void ParseFields<T>(ref T parentInstance, IDictionary<string, Action<T, ParseNode>> fixedFields, IDictionary<Func<string, bool>, Action<T, string, ParseNode>> patternFields)
public void ParseFields<T>(T parentInstance, IDictionary<string, Action<T, ParseNode>> fixedFields, IDictionary<Func<string, bool>, Action<T, string, ParseNode>> patternFields)
{
foreach (var propertyNode in this)
{
propertyNode.ParseField(parentInstance, fixedFields, patternFields);
}
}

// Parse only patternfields on top.
public void ParseFields<T>(T parentInstance, IDictionary<Func<string, bool>, Action<T, string, ParseNode>> patternFields)
{
foreach (var propertyNode in this)
{
propertyNode.ParseField(parentInstance, patternFields);
}
}

private string ToScalarValue(JsonNode node)
{
var scalarNode = node is JsonValue value ? value : throw new AsyncApiException($"Expected scalar value");
Expand Down
10 changes: 10 additions & 0 deletions src/ByteBard.AsyncAPI.Readers/ParseNodes/ParseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public virtual List<T> CreateList<T>(Func<MapNode, T> map)
throw new AsyncApiReaderException("Cannot create list from this type of node.", this.Context);
}

public virtual Dictionary<string, T> CreateMap<T>(Func<string, string> keySelector, Func<MapNode, string, T> map)
{
throw new AsyncApiReaderException("Cannot create map from this type of node.", this.Context);
}

public virtual Dictionary<string, T> CreateMap<T>(Func<MapNode, T> map)
{
throw new AsyncApiReaderException("Cannot create map from this type of node.", this.Context);
Expand All @@ -72,6 +77,11 @@ public virtual List<T> CreateSimpleList<T>(Func<ValueNode, T> map)
throw new AsyncApiReaderException("Cannot create simple list from this type of node.", this.Context);
}

public virtual HashSet<T> CreateSimpleSet<T>(Func<ValueNode, T> map)
{
throw new AsyncApiReaderException("Cannot create simple list from this type of node.", this.Context);
}

public virtual Dictionary<string, T> CreateSimpleMap<T>(Func<ValueNode, T> map)
{
throw new AsyncApiReaderException("Cannot create simple map from this type of node.", this.Context);
Expand Down
26 changes: 26 additions & 0 deletions src/ByteBard.AsyncAPI.Readers/ParseNodes/PropertyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,32 @@ public PropertyNode(ParsingContext context, string name, JsonNode node)

public ParseNode Value { get; set; }

public void ParseField<T>(T parentInstance, IDictionary<Func<string, bool>, Action<T, string, ParseNode>> patternFields)
{
var map = patternFields.Where(p => p.Key(this.Name)).Select(p => p.Value).FirstOrDefault();
if (map != null)
{
try
{
this.Context.StartObject(this.Name);
map(parentInstance, this.Name, this.Value);
}
catch (AsyncApiReaderException ex)
{
this.Context.Diagnostic.Errors.Add(new AsyncApiError(ex));
}
catch (AsyncApiException ex)
{
ex.Pointer = this.Context.GetLocation();
this.Context.Diagnostic.Errors.Add(new AsyncApiError(ex));
}
finally
{
this.Context.EndObject();
}
}
}

public void ParseField<T>(
T parentInstance,
IDictionary<string, Action<T, ParseNode>> fixedFields,
Expand Down
1 change: 0 additions & 1 deletion src/ByteBard.AsyncAPI.Readers/ParseNodes/ValueNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public override string GetScalarValue()
{
if (this.cachedScalarValue == null)
{
// TODO: Update this property to use the .ToString() or JsonReader.
var scalarNode = this.node is JsonValue value ? value : throw new AsyncApiException($"Expected scalar value");
this.cachedScalarValue = Convert.ToString(scalarNode.GetValue<object>(), this.Context.Settings.CultureInfo);
}
Expand Down
76 changes: 71 additions & 5 deletions src/ByteBard.AsyncAPI.Readers/ParsingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ namespace ByteBard.AsyncAPI.Readers
using ByteBard.AsyncAPI.Readers.Interface;
using ByteBard.AsyncAPI.Readers.ParseNodes;
using ByteBard.AsyncAPI.Readers.V2;

using ByteBard.AsyncAPI.Readers.V3;
public class ParsingContext
{
private readonly Stack<string> currentLocation = new();
private readonly Dictionary<string, object> tempStorage = new();
private readonly Dictionary<object, Dictionary<string, object>> scopedTempStorage = new();
public volatile int MessageCounter = 0;
public volatile int OperationCounter = 0;

internal Dictionary<string, Func<AsyncApiAny, IAsyncApiExtension>> ExtensionParsers
{
Expand All @@ -40,7 +44,7 @@ internal Dictionary<string, Func<AsyncApiAny, IAsyncApiExtension>> ExtensionPars
public AsyncApiDiagnostic Diagnostic { get; }

/// <summary>
/// Gets the settings used fore reading json.
/// Gets the settings used fore reading json.
/// </summary>
public AsyncApiReaderSettings Settings { get; }

Expand Down Expand Up @@ -82,19 +86,35 @@ internal AsyncApiDocument Parse(JsonNode jsonNode)
this.VersionService = new AsyncApiV2VersionService(this.Diagnostic);
doc = this.VersionService.LoadDocument(this.RootNode);

// Register components
this.Workspace.RegisterComponents(doc); // pre-register components.
this.Workspace.RegisterComponent(string.Empty, this.ParseToStream(jsonNode)); // register root document.
this.Workspace.SetRootDocument(doc);
this.Workspace.RegisterComponents(doc);
this.Workspace.RegisterComponent(string.Empty, this.ParseToStream(doc));

this.Diagnostic.SpecificationVersion = AsyncApiVersion.AsyncApi2_0;
break;
case string version when version.StartsWith("3"):
this.VersionService = new AsyncApiV3VersionService(this.Diagnostic);
doc = this.VersionService.LoadDocument(this.RootNode);

this.Workspace.SetRootDocument(doc);
this.Workspace.RegisterComponents(doc);
this.Workspace.RegisterComponent(string.Empty, this.ParseToStream(jsonNode));

this.Diagnostic.SpecificationVersion = AsyncApiVersion.AsyncApi3_0;
break;
default:
throw new AsyncApiUnsupportedSpecVersionException(inputVersion);
}

return doc;
}

private Stream ParseToStream(AsyncApiDocument document)
{
var json = document.SerializeAsJson(AsyncApiVersion.AsyncApi3_0);
return this.ParseToStream(JsonNode.Parse(json));
}

private Stream ParseToStream(JsonNode node)
{
var stream = new MemoryStream();
Expand All @@ -120,6 +140,10 @@ internal T ParseFragment<T>(JsonNode jsonNode, AsyncApiVersion version)
this.VersionService = new AsyncApiV2VersionService(this.Diagnostic);
element = this.VersionService.LoadElement<T>(node);
break;
case AsyncApiVersion.AsyncApi3_0:
this.VersionService = new AsyncApiV3VersionService(this.Diagnostic);
element = this.VersionService.LoadElement<T>(node);
break;
}

return element;
Expand All @@ -133,6 +157,48 @@ private static string GetVersion(RootNode rootNode)

internal IAsyncApiVersionService VersionService { get; set; }

public T GetFromTempStorage<T>(string key, object scope = null)
{
Dictionary<string, object> storage;

if (scope == null)
{
storage = this.tempStorage;
}
else if (!this.scopedTempStorage.TryGetValue(scope, out storage))
{
return default;
}

return storage.TryGetValue(key, out var value) ? (T)value : default;
}

/// <summary>
/// Sets the temporary storage for this key and value.
/// </summary>
public void SetTempStorage(string key, object value, object scope = null)
{
Dictionary<string, object> storage;

if (scope == null)
{
storage = this.tempStorage;
}
else if (!this.scopedTempStorage.TryGetValue(scope, out storage))
{
storage = this.scopedTempStorage[scope] = new();
}

if (value == null)
{
storage.Remove(key);
}
else
{
storage[key] = value;
}
}

public void EndObject()
{
this.currentLocation.Pop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public AsyncApiReferenceCollector(
{
this.workspace = workspace;
}

/// <summary>
/// List of all external references collected from AsyncApiDocument.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public Stream Load(Uri uri)
}
catch (Exception ex)
{

throw new AsyncApiReaderException($"Something went wrong trying to fetch '{uri.OriginalString}. {ex.Message}'", ex);
}
}
Expand All @@ -50,7 +49,6 @@ public async Task<Stream> LoadAsync(Uri uri)
}
catch (Exception ex)
{

throw new AsyncApiReaderException($"Something went wrong trying to fetch '{uri.OriginalString}'. {ex.Message}", ex);
}
}
Expand Down
Loading
Loading