1
1
using NJsonSchema ;
2
- using NJsonSchema . CodeGeneration ;
3
2
using NJsonSchema . Visitors ;
4
3
5
4
namespace Bonsai . Sgen
6
5
{
7
6
internal static class JsonSchemaExtensions
8
7
{
9
- public static JsonSchema WithUniqueDiscriminatorProperties ( this JsonSchema schema )
8
+ public static JsonSchema WithResolvedDiscriminatorInheritance ( this JsonSchema schema )
10
9
{
11
- var visitor = new DiscriminatorSchemaVisitor ( schema ) ;
12
- visitor . Visit ( schema ) ;
10
+ var discriminatorVisitor = new DiscriminatorSchemaVisitor ( schema ) ;
11
+ var derivedDiscriminatorVisitor = new DerivedDiscriminatorSchemaVisitor ( ) ;
12
+ discriminatorVisitor . Visit ( schema ) ;
13
+ derivedDiscriminatorVisitor . Visit ( schema ) ;
13
14
return schema ;
14
15
}
15
16
16
17
class DiscriminatorSchemaVisitor : JsonSchemaVisitorBase
17
18
{
18
- readonly Dictionary < JsonSchema , string > reverseTypeNameLookup = new ( ) ;
19
+ readonly Dictionary < JsonSchema , string > definitionTypeNameLookup = new ( ) ;
19
20
20
21
public DiscriminatorSchemaVisitor ( JsonSchema rootObject )
21
22
{
@@ -34,7 +35,11 @@ private void ResolveOneOfInheritance(JsonSchema schema, JsonSchema baseSchema)
34
35
continue ;
35
36
}
36
37
37
- derivedSchema . ActualSchema . AllOf . Add ( new JsonSchema { Reference = baseSchema } ) ;
38
+ var actualSchema = derivedSchema . ActualSchema ;
39
+ if ( ! actualSchema . AllOf . Any ( schema => schema . Reference == baseSchema ) )
40
+ {
41
+ actualSchema . AllOf . Add ( new JsonSchema { Reference = baseSchema } ) ;
42
+ }
38
43
}
39
44
}
40
45
@@ -43,15 +48,16 @@ protected override JsonSchema VisitSchema(JsonSchema schema, string path, string
43
48
var actualSchema = schema . ActualSchema ;
44
49
if ( actualSchema . DiscriminatorObject != null )
45
50
{
46
- if ( schema is JsonSchemaProperty || schema . ParentSchema ? . Item == schema )
51
+ var isDefinition = definitionTypeNameLookup . TryGetValue ( actualSchema , out _ ) ;
52
+ if ( schema is JsonSchemaProperty || schema . ParentSchema ? . Item == schema || isDefinition )
47
53
{
48
- if ( string . IsNullOrEmpty ( typeNameHint ) &&
49
- ! reverseTypeNameLookup . TryGetValue ( actualSchema , out typeNameHint ) )
54
+ var discriminatorSchema = isDefinition ? actualSchema : null ;
55
+ if ( string . IsNullOrEmpty ( typeNameHint ) )
50
56
{
51
57
typeNameHint = "Anonymous" ;
52
58
}
53
59
54
- if ( ! RootObject . Definitions . TryGetValue ( typeNameHint , out JsonSchema ? discriminatorSchema ) )
60
+ if ( discriminatorSchema == null && ! RootObject . Definitions . TryGetValue ( typeNameHint , out discriminatorSchema ) )
55
61
{
56
62
discriminatorSchema = new JsonSchema ( ) ;
57
63
discriminatorSchema . DiscriminatorObject = actualSchema . DiscriminatorObject ;
@@ -64,23 +70,13 @@ protected override JsonSchema VisitSchema(JsonSchema schema, string path, string
64
70
if ( discriminatorSchema . OneOf . Count > 0 )
65
71
{
66
72
ResolveOneOfInheritance ( discriminatorSchema , discriminatorSchema ) ;
67
- discriminatorSchema . OneOf . Clear ( ) ;
68
73
}
69
74
}
70
75
71
- schema . DiscriminatorObject = null ;
72
- schema . IsAbstract = false ;
73
- return schema ;
74
- }
75
-
76
- foreach ( var derivedSchema in schema . GetDerivedSchemas ( RootObject ) . Keys )
77
- {
78
- foreach ( var property in derivedSchema . Properties . Keys . ToList ( ) )
76
+ if ( ! isDefinition )
79
77
{
80
- if ( property == schema . Discriminator )
81
- {
82
- derivedSchema . Properties . Remove ( property ) ;
83
- }
78
+ actualSchema . DiscriminatorObject = null ;
79
+ actualSchema . IsAbstract = false ;
84
80
}
85
81
}
86
82
}
@@ -111,7 +107,7 @@ private void VisitDefinitions(JsonSchema schema)
111
107
{
112
108
foreach ( var definition in schema . Definitions )
113
109
{
114
- reverseTypeNameLookup [ definition . Value ] = definition . Key ;
110
+ definitionTypeNameLookup [ definition . Value ] = definition . Key ;
115
111
VisitDefinitions ( definition . Value ) ;
116
112
}
117
113
}
@@ -139,5 +135,22 @@ private void VisitDefinitions(IDictionary<string, JsonSchemaProperty> dictionary
139
135
}
140
136
}
141
137
}
138
+
139
+ class DerivedDiscriminatorSchemaVisitor : JsonSchemaVisitorBase
140
+ {
141
+ protected override JsonSchema VisitSchema ( JsonSchema schema , string path , string typeNameHint )
142
+ {
143
+ foreach ( var baseSchema in schema . AllInheritedSchemas )
144
+ {
145
+ var discriminatorSchema = baseSchema . DiscriminatorObject ;
146
+ if ( discriminatorSchema != null )
147
+ {
148
+ schema . Properties . Remove ( discriminatorSchema . PropertyName ) ;
149
+ }
150
+ }
151
+
152
+ return schema ;
153
+ }
154
+ }
142
155
}
143
156
}
0 commit comments