Skip to content

Commit

Permalink
Resolve Schema
Browse files Browse the repository at this point in the history
  • Loading branch information
chidozieononiwu committed Jun 13, 2023
1 parent bb313b5 commit 9feb94d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class Reference : ITokenSerializable

public bool IsRefObject()
{
return this.@ref != null;
return !string.IsNullOrEmpty(this.@ref);
}

public CodeFileToken[] TokenSerialize(SerializeContext context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public class Schema : Items, ITokenSerializable
tableItems = this.TokenSerializePropertyIntoTableItems(context, this.tableItems);
var tableRet = new List<CodeFileToken>();
var tableRows = new List<CodeFileToken>();
foreach (var tableItem in this.tableItems)
if (tableItems.Count > 0)
{
tableRows.AddRange(tableItem.TokenSerialize());
tableRows.AddRange(tableItems[0].TokenSerialize()); // Serialize only forst row to avoid flattened properties
}
if (tableRows.Count > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@ public Parameter GetResolvedParameter(Parameter parameter, string currentSwagger
return parameter;
}

public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, LinkedList<string> refChain = null)
public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, LinkedList<string> refChain = null, Dictionary<string, Definition> definitions = null)
{
string schemaKey = string.Empty;
refChain ??= new LinkedList<string>();
if (root == null)
{
Expand All @@ -186,6 +187,7 @@ public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, Link
var resolvedSchema = this.GetSchemaFromResolvedCache(root.@ref, currentSwaggerFilePath);
if (resolvedSchema != null)
{
Utils.AddSchemaToRootDefinition(resolvedSchema, definitions);
return resolvedSchema;
}

Expand All @@ -211,6 +213,7 @@ public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, Link
}

ret.originalRef = root.@ref;
Utils.AddSchemaToRootDefinition(ret, definitions);
return ret;
}

Expand All @@ -224,6 +227,8 @@ public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, Link
continue;
}

Utils.AddSchemaToRootDefinition(resolvedChild, definitions);

// should be in allOf property
foreach (var prop in resolvedChild.properties)
{
Expand All @@ -234,7 +239,9 @@ public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, Link

if (root.items != null && root.items.@ref != null && !refChain.Contains(root.items.@ref))
{
root.items = GetResolvedSchema(root.items, currentSwaggerFilePath, refChain);
var items = GetResolvedSchema(root.items, currentSwaggerFilePath, refChain);
root.items = items;
Utils.AddSchemaToRootDefinition(items, definitions);
}

if (root.properties != null)
Expand All @@ -248,11 +255,13 @@ public Schema GetResolvedSchema(Schema root, string currentSwaggerFilePath, Link

if (!refChain.Contains(rootProperty.Value.@ref) && !refChain.Contains(rootProperty.Value.@ref) && !refChain.Contains(rootProperty.Value.items?.@ref))
{
root.properties[rootProperty.Key] = this.GetResolvedSchema(rootProperty.Value, currentSwaggerFilePath, refChain);
var property = this.GetResolvedSchema(rootProperty.Value, currentSwaggerFilePath, refChain);
root.properties[rootProperty.Key] = property;
Utils.AddSchemaToRootDefinition(property, definitions);
}
}
}

Utils.AddSchemaToRootDefinition(root, definitions);
return root;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
Expand Down Expand Up @@ -120,7 +121,7 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
@in = param.@in,
description = param.description,
required = param.required,
schema = schemaCache.GetResolvedSchema(param.schema, referenceSwaggerFilePath),
schema = schemaCache.GetResolvedSchema(param.schema, referenceSwaggerFilePath, null, swaggerSpec.definitions),
format = param.format,
@ref = param.@ref,
type = param.type
Expand Down Expand Up @@ -199,17 +200,22 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referenceSwaggerFilePath);
AddDefinitionsToCache(referenceSwaggerSpec, referenceSwaggerFilePath, schemaCache);
schema = schemaCache.GetSchemaFromCache(referencePath, referenceSwaggerFilePath, false);
if (schema.originalRef == null)
{
schema.originalRef = referencePath;
}

if (schema != null && schema.IsRefObject())
referencePath = schema.@ref;
}
while (schema != null && schema.IsRefObject());
}
else
{
LinkedList<string> refChain = new LinkedList<string>();
// The initial refChain is the root level schema.
// There are some scenarios that the property of the root level schema is a ref to the root level itself (circular reference).
// Like "errorDetail" schema in common types.
schema = schemaCache.GetResolvedSchema(schema, referenceSwaggerFilePath, refChain);
}

LinkedList<string> refChain = new LinkedList<string>();
// The initial refChain is the root level schema.
// There are some scenarios that the property of the root level schema is a ref to the root level itself (circular reference).
// Like "errorDetail" schema in common types.
schema = schemaCache.GetResolvedSchema(schema, referenceSwaggerFilePath, refChain, swaggerSpec.definitions);
}

var headers = response.headers ?? new Dictionary<string, Header>();
Expand All @@ -221,14 +227,6 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
}
}

if (swaggerSpec.definitions != null)
{
foreach (var definition in swaggerSpec.definitions)
{
ret.SwaggerApiViewDefinitions.Add(definition.Key, definition.Value);
}
}

if (swaggerSpec.parameters != null)
{
foreach (var (key, value) in swaggerSpec.parameters)
Expand All @@ -241,14 +239,22 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
required = param.required,
format = param.format,
@in = param.@in,
schema = schemaCache.GetResolvedSchema(param.schema, swaggerFilePath),
schema = schemaCache.GetResolvedSchema(param.schema, swaggerFilePath, null, swaggerSpec.definitions),
@ref = param.@ref,
type = param.type
};
ret.SwaggerApiViewGlobalParameters.Add(key, swaggerApiViewParameter);
}
}

if (swaggerSpec.definitions != null)
{
foreach (var definition in swaggerSpec.definitions)
{
ret.SwaggerApiViewDefinitions.Add(definition.Key, definition.Value);
}
}

ret.Paths.SortByMethod();
return ret;
}
Expand Down
35 changes: 35 additions & 0 deletions tools/apiview/parsers/swagger-api-parser/SwaggerApiParser/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,40 @@ public static void SerializePatternedObjects(IDictionary<string, JsonElement> pa
}
}
}

public static void AddSchemaToRootDefinition(Schema schema, Dictionary<string, Definition> definitions)
{
if (!String.IsNullOrEmpty(schema.originalRef))
{
var schemaKey = Utils.GetDefinitionType(schema.originalRef);
if (definitions != null)
{
if (!definitions.ContainsKey(schemaKey))
{
definitions.Add(schemaKey, (Definition)schema);
}
else
{
Definition def = (Definition)schema;
if (definitions[schemaKey].IsRefObject())
{
definitions[schemaKey] = def;
}
else
{
definitions[schemaKey].description = definitions[schemaKey].description ?? def.description;
foreach (var prop in def.properties)
{
if (!definitions[schemaKey].properties.ContainsKey(prop.Key))
{
definitions[schemaKey].properties.Add(prop.Key, prop.Value);
}
}
}

}
}
}
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public async Task TestGenerateSwaggerApiViewCompute()
await codeFile.SerializeAsync(writer);*/
}

[Fact]
[Fact(Skip ="No longer grouping model proprties")]
public async Task TestGenerateSwaggerApiViewGroupedModelProperties()
{
var runCommandsFilePath = Path.GetFullPath("./fixtures/communicationserviceschat.json");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public async Task TestMultivariate()
await codeFile.SerializeAsync(writer);
}

[Fact]
[Fact(Skip ="Missing test file due to recursive file search")]
public async Task TestCommunicate()
{
const string multiVariateSwaggerFile = "./fixtures/communicate.json";
Expand Down

0 comments on commit 9feb94d

Please sign in to comment.