@@ -647,10 +647,10 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
647647 return op ;
648648 }
649649
650- private void postProcessPolymorphism (List <ModelMap > allModels ) {
651- final HashMap <String , List <String >> mapDiscriminator = new HashMap <>();
650+ private void postProcessPolymorphism (final List <ModelMap > allModels ) {
651+ final HashMap <String , List <String >> discriminatorsForModel = new HashMap <>();
652652
653- for (ModelMap mo : allModels ) {
653+ for (final ModelMap mo : allModels ) {
654654 final CodegenModel cm = mo .getModel ();
655655
656656 final CodegenComposedSchemas cs = cm .getComposedSchemas ();
@@ -671,43 +671,29 @@ private void postProcessPolymorphism(List<ModelMap> allModels) {
671671 }
672672
673673 if (cm .discriminator != null ) {
674- for (String model : cm .oneOf ) {
675- final List <String > discriminators = mapDiscriminator .getOrDefault (model , new ArrayList <>());
674+ for (final String model : cm .oneOf ) {
675+ final List <String > discriminators = discriminatorsForModel .getOrDefault (model , new ArrayList <>());
676676 discriminators .add (cm .discriminator .getPropertyName ());
677- mapDiscriminator .put (model , discriminators );
677+ discriminatorsForModel .put (model , discriminators );
678678 }
679679
680- for (String model : cm .anyOf ) {
681- final List <String > discriminators = mapDiscriminator .getOrDefault (model , new ArrayList <>());
680+ for (final String model : cm .anyOf ) {
681+ final List <String > discriminators = discriminatorsForModel .getOrDefault (model , new ArrayList <>());
682682 discriminators .add (cm .discriminator .getPropertyName ());
683- mapDiscriminator .put (model , discriminators );
683+ discriminatorsForModel .put (model , discriminators );
684684 }
685685 }
686686 }
687687
688+ final var blocking = new HashSet <String >();
688689 for (ModelMap mo : allModels ) {
689690 final CodegenModel cm = mo .getModel ();
690691
691- final List <String > discriminatorsForModel = mapDiscriminator .get (cm .getSchemaName ());
692- if (discriminatorsForModel != null ) {
693- for (CodegenProperty var : cm .vars ) {
694- var .isDiscriminator = false ;
695- }
696-
697- boolean hasDiscriminatorDefined = false ;
698- for (String discriminator : discriminatorsForModel ) {
699- for (CodegenProperty var : cm .vars ) {
700- if (var .baseName .equals (discriminator ) || var .name .equals (discriminator )) {
701- var .isDiscriminator = true ;
702- hasDiscriminatorDefined = true ;
703- break ;
704- }
705- }
706- }
707-
692+ final List <String > discriminators = discriminatorsForModel .get (cm .getSchemaName ());
693+ if (discriminators != null ) {
708694 // If the discriminator field is not a defined attribute in the variant structure, create it.
709- if (!hasDiscriminatorDefined && ! discriminatorsForModel . isEmpty ( )) {
710- final String discriminator = discriminatorsForModel .get (0 );
695+ if (!discriminating ( discriminators , cm )) {
696+ final String discriminator = discriminators .get (0 );
711697
712698 CodegenProperty property = new CodegenProperty ();
713699
@@ -740,6 +726,50 @@ private void postProcessPolymorphism(List<ModelMap> allModels) {
740726 cm .vars .add (property );
741727 }
742728 }
729+
730+ if (cm .vars .stream ().noneMatch (v -> v .isDiscriminator )) {
731+ blocking .add (cm .getSchemaName ());
732+ }
733+ }
734+
735+ for (final ModelMap mo : allModels ) {
736+ final CodegenModel cm = mo .getModel ();
737+ if (cm .discriminator != null ) {
738+ // if no discriminator in any of variant -> disable discriminator
739+ if (cm .oneOf .stream ().anyMatch (blocking ::contains ) || cm .anyOf .stream ().anyMatch (blocking ::contains )) {
740+ cm .discriminator = null ;
741+ }
742+ }
743+ }
744+ }
745+
746+ private static boolean discriminating (final List <String > discriminatorsForModel , final CodegenModel cm ) {
747+ resetDiscriminatorProperty (cm );
748+
749+ // Discriminator will be presented as enum tag -> One and only one tag is allowed
750+ int countString = 0 ;
751+ int countNonString = 0 ;
752+ for (final CodegenProperty var : cm .vars ) {
753+ if (discriminatorsForModel .stream ().anyMatch (discriminator -> var .baseName .equals (discriminator ) || var .name .equals (discriminator ))) {
754+ if (var .isString ) {
755+ var .isDiscriminator = true ;
756+ ++countString ;
757+ } else
758+ ++countNonString ;
759+ }
760+ }
761+
762+ if (countString > 0 && (countNonString > 0 || countString > 1 )) {
763+ // at least two discriminator, one of them is string -> should not render serde tag
764+ resetDiscriminatorProperty (cm );
765+ }
766+
767+ return countNonString > 0 || countString > 0 ;
768+ }
769+
770+ private static void resetDiscriminatorProperty (final CodegenModel cm ) {
771+ for (final CodegenProperty var : cm .vars ) {
772+ var .isDiscriminator = false ;
743773 }
744774 }
745775
0 commit comments