forked from loafle/openapi-generator-original
[dart-dio] Fix non legacy discriminator behavior (#14291)
* override createDiscriminator * assign discriminator = null to remove duplicates * added discriminatorValue extension * added _defaults * formatting * samples * use gitter instead * remove comment * updated samples * revert formatting changes * update samples * change file permissions * remove discriminator check for anyOf * add comment to createDiscriminator
This commit is contained in:
@@ -19,10 +19,13 @@ package org.openapitools.codegen.languages;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.media.Discriminator;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
|
||||
import org.openapitools.codegen.api.TemplatePathLocator;
|
||||
import org.openapitools.codegen.config.GlobalSettings;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
@@ -44,6 +47,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -275,7 +279,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
|
||||
imports.put("Uint8List", "dart:typed_data");
|
||||
imports.put("MultipartFile", DIO_IMPORT);
|
||||
}
|
||||
|
||||
|
||||
private void configureDateLibrary(String srcFolder) {
|
||||
switch (dateLibrary) {
|
||||
case DATE_LIBRARY_TIME_MACHINE:
|
||||
@@ -400,6 +404,7 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
|
||||
private final String kHasAncestorOnlyProps = "x-has-ancestor-only-props";
|
||||
private final String kSelfAndAncestorOnlyProps = "x-self-and-ancestor-only-props";
|
||||
private final String kHasSelfAndAncestorOnlyProps = "x-has-self-and-ancestor-only-props";
|
||||
private final String kParentDiscriminator = "x-parent-discriminator";
|
||||
|
||||
// adapts codegen models and property to dart rules of inheritance
|
||||
private void adaptToDartInheritance(Map<String, ModelsMap> objs) {
|
||||
@@ -449,6 +454,14 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
|
||||
cm.vendorExtensions.put(kIsChild, isChild);
|
||||
cm.vendorExtensions.put(kIsParent, isParent);
|
||||
cm.vendorExtensions.put(kIsPure, isPure);
|
||||
if (!isParent && (cm.oneOf == null || cm.oneOf.isEmpty())) {
|
||||
//discriminator has no meaning here
|
||||
if (cm.discriminator!=null) {
|
||||
cm.vendorExtensions.put(kParentDiscriminator, cm.discriminator);
|
||||
cm.discriminator=null;
|
||||
}
|
||||
|
||||
}
|
||||
// when pure:
|
||||
// vars = allVars = selfOnlyProperties = kSelfAndAncestorOnlyProps
|
||||
// ancestorOnlyProps = empty
|
||||
@@ -541,6 +554,30 @@ public class DartDioClientCodegen extends AbstractDartCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
/// override the default behavior of createDiscriminator
|
||||
/// to remove extra mappings added as a side effect of setLegacyDiscriminatorBehavior(false)
|
||||
/// this ensures 1-1 schema mapping instead of 1-many
|
||||
@Override
|
||||
protected CodegenDiscriminator createDiscriminator(String schemaName, Schema schema, OpenAPI openAPI) {
|
||||
CodegenDiscriminator sub = super.createDiscriminator(schemaName, schema, openAPI);
|
||||
Discriminator originalDiscriminator = schema.getDiscriminator();
|
||||
if (originalDiscriminator!=null) {
|
||||
Map<String,String> originalMapping = originalDiscriminator.getMapping();
|
||||
if (originalMapping != null && !originalMapping.isEmpty()) {
|
||||
//we already have a discriminator mapping, remove everything else
|
||||
for (MappedModel currentMappings : new HashSet<>(sub.getMappedModels())) {
|
||||
if (originalMapping.containsKey(currentMappings.getMappingName())) {
|
||||
//all good
|
||||
} else {
|
||||
sub.getMapping().remove(currentMappings.getMappingName());
|
||||
sub.getMappedModels().remove(currentMappings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
|
||||
objs = super.postProcessAllModels(objs);
|
||||
|
||||
@@ -10,7 +10,9 @@ part '{{classFilename}}.g.dart';
|
||||
{{>serialization/built_value/class_header}} {
|
||||
{{>serialization/built_value/class_members}}
|
||||
}
|
||||
|
||||
{{#discriminator}}{{#hasDiscriminatorWithNonEmptyMapping}}
|
||||
{{>serialization/built_value/class_discriminator}}
|
||||
{{/hasDiscriminatorWithNonEmptyMapping}}{{/discriminator}}
|
||||
{{>serialization/built_value/class_serializer}}{{#vendorExtensions.x-is-parent}}
|
||||
|
||||
{{>serialization/built_value/class_concrete}}{{/vendorExtensions.x-is-parent}}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
extension {{classname}}DiscriminatorExt on {{classname}} {
|
||||
String? get discriminatorValue {
|
||||
{{#mappedModels}}
|
||||
if (this is {{modelName}}) {
|
||||
return r'{{mappingName}}';
|
||||
}
|
||||
{{/mappedModels}}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension {{classname}}BuilderDiscriminatorExt on {{classname}}Builder {
|
||||
String? get discriminatorValue {
|
||||
{{#mappedModels}}
|
||||
if (this is {{modelName}}Builder) {
|
||||
return r'{{mappingName}}';
|
||||
}
|
||||
{{/mappedModels}}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
factory {{classname}}([void updates({{classname}}Builder b)]) = _${{classname}};
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults({{{classname}}}Builder b) => b{{#vendorExtensions.x-self-and-ancestor-only-props}}{{#defaultValue}}
|
||||
static void _defaults({{{classname}}}Builder b) => b{{#vendorExtensions.x-parent-discriminator}}..{{propertyName}}=b.discriminatorValue{{/vendorExtensions.x-parent-discriminator}}{{#vendorExtensions.x-self-and-ancestor-only-props}}{{#defaultValue}}
|
||||
..{{{name}}} = {{#isEnum}}{{^isContainer}}const {{{enumName}}}._({{/isContainer}}{{/isEnum}}{{{defaultValue}}}{{#isEnum}}{{^isContainer}}){{/isContainer}}{{/isEnum}}{{/defaultValue}}{{/vendorExtensions.x-self-and-ancestor-only-props}};
|
||||
|
||||
{{/vendorExtensions.x-is-parent}} @BuiltValueSerializer(custom: true)
|
||||
|
||||
@@ -32,14 +32,12 @@ abstract class Bar implements Entity, Built<Bar, BarBuilder> {
|
||||
@BuiltValueField(wireName: r'barPropA')
|
||||
String? get barPropA;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
Bar._();
|
||||
|
||||
factory Bar([void updates(BarBuilder b)]) = _$Bar;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(BarBuilder b) => b;
|
||||
static void _defaults(BarBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<Bar> get serializer => _$BarSerializer();
|
||||
|
||||
@@ -32,14 +32,12 @@ abstract class BarCreate implements Entity, Built<BarCreate, BarCreateBuilder> {
|
||||
@BuiltValueField(wireName: r'barPropA')
|
||||
String? get barPropA;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
BarCreate._();
|
||||
|
||||
factory BarCreate([void updates(BarCreateBuilder b)]) = _$BarCreate;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(BarCreateBuilder b) => b;
|
||||
static void _defaults(BarCreateBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<BarCreate> get serializer => _$BarCreateSerializer();
|
||||
|
||||
@@ -19,14 +19,12 @@ part 'bar_ref.g.dart';
|
||||
/// * [atType] - When sub-classing, this defines the sub-class Extensible name
|
||||
@BuiltValue()
|
||||
abstract class BarRef implements EntityRef, Built<BarRef, BarRefBuilder> {
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
BarRef._();
|
||||
|
||||
factory BarRef([void updates(BarRefBuilder b)]) = _$BarRef;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(BarRefBuilder b) => b;
|
||||
static void _defaults(BarRefBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<BarRef> get serializer => _$BarRefSerializer();
|
||||
|
||||
@@ -42,6 +42,29 @@ abstract class BarRefOrValue implements Built<BarRefOrValue, BarRefOrValueBuilde
|
||||
static Serializer<BarRefOrValue> get serializer => _$BarRefOrValueSerializer();
|
||||
}
|
||||
|
||||
extension BarRefOrValueDiscriminatorExt on BarRefOrValue {
|
||||
String? get discriminatorValue {
|
||||
if (this is Bar) {
|
||||
return r'Bar';
|
||||
}
|
||||
if (this is BarRef) {
|
||||
return r'BarRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension BarRefOrValueBuilderDiscriminatorExt on BarRefOrValueBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is BarBuilder) {
|
||||
return r'Bar';
|
||||
}
|
||||
if (this is BarRefBuilder) {
|
||||
return r'BarRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$BarRefOrValueSerializer implements PrimitiveSerializer<BarRefOrValue> {
|
||||
@override
|
||||
final Iterable<Type> types = const [BarRefOrValue, _$BarRefOrValue];
|
||||
|
||||
@@ -41,6 +41,53 @@ abstract class Entity implements Addressable, Extensible {
|
||||
static Serializer<Entity> get serializer => _$EntitySerializer();
|
||||
}
|
||||
|
||||
extension EntityDiscriminatorExt on Entity {
|
||||
String? get discriminatorValue {
|
||||
if (this is Bar) {
|
||||
return r'Bar';
|
||||
}
|
||||
if (this is BarCreate) {
|
||||
return r'Bar_Create';
|
||||
}
|
||||
if (this is Foo) {
|
||||
return r'Foo';
|
||||
}
|
||||
if (this is Pasta) {
|
||||
return r'Pasta';
|
||||
}
|
||||
if (this is Pizza) {
|
||||
return r'Pizza';
|
||||
}
|
||||
if (this is PizzaSpeziale) {
|
||||
return r'PizzaSpeziale';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension EntityBuilderDiscriminatorExt on EntityBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is BarBuilder) {
|
||||
return r'Bar';
|
||||
}
|
||||
if (this is BarCreateBuilder) {
|
||||
return r'Bar_Create';
|
||||
}
|
||||
if (this is FooBuilder) {
|
||||
return r'Foo';
|
||||
}
|
||||
if (this is PastaBuilder) {
|
||||
return r'Pasta';
|
||||
}
|
||||
if (this is PizzaBuilder) {
|
||||
return r'Pizza';
|
||||
}
|
||||
if (this is PizzaSpezialeBuilder) {
|
||||
return r'PizzaSpeziale';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$EntitySerializer implements PrimitiveSerializer<Entity> {
|
||||
@override
|
||||
final Iterable<Type> types = const [Entity];
|
||||
|
||||
@@ -43,6 +43,29 @@ abstract class EntityRef implements Addressable, Extensible {
|
||||
static Serializer<EntityRef> get serializer => _$EntityRefSerializer();
|
||||
}
|
||||
|
||||
extension EntityRefDiscriminatorExt on EntityRef {
|
||||
String? get discriminatorValue {
|
||||
if (this is BarRef) {
|
||||
return r'BarRef';
|
||||
}
|
||||
if (this is FooRef) {
|
||||
return r'FooRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension EntityRefBuilderDiscriminatorExt on EntityRefBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is BarRefBuilder) {
|
||||
return r'BarRef';
|
||||
}
|
||||
if (this is FooRefBuilder) {
|
||||
return r'FooRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$EntityRefSerializer implements PrimitiveSerializer<EntityRef> {
|
||||
@override
|
||||
final Iterable<Type> types = const [EntityRef];
|
||||
|
||||
@@ -27,14 +27,12 @@ abstract class Foo implements Entity, Built<Foo, FooBuilder> {
|
||||
@BuiltValueField(wireName: r'fooPropB')
|
||||
String? get fooPropB;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
Foo._();
|
||||
|
||||
factory Foo([void updates(FooBuilder b)]) = _$Foo;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(FooBuilder b) => b;
|
||||
static void _defaults(FooBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<Foo> get serializer => _$FooSerializer();
|
||||
|
||||
@@ -23,14 +23,12 @@ abstract class FooRef implements EntityRef, Built<FooRef, FooRefBuilder> {
|
||||
@BuiltValueField(wireName: r'foorefPropA')
|
||||
String? get foorefPropA;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
FooRef._();
|
||||
|
||||
factory FooRef([void updates(FooRefBuilder b)]) = _$FooRef;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(FooRefBuilder b) => b;
|
||||
static void _defaults(FooRefBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<FooRef> get serializer => _$FooRefSerializer();
|
||||
|
||||
@@ -42,6 +42,29 @@ abstract class FooRefOrValue implements Built<FooRefOrValue, FooRefOrValueBuilde
|
||||
static Serializer<FooRefOrValue> get serializer => _$FooRefOrValueSerializer();
|
||||
}
|
||||
|
||||
extension FooRefOrValueDiscriminatorExt on FooRefOrValue {
|
||||
String? get discriminatorValue {
|
||||
if (this is Foo) {
|
||||
return r'Foo';
|
||||
}
|
||||
if (this is FooRef) {
|
||||
return r'FooRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension FooRefOrValueBuilderDiscriminatorExt on FooRefOrValueBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is FooBuilder) {
|
||||
return r'Foo';
|
||||
}
|
||||
if (this is FooRefBuilder) {
|
||||
return r'FooRef';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$FooRefOrValueSerializer implements PrimitiveSerializer<FooRefOrValue> {
|
||||
@override
|
||||
final Iterable<Type> types = const [FooRefOrValue, _$FooRefOrValue];
|
||||
|
||||
@@ -23,14 +23,12 @@ abstract class Pasta implements Entity, Built<Pasta, PastaBuilder> {
|
||||
@BuiltValueField(wireName: r'vendor')
|
||||
String? get vendor;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
Pasta._();
|
||||
|
||||
factory Pasta([void updates(PastaBuilder b)]) = _$Pasta;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(PastaBuilder b) => b;
|
||||
static void _defaults(PastaBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<Pasta> get serializer => _$PastaSerializer();
|
||||
|
||||
@@ -34,6 +34,23 @@ abstract class Pizza implements Entity {
|
||||
static Serializer<Pizza> get serializer => _$PizzaSerializer();
|
||||
}
|
||||
|
||||
extension PizzaDiscriminatorExt on Pizza {
|
||||
String? get discriminatorValue {
|
||||
if (this is PizzaSpeziale) {
|
||||
return r'PizzaSpeziale';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension PizzaBuilderDiscriminatorExt on PizzaBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is PizzaSpezialeBuilder) {
|
||||
return r'PizzaSpeziale';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$PizzaSerializer implements PrimitiveSerializer<Pizza> {
|
||||
@override
|
||||
final Iterable<Type> types = const [Pizza];
|
||||
|
||||
@@ -23,14 +23,12 @@ abstract class PizzaSpeziale implements Pizza, Built<PizzaSpeziale, PizzaSpezial
|
||||
@BuiltValueField(wireName: r'toppings')
|
||||
String? get toppings;
|
||||
|
||||
static const String discriminatorFieldName = r'@type';
|
||||
|
||||
PizzaSpeziale._();
|
||||
|
||||
factory PizzaSpeziale([void updates(PizzaSpezialeBuilder b)]) = _$PizzaSpeziale;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(PizzaSpezialeBuilder b) => b;
|
||||
static void _defaults(PizzaSpezialeBuilder b) => b..atType=b.discriminatorValue;
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
static Serializer<PizzaSpeziale> get serializer => _$PizzaSpezialeSerializer();
|
||||
|
||||
@@ -34,6 +34,29 @@ abstract class Animal {
|
||||
static Serializer<Animal> get serializer => _$AnimalSerializer();
|
||||
}
|
||||
|
||||
extension AnimalDiscriminatorExt on Animal {
|
||||
String? get discriminatorValue {
|
||||
if (this is Cat) {
|
||||
return r'Cat';
|
||||
}
|
||||
if (this is Dog) {
|
||||
return r'Dog';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
extension AnimalBuilderDiscriminatorExt on AnimalBuilder {
|
||||
String? get discriminatorValue {
|
||||
if (this is CatBuilder) {
|
||||
return r'Cat';
|
||||
}
|
||||
if (this is DogBuilder) {
|
||||
return r'Dog';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _$AnimalSerializer implements PrimitiveSerializer<Animal> {
|
||||
@override
|
||||
final Iterable<Type> types = const [Animal];
|
||||
|
||||
@@ -18,14 +18,12 @@ part 'cat.g.dart';
|
||||
/// * [declawed]
|
||||
@BuiltValue()
|
||||
abstract class Cat implements Animal, CatAllOf, Built<Cat, CatBuilder> {
|
||||
static const String discriminatorFieldName = r'className';
|
||||
|
||||
Cat._();
|
||||
|
||||
factory Cat([void updates(CatBuilder b)]) = _$Cat;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(CatBuilder b) => b
|
||||
static void _defaults(CatBuilder b) => b..className=b.discriminatorValue
|
||||
..color = 'red';
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
|
||||
@@ -18,14 +18,12 @@ part 'dog.g.dart';
|
||||
/// * [breed]
|
||||
@BuiltValue()
|
||||
abstract class Dog implements Animal, DogAllOf, Built<Dog, DogBuilder> {
|
||||
static const String discriminatorFieldName = r'className';
|
||||
|
||||
Dog._();
|
||||
|
||||
factory Dog([void updates(DogBuilder b)]) = _$Dog;
|
||||
|
||||
@BuiltValueHook(initializeBuilder: true)
|
||||
static void _defaults(DogBuilder b) => b
|
||||
static void _defaults(DogBuilder b) => b..className=b.discriminatorValue
|
||||
..color = 'red';
|
||||
|
||||
@BuiltValueSerializer(custom: true)
|
||||
|
||||
Reference in New Issue
Block a user