-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from bonsai-rx/discriminator-dev
Add support for oneOf inheritance
- Loading branch information
Showing
5 changed files
with
248 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using NJsonSchema; | ||
using NJsonSchema.CodeGeneration.CSharp; | ||
|
||
namespace Bonsai.Sgen | ||
{ | ||
internal class CSharpTypeResolver : NJsonSchema.CodeGeneration.CSharp.CSharpTypeResolver | ||
{ | ||
readonly Dictionary<JsonSchema, JsonSchema> _baseTypeCache = new(); | ||
|
||
public CSharpTypeResolver(CSharpGeneratorSettings settings) | ||
: base(settings) | ||
{ | ||
} | ||
|
||
public CSharpTypeResolver(CSharpGeneratorSettings settings, JsonSchema exceptionSchema) | ||
: base(settings, exceptionSchema) | ||
{ | ||
} | ||
|
||
public override JsonSchema RemoveNullability(JsonSchema schema) | ||
{ | ||
JsonSchema? selectedSchema = null; | ||
foreach (JsonSchema o in schema.ActualSchema.OneOf) | ||
{ | ||
if (o.IsNullable(SchemaType.JsonSchema)) | ||
{ | ||
continue; | ||
} | ||
|
||
if (selectedSchema == null) | ||
{ | ||
selectedSchema = o; | ||
} | ||
else | ||
{ | ||
return ResolveBaseTypeSchema(schema.ActualSchema); | ||
} | ||
} | ||
|
||
return selectedSchema ?? schema; | ||
} | ||
|
||
private JsonSchema ResolveBaseTypeSchema(JsonSchema schema) | ||
{ | ||
if (!_baseTypeCache.TryGetValue(schema, out JsonSchema? baseSchema)) | ||
{ | ||
foreach (JsonSchema o in schema.OneOf) | ||
{ | ||
if (o.IsNullable(SchemaType.JsonSchema)) | ||
{ | ||
continue; | ||
} | ||
|
||
if (baseSchema == null) | ||
{ | ||
baseSchema = o; | ||
} | ||
else | ||
{ | ||
baseSchema = FindBestBaseSchema(baseSchema, o); | ||
if (baseSchema == null) break; | ||
} | ||
} | ||
|
||
baseSchema ??= JsonSchema.CreateAnySchema(); | ||
_baseTypeCache[schema] = baseSchema; | ||
} | ||
|
||
return baseSchema; | ||
} | ||
|
||
private static JsonSchema? FindBestBaseSchema(JsonSchema baseSchema, JsonSchema schema) | ||
{ | ||
while (!IsAssignableFrom(baseSchema.ActualSchema, schema)) | ||
{ | ||
baseSchema = baseSchema.ActualSchema.InheritedSchema; | ||
if (baseSchema == null) break; | ||
} | ||
|
||
return baseSchema; | ||
} | ||
|
||
private static bool IsAssignableFrom(JsonSchema schema, JsonSchema? typeSchema) | ||
{ | ||
while (typeSchema?.ActualSchema != null && schema != typeSchema.ActualSchema) | ||
{ | ||
typeSchema = typeSchema.ActualSchema.InheritedSchema; | ||
} | ||
|
||
return typeSchema?.ActualSchema != null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using NJsonSchema; | ||
using NJsonSchema.CodeGeneration; | ||
using NJsonSchema.Visitors; | ||
|
||
namespace Bonsai.Sgen | ||
{ | ||
public static class JsonSchemaExtensions | ||
{ | ||
public static JsonSchema WithUniqueDiscriminatorProperties(this JsonSchema schema) | ||
{ | ||
var visitor = new DiscriminatorSchemaVisitor(schema); | ||
visitor.Visit(schema); | ||
return schema; | ||
} | ||
|
||
class DiscriminatorSchemaVisitor : JsonSchemaVisitorBase | ||
{ | ||
public DiscriminatorSchemaVisitor(object rootObject) | ||
{ | ||
RootObject = rootObject; | ||
} | ||
|
||
public object RootObject { get; } | ||
|
||
protected override JsonSchema VisitSchema(JsonSchema schema, string path, string typeNameHint) | ||
{ | ||
if (schema.DiscriminatorObject != null) | ||
{ | ||
foreach (var derivedSchema in schema.GetDerivedSchemas(RootObject).Keys) | ||
{ | ||
foreach (var property in derivedSchema.Properties.Keys.ToList()) | ||
{ | ||
if (property == schema.Discriminator) | ||
{ | ||
derivedSchema.Properties.Remove(property); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return schema; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters