RepreZen / KaiZen-OpenApi-Parser

High-performance Parser, Validator, and Java Object Model for OpenAPI 3.x
130 stars 31 forks source link

Support union-like extension capability #122

Open andylowry opened 6 years ago

andylowry commented 6 years ago

The recently added discriminator and discriminatorValue properties makes it possible to create something that's sort of like a discriminated union style of subtyping, but it's not as tight as it ought to be.

The goal is to create a form of supertype that meets the need for multiple types that are not in an extensionOf relationship to nevertheless satisfy some other common type. This is similar to the use of "marker" interfaces in Java that do not contribute any required members. Any other type can be made to satisfy (in the instanceof meaning) such an interface simply be declaring that the type implements the marker interface.

In our case, we need more than just marker interfaces, because of the need for a delegating factory in the supertype. I.e. the supertype must give rise to a generated class, not just a generated interface, of which the factory becomes a generated static member. This factory is responsible for constructing an instance of the correct subtype when encountering a JSON object in a context requiring the supertype, during overlay construction.

This is where discriminators come, in and why this ends up looking quite a bit like a discriminated union. The supertype factory must delegate to a subtype factory, but to do that it must be able to select the correct subtype. The discriminator property in the supertype specification defines a path, relative to the JSON node to which the factory is applied, and from which a string value is obtained. That string value is compared with the declared discriminatorValues of the subtypes (defaulting to the simple name of the generated subtype interface) to decide which subtype factory to use.

In order to support this more fully, we need something beyond extensionOf to establish this other form of subtyping relationship. At present, extensionOf can be used, but it forces the subtypes to expend their sole Java extends opportunity for this use. We'll now support the following new type properties:

Additional rules:

A couple of other problems that have emerged with the existing support for discriminators will be addressed in the work on this issue: