diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java index 077f79904a69..eae2b9a155a0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java @@ -77,6 +77,9 @@ public class DartDioClientCodegen extends AbstractDartCodegen { public static final String SKIP_COPY_WITH_DEFAULT_VALUE = "false"; private static final String CLIENT_NAME = "clientName"; + private static final String X_DISCRIMINATOR_MAPPED_MODELS_NONSELF = "x-discriminator-mapped-models-nonself"; + private static final String X_HAS_DISCRIMINATOR_SELF_MAPPING = "x-has-discriminator-self-mapping"; + private static final String X_DISCRIMINATOR_SELF_MAPPING_NAME = "x-discriminator-self-mapping-name"; @Getter @Setter private String dateLibrary; @@ -582,36 +585,200 @@ private void adaptToDartInheritance(Map objs) { } } + private int getSchemaInheritanceDepth(String schemaName, String ancestorSchemaName, Set visited) { + if (schemaName == null || ancestorSchemaName == null) { + return -1; + } + if (schemaName.equals(ancestorSchemaName)) { + return 0; + } + + Schema currentSchema = ModelUtils.getSchema(openAPI, schemaName); + if (currentSchema == null || currentSchema.getAllOf() == null || currentSchema.getAllOf().isEmpty()) { + return -1; + } + + int maxDepth = -1; + for (Object parentObj : currentSchema.getAllOf()) { + if (!(parentObj instanceof Schema)) { + continue; + } + Schema parentSchema = (Schema) parentObj; + String parentRef = parentSchema.get$ref(); + if (parentRef == null) { + continue; + } + + String parentSchemaName = ModelUtils.getSimpleRef(parentRef); + if (ancestorSchemaName.equals(parentSchemaName)) { + maxDepth = Math.max(maxDepth, 1); + continue; + } + + if (parentSchemaName != null && visited.add(parentSchemaName)) { + int parentDepth = getSchemaInheritanceDepth(parentSchemaName, ancestorSchemaName, visited); + if (parentDepth >= 0) { + maxDepth = Math.max(maxDepth, parentDepth + 1); + } + visited.remove(parentSchemaName); + } + } + + return maxDepth; + } + /// 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) { CodegenDiscriminator sub = super.createDiscriminator(schemaName, schema); - Discriminator originalDiscriminator = schema.getDiscriminator(); + if (sub == null) { + return null; + } + + if (sub.getMapping() != null) { + // Defensive copy: avoid mutating shared mapping objects from the parsed spec. + sub.setMapping(new LinkedHashMap<>(sub.getMapping())); + } + + Discriminator originalDiscriminator = getSchemaLocalDiscriminator(schema); if (originalDiscriminator != null) { Map 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); - } - } + // keep only explicitly declared mappings on the schema-local discriminator + filterMappedModels(sub, mappedModel -> originalMapping.containsKey(mappedModel.getMappingName())); } + orderMappedModelsBySchemaSpecificity(sub, schemaName); + prepareDiscriminatorTemplateData(sub, schemaName, toModelName(schemaName)); + return sub; } + + // For inherited discriminators, keep only real allOf descendants of this schema + // (e.g. Reptile keeps Crocodile/Turtle, but not Bird from Animal's mapping). + Set descendantSchemaNames = getAllOfDescendants(schemaName).stream() + .map(MappedModel::getSchemaName) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + if (ModelUtils.isComposedSchema(schema) && schema.getAllOf() != null) { + filterMappedModels(sub, mappedModel -> descendantSchemaNames.contains(mappedModel.getSchemaName()) + || schemaName.equals(mappedModel.getSchemaName())); + } + + orderMappedModelsBySchemaSpecificity(sub, schemaName); + prepareDiscriminatorTemplateData(sub, schemaName, toModelName(schemaName)); return sub; } + private void prepareDiscriminatorTemplateData(CodegenDiscriminator discriminator, String schemaName, String modelName) { + if (discriminator == null || discriminator.getMappedModels() == null) { + return; + } + + String selfMappingName = null; + List nonSelfMappedModels = new ArrayList<>(); + for (MappedModel mappedModel : discriminator.getMappedModels()) { + boolean isSelfMapping = Objects.equals(schemaName, mappedModel.getSchemaName()) + || Objects.equals(modelName, mappedModel.getModelName()); + if (isSelfMapping) { + selfMappingName = mappedModel.getMappingName(); + } else { + nonSelfMappedModels.add(mappedModel); + } + } + + discriminator.getVendorExtensions().put(X_DISCRIMINATOR_MAPPED_MODELS_NONSELF, nonSelfMappedModels); + discriminator.getVendorExtensions().put(X_HAS_DISCRIMINATOR_SELF_MAPPING, selfMappingName != null); + if (selfMappingName != null) { + discriminator.getVendorExtensions().put(X_DISCRIMINATOR_SELF_MAPPING_NAME, selfMappingName); + } else { + discriminator.getVendorExtensions().remove(X_DISCRIMINATOR_SELF_MAPPING_NAME); + } + } + + private void orderMappedModelsBySchemaSpecificity(CodegenDiscriminator discriminator, String ownerSchemaName) { + if (discriminator.getMappedModels() == null || discriminator.getMappedModels().size() < 2) { + return; + } + + List ordered = new ArrayList<>(discriminator.getMappedModels()); + Map inheritanceDepthBySchema = new HashMap<>(); + Map originalOrder = new HashMap<>(); + for (int i = 0; i < ordered.size(); i++) { + MappedModel mappedModel = ordered.get(i); + originalOrder.put(mappedModel, i); + inheritanceDepthBySchema.computeIfAbsent( + mappedModel.getSchemaName(), + schemaName -> getSchemaInheritanceDepth(schemaName, ownerSchemaName, new HashSet<>()) + ); + } + + ordered.sort((left, right) -> { + int leftDepth = inheritanceDepthBySchema.getOrDefault(left.getSchemaName(), -1); + int rightDepth = inheritanceDepthBySchema.getOrDefault(right.getSchemaName(), -1); + if (leftDepth != rightDepth) { + return Integer.compare(rightDepth, leftDepth); + } + + return Integer.compare(originalOrder.get(left), originalOrder.get(right)); + }); + + discriminator.setMappedModels(new LinkedHashSet<>(ordered)); + } + + private void filterMappedModels(CodegenDiscriminator discriminator, java.util.function.Predicate keepPredicate) { + for (MappedModel mappedModel : new HashSet<>(discriminator.getMappedModels())) { + if (!keepPredicate.test(mappedModel)) { + if (discriminator.getMapping() != null) { + discriminator.getMapping().remove(mappedModel.getMappingName()); + } + discriminator.getMappedModels().remove(mappedModel); + } + } + } + + private Discriminator getSchemaLocalDiscriminator(Schema schema) { + if (schema == null) { + return null; + } + + if (schema.getDiscriminator() != null) { + return schema.getDiscriminator(); + } + + if (ModelUtils.isComposedSchema(schema) && schema.getAllOf() != null) { + // Prefer inline allOf discriminator (child-local) over inherited parent discriminators. + for (Object allOfSchemaObj : schema.getAllOf()) { + if (!(allOfSchemaObj instanceof Schema)) { + continue; + } + Schema allOfSchema = (Schema) allOfSchemaObj; + if (allOfSchema.getDiscriminator() != null) { + return allOfSchema.getDiscriminator(); + } + } + } + + return null; + } + @Override public Map postProcessAllModels(Map objs) { objs = super.postProcessAllModels(objs); if (SERIALIZATION_LIBRARY_BUILT_VALUE.equals(library)) { adaptToDartInheritance(objs); syncRootTypesWithInnerVars(objs); + for (ModelsMap entry : objs.values()) { + for (ModelMap mo : entry.getModels()) { + CodegenModel cm = mo.getModel(); + if (cm != null && cm.discriminator != null) { + String ownerSchemaName = ObjectUtils.firstNonNull(cm.getSchemaName(), cm.getName(), cm.getClassname()); + orderMappedModelsBySchemaSpecificity(cm.discriminator, ownerSchemaName); + prepareDiscriminatorTemplateData(cm.discriminator, cm.getSchemaName(), cm.classname); + } + } + } } // loop through models to update the imports diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_discriminator.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_discriminator.mustache index f867345883b1..a523fded4812 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_discriminator.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_discriminator.mustache @@ -1,20 +1,31 @@ extension {{classname}}DiscriminatorExt on {{classname}} { String? get discriminatorValue { - {{#mappedModels}} + {{#vendorExtensions.x-discriminator-mapped-models-nonself}} if (this is {{modelName}}) { return r'{{mappingName}}'; } - {{/mappedModels}} + {{/vendorExtensions.x-discriminator-mapped-models-nonself}} + {{#vendorExtensions.x-has-discriminator-self-mapping}} + return r'{{vendorExtensions.x-discriminator-self-mapping-name}}'; + {{/vendorExtensions.x-has-discriminator-self-mapping}} + {{^vendorExtensions.x-has-discriminator-self-mapping}} return null; + {{/vendorExtensions.x-has-discriminator-self-mapping}} } } extension {{classname}}BuilderDiscriminatorExt on {{classname}}Builder { String? get discriminatorValue { - {{#mappedModels}} + {{#vendorExtensions.x-discriminator-mapped-models-nonself}} if (this is {{modelName}}Builder) { return r'{{mappingName}}'; } - {{/mappedModels}} + {{/vendorExtensions.x-discriminator-mapped-models-nonself}} + {{#vendorExtensions.x-has-discriminator-self-mapping}} + return r'{{vendorExtensions.x-discriminator-self-mapping-name}}'; + {{/vendorExtensions.x-has-discriminator-self-mapping}} + {{^vendorExtensions.x-has-discriminator-self-mapping}} return null; + {{/vendorExtensions.x-has-discriminator-self-mapping}} } -} \ No newline at end of file +} + diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_serializer.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_serializer.mustache index 4cd02f3506de..937f9c086972 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_serializer.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/class_serializer.mustache @@ -75,11 +75,11 @@ class _${{classname}}Serializer implements PrimitiveSerializer<{{classname}}> { {{#hasDiscriminatorWithNonEmptyMapping}} {{#discriminator}} {{! handle discriminator }} - {{#mappedModels}} + {{#vendorExtensions.x-discriminator-mapped-models-nonself}} if (object is {{modelName}}) { return serializers.serialize(object, specifiedType: FullType({{modelName}}))!; } - {{/mappedModels}} + {{/vendorExtensions.x-discriminator-mapped-models-nonself}} {{/discriminator}} {{/hasDiscriminatorWithNonEmptyMapping}} return _serializeProperties(serializers, object, specifiedType: specifiedType).toList(); @@ -271,10 +271,10 @@ class _${{classname}}Serializer implements PrimitiveSerializer<{{classname}}> { final discIndex = serializedList.indexOf({{classname}}.discriminatorFieldName) + 1; final discValue = serializers.deserialize(serializedList[discIndex], specifiedType: FullType(String)) as String; switch (discValue) { - {{#mappedModels}} + {{#vendorExtensions.x-discriminator-mapped-models-nonself}} case r'{{mappingName}}': return serializers.deserialize(serialized, specifiedType: FullType({{modelName}})) as {{modelName}}; - {{/mappedModels}} + {{/vendorExtensions.x-discriminator-mapped-models-nonself}} default: return serializers.deserialize(serialized, specifiedType: FullType(${{classname}})) as ${{classname}}; } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioModelTest.java index b23213fd74ac..1a363350346d 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioModelTest.java @@ -387,6 +387,104 @@ public void mapModelTest() { Assert.assertEquals(cm.vars.size(), 0); } + @Test(description = "uses schema-local discriminator mapping for dart-dio") + public void localDiscriminatorUsesDeclaredMappingsOnly() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/bugs/issue_15467.json"); + + final DefaultCodegen codegen = new DartDioClientCodegen(); + codegen.additionalProperties().put(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_BUILT_VALUE); + codegen.processOpts(); + codegen.setOpenAPI(openAPI); + + final String modelName = "Animal"; + final Schema model = openAPI.getComponents().getSchemas().get(modelName); + final CodegenModel cm = codegen.fromModel(modelName, model); + + Assert.assertNotNull(cm.discriminator); + Assert.assertEquals(cm.discriminator.getMapping().size(), 4); + Assert.assertTrue(cm.discriminator.getMapping().containsKey("Bird")); + Assert.assertTrue(cm.discriminator.getMapping().containsKey("Reptile")); + Assert.assertTrue(cm.discriminator.getMapping().containsKey("Crocodile")); + Assert.assertTrue(cm.discriminator.getMapping().containsKey("Turtle")); + Assert.assertFalse(cm.discriminator.getMapping().containsKey("Lizard")); + } + + @Test(description = "does not leak sibling mappings into inherited discriminator for intermediate allOf models") + public void inheritedDiscriminatorKeepsOnlyDescendantsForIntermediateModel() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/bugs/issue_15467.json"); + + final DefaultCodegen codegen = new DartDioClientCodegen(); + codegen.additionalProperties().put(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_BUILT_VALUE); + codegen.processOpts(); + codegen.setOpenAPI(openAPI); + + final Schema reptileSchema = openAPI.getComponents().getSchemas().get("Reptile"); + final CodegenModel reptileModel = codegen.fromModel("Reptile", reptileSchema); + + Assert.assertNotNull(reptileModel.discriminator); + Assert.assertNotNull(reptileModel.discriminator.getMapping()); + Assert.assertTrue(reptileModel.discriminator.getMapping().containsKey("Crocodile")); + Assert.assertTrue(reptileModel.discriminator.getMapping().containsKey("Turtle")); + Assert.assertTrue(reptileModel.discriminator.getMapping().containsKey("Reptile")); + Assert.assertFalse(reptileModel.discriminator.getMapping().containsKey("Bird")); + + java.util.List reptileMappedModelOrder = reptileModel.discriminator.getMappedModels().stream() + .map(CodegenDiscriminator.MappedModel::getModelName) + .collect(java.util.stream.Collectors.toList()); + Assert.assertEquals(reptileMappedModelOrder.get(reptileMappedModelOrder.size() - 1), "Reptile"); + + Assert.assertEquals(reptileModel.discriminator.getVendorExtensions().get("x-has-discriminator-self-mapping"), Boolean.TRUE); + Assert.assertEquals(reptileModel.discriminator.getVendorExtensions().get("x-discriminator-self-mapping-name"), "Reptile"); + @SuppressWarnings("unchecked") + java.util.List reptileNonSelfMappedModels = + (java.util.List) reptileModel.discriminator.getVendorExtensions().get("x-discriminator-mapped-models-nonself"); + Assert.assertNotNull(reptileNonSelfMappedModels); + Assert.assertEquals( + reptileNonSelfMappedModels.stream() + .map(CodegenDiscriminator.MappedModel::getModelName) + .collect(java.util.stream.Collectors.toList()), + java.util.Arrays.asList("Crocodile", "Turtle")); + + final Schema animalSchema = openAPI.getComponents().getSchemas().get("Animal"); + final CodegenModel animalModel = codegen.fromModel("Animal", animalSchema); + Assert.assertNotNull(animalModel.discriminator); + Assert.assertNotNull(animalModel.discriminator.getMapping()); + Assert.assertTrue(animalModel.discriminator.getMapping().containsKey("Bird")); + Assert.assertTrue(animalModel.discriminator.getMapping().containsKey("Reptile")); + Assert.assertEquals(animalModel.discriminator.getVendorExtensions().get("x-has-discriminator-self-mapping"), Boolean.FALSE); + } + + @Test(description = "orders discriminator mappings so subclasses are checked before ancestor types") + public void discriminatorChecksSubclassesBeforeParentTypes() { + OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/bugs/issue_15467.json"); + + final DefaultCodegen codegen = new DartDioClientCodegen(); + codegen.additionalProperties().put(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_BUILT_VALUE); + codegen.processOpts(); + codegen.setOpenAPI(openAPI); + + final Schema animalSchema = openAPI.getComponents().getSchemas().get("Animal"); + final CodegenModel animalModel = codegen.fromModel("Animal", animalSchema); + + Assert.assertNotNull(animalModel.discriminator); + java.util.List mappedModelOrder = animalModel.discriminator.getMappedModels().stream() + .map(CodegenDiscriminator.MappedModel::getModelName) + .collect(java.util.stream.Collectors.toList()); + + Assert.assertTrue(mappedModelOrder.indexOf("Turtle") < mappedModelOrder.indexOf("Reptile")); + Assert.assertTrue(mappedModelOrder.indexOf("Crocodile") < mappedModelOrder.indexOf("Reptile")); + + @SuppressWarnings("unchecked") + java.util.List animalNonSelfMappedModels = + (java.util.List) animalModel.discriminator.getVendorExtensions().get("x-discriminator-mapped-models-nonself"); + Assert.assertNotNull(animalNonSelfMappedModels); + java.util.List animalNonSelfMappedModelOrder = animalNonSelfMappedModels.stream() + .map(CodegenDiscriminator.MappedModel::getModelName) + .collect(java.util.stream.Collectors.toList()); + Assert.assertTrue(animalNonSelfMappedModelOrder.indexOf("Turtle") < animalNonSelfMappedModelOrder.indexOf("Reptile")); + Assert.assertTrue(animalNonSelfMappedModelOrder.indexOf("Crocodile") < animalNonSelfMappedModelOrder.indexOf("Reptile")); + } + @DataProvider(name = "modelNames") public static Object[][] modelNames() { return new Object[][]{ diff --git a/modules/openapi-generator/src/test/resources/bugs/issue_15467.json b/modules/openapi-generator/src/test/resources/bugs/issue_15467.json new file mode 100644 index 000000000000..d166013024dc --- /dev/null +++ b/modules/openapi-generator/src/test/resources/bugs/issue_15467.json @@ -0,0 +1,80 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Test API", + "version": "v1" + }, + "paths": {}, + "components": { + "schemas": { + "Animal": { + "type": "object", + "discriminator": { + "propertyName": "type", + "mapping": { + "Bird": "#/components/schemas/Bird", + "Reptile": "#/components/schemas/Reptile", + "Crocodile": "#/components/schemas/Crocodile", + "Turtle": "#/components/schemas/Turtle" + } + }, + "additionalProperties": false, + "properties": { + "id": {"type": "string", "nullable": true}, + "name": {"type": "string", "nullable": true}, + "age": {"type": "integer", "format": "int32"}, + "type": {"type": "string", "nullable": true} + } + }, + "Bird": { + "allOf": [ + {"$ref": "#/components/schemas/Animal"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "wingSpan": {"type": "number", "format": "double"} + } + } + ] + }, + "Reptile": { + "allOf": [ + {"$ref": "#/components/schemas/Animal"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "scaleColor": {"type": "string", "nullable": true} + } + } + ] + }, + "Crocodile": { + "allOf": [ + {"$ref": "#/components/schemas/Reptile"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "numberOfTeeth": {"type": "integer", "format": "int32"} + } + } + ] + }, + "Turtle": { + "allOf": [ + {"$ref": "#/components/schemas/Reptile"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "shellDiameter": {"type": "number", "format": "double"} + } + } + ] + } + } + } +} + diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/bar_ref_or_value.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/bar_ref_or_value.dart index 31a5f74c8fd1..191068d5f56f 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/bar_ref_or_value.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/bar_ref_or_value.dart @@ -71,6 +71,8 @@ extension BarRefOrValueBuilderDiscriminatorExt on BarRefOrValueBuilder { } } + + class _$BarRefOrValueSerializer implements PrimitiveSerializer { @override final Iterable types = const [BarRefOrValue, _$BarRefOrValue]; diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity.dart index 7e27fab47387..d4effc6d3d93 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity.dart @@ -29,12 +29,12 @@ abstract class Entity implements Addressable, Extensible { static const String discriminatorFieldName = r'@type'; static const Map discriminatorMapping = { + r'PizzaSpeziale': PizzaSpeziale, r'Bar': Bar, r'Bar_Create': BarCreate, r'Foo': Foo, r'Pasta': Pasta, r'Pizza': Pizza, - r'PizzaSpeziale': PizzaSpeziale, }; @BuiltValueSerializer(custom: true) @@ -43,6 +43,9 @@ abstract class Entity implements Addressable, Extensible { extension EntityDiscriminatorExt on Entity { String? get discriminatorValue { + if (this is PizzaSpeziale) { + return r'PizzaSpeziale'; + } if (this is Bar) { return r'Bar'; } @@ -58,14 +61,14 @@ extension EntityDiscriminatorExt on Entity { 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 PizzaSpezialeBuilder) { + return r'PizzaSpeziale'; + } if (this is BarBuilder) { return r'Bar'; } @@ -81,13 +84,12 @@ extension EntityBuilderDiscriminatorExt on EntityBuilder { if (this is PizzaBuilder) { return r'Pizza'; } - if (this is PizzaSpezialeBuilder) { - return r'PizzaSpeziale'; - } return null; } } + + class _$EntitySerializer implements PrimitiveSerializer { @override final Iterable types = const [Entity]; @@ -141,6 +143,9 @@ class _$EntitySerializer implements PrimitiveSerializer { Entity object, { FullType specifiedType = FullType.unspecified, }) { + if (object is PizzaSpeziale) { + return serializers.serialize(object, specifiedType: FullType(PizzaSpeziale))!; + } if (object is Bar) { return serializers.serialize(object, specifiedType: FullType(Bar))!; } @@ -156,9 +161,6 @@ class _$EntitySerializer implements PrimitiveSerializer { if (object is Pizza) { return serializers.serialize(object, specifiedType: FullType(Pizza))!; } - if (object is PizzaSpeziale) { - return serializers.serialize(object, specifiedType: FullType(PizzaSpeziale))!; - } return _serializeProperties(serializers, object, specifiedType: specifiedType).toList(); } @@ -172,6 +174,8 @@ class _$EntitySerializer implements PrimitiveSerializer { final discIndex = serializedList.indexOf(Entity.discriminatorFieldName) + 1; final discValue = serializers.deserialize(serializedList[discIndex], specifiedType: FullType(String)) as String; switch (discValue) { + case r'PizzaSpeziale': + return serializers.deserialize(serialized, specifiedType: FullType(PizzaSpeziale)) as PizzaSpeziale; case r'Bar': return serializers.deserialize(serialized, specifiedType: FullType(Bar)) as Bar; case r'Bar_Create': @@ -182,8 +186,6 @@ class _$EntitySerializer implements PrimitiveSerializer { return serializers.deserialize(serialized, specifiedType: FullType(Pasta)) as Pasta; case r'Pizza': return serializers.deserialize(serialized, specifiedType: FullType(Pizza)) as Pizza; - case r'PizzaSpeziale': - return serializers.deserialize(serialized, specifiedType: FullType(PizzaSpeziale)) as PizzaSpeziale; default: return serializers.deserialize(serialized, specifiedType: FullType($Entity)) as $Entity; } diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity_ref.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity_ref.dart index 91fdfd017d78..e4263aca62a4 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity_ref.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/entity_ref.dart @@ -66,6 +66,8 @@ extension EntityRefBuilderDiscriminatorExt on EntityRefBuilder { } } + + class _$EntityRefSerializer implements PrimitiveSerializer { @override final Iterable types = const [EntityRef]; diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/foo_ref_or_value.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/foo_ref_or_value.dart index 073fb4ff9c5e..bcbfcba36cc2 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/foo_ref_or_value.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/foo_ref_or_value.dart @@ -70,6 +70,8 @@ extension FooRefOrValueBuilderDiscriminatorExt on FooRefOrValueBuilder { } } + + class _$FooRefOrValueSerializer implements PrimitiveSerializer { @override final Iterable types = const [FooRefOrValue, _$FooRefOrValue]; diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/fruit.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/fruit.dart index 31b61361de5e..ca3cb895e972 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/fruit.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/fruit.dart @@ -68,6 +68,8 @@ extension FruitBuilderDiscriminatorExt on FruitBuilder { } } + + class _$FruitSerializer implements PrimitiveSerializer { @override final Iterable types = const [Fruit, _$Fruit]; diff --git a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/pizza.dart b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/pizza.dart index 6e255af0866f..c83a729a7156 100644 --- a/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/pizza.dart +++ b/samples/openapi3/client/petstore/dart-dio/oneof_polymorphism_and_inheritance/lib/src/model/pizza.dart @@ -51,6 +51,8 @@ extension PizzaBuilderDiscriminatorExt on PizzaBuilder { } } + + class _$PizzaSerializer implements PrimitiveSerializer { @override final Iterable types = const [Pizza]; diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/animal.dart b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/animal.dart index 20b3f9f50b71..4aa68d04f60c 100644 --- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/animal.dart +++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/animal.dart @@ -57,6 +57,8 @@ extension AnimalBuilderDiscriminatorExt on AnimalBuilder { } } + + class _$AnimalSerializer implements PrimitiveSerializer { @override final Iterable types = const [Animal]; diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/parent_with_nullable.dart b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/parent_with_nullable.dart index 99300ffdfb5c..2ffb0e1362d9 100644 --- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/parent_with_nullable.dart +++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake/lib/src/model/parent_with_nullable.dart @@ -49,6 +49,8 @@ extension ParentWithNullableBuilderDiscriminatorExt on ParentWithNullableBuilder } } + + class _$ParentWithNullableSerializer implements PrimitiveSerializer { @override final Iterable types = const [ParentWithNullable];