Skip to content

Commit d6bd6b4

Browse files
kbrooksKyle
andauthored
[Kotlin] Ability to generate sealed interfaces (#869)
Co-authored-by: Kyle <[email protected]>
1 parent 7f5b3c8 commit d6bd6b4

File tree

21 files changed

+159
-3
lines changed

21 files changed

+159
-3
lines changed

docs/codegen-options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ See [DirectiveAnnotationsMapping](#option-directiveannotationsmapping)* |
5757
| `generatedLanguage` | Enum | GeneratedLanguage.JAVA | Choose which language you want to generate, Java,Scala,Kotlin were supported. Note that due to language features, there are slight differences in default values between languages.|
5858
| `generateModelOpenClasses` | Boolean | false | The class type of the generated model. If true, generate normal classes, else generate data classes. It only support in kotlin(```data class```) and scala(```case class```). Maybe we will consider to support Java ```record``` in the future.|
5959
| `initializeNullableTypes` | Boolean | false | Adds a default null value to nullable arguments. Only supported in Kotlin.
60+
| `generateSealedInterfaces` | Boolean | false | This applies to generated interfaces on unions and interfaces. If true, generate sealed interfaces, else generate normal ones. It is only supported in Kotlin. |
6061
| `typesAsInterfaces` | Set(String) | Empty | Types that must generated as interfaces should be defined here in format: `TypeName` or `@directive`. E.g.: `User`, `@asInterface`. |
6162

6263
### Option `graphqlSchemas`

plugins/gradle/example-client-kotlin/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ task graphqlCodegenKotlinService(type: GraphQLCodegenGradleTask) {
5757
apiPackageName = "io.github.dreamylost.api"
5858
modelPackageName = "io.github.dreamylost.model"
5959
generateModelOpenClasses = true
60+
generateSealedInterfaces = true
6061
customAnnotationsMapping = [
6162
"Character": ["@com.fasterxml.jackson.annotation.JsonTypeInfo(use=com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include=com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY,property = \"__typename\")",
6263
"@com.fasterxml.jackson.annotation.JsonSubTypes(value = arrayOf(" + System.lineSeparator() +

plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
104104
private GeneratedLanguage generatedLanguage = MappingConfigConstants.DEFAULT_GENERATED_LANGUAGE;
105105
private Boolean generateModelOpenClasses = MappingConfigConstants.DEFAULT_GENERATE_MODEL_OPEN_CLASSES;
106106
private Boolean initializeNullableTypes = MappingConfigConstants.DEFAULT_INITIALIZE_NULLABLE_TYPES;
107+
private Boolean generateSealedInterfaces = MappingConfigConstants.DEFAULT_GENERATE_SEALED_INTERFACES;
107108

108109
public GraphQLCodegenGradleTask() {
109110
setGroup("codegen");
@@ -857,4 +858,15 @@ public Boolean isInitializeNullableTypes() {
857858
public void setInitializeNullableTypes(Boolean initializeNullableTypes) {
858859
this.initializeNullableTypes = initializeNullableTypes;
859860
}
861+
862+
@Input
863+
@Optional
864+
@Override
865+
public Boolean isGenerateSealedInterfaces() {
866+
return generateSealedInterfaces;
867+
}
868+
869+
public void setGenerateSealedInterfaces(Boolean generateSealedInterfaces) {
870+
this.generateSealedInterfaces = generateSealedInterfaces;
871+
}
860872
}

plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
212212
@Parameter(defaultValue = MappingConfigConstants.DEFAULT_INITIALIZE_NULLABLE_TYPES_STRING)
213213
private boolean initializeNullableTypes;
214214

215+
@Parameter(defaultValue = MappingConfigConstants.DEFAULT_GENERATE_SEALED_INTERFACES_STRING)
216+
private boolean generateSealedInterfaces;
217+
215218
@Override
216219
public void execute() throws MojoExecutionException {
217220
addCompileSourceRootIfConfigured();
@@ -271,6 +274,7 @@ public void execute() throws MojoExecutionException {
271274
mappingConfig.setGeneratedLanguage(generatedLanguage);
272275
mappingConfig.setGenerateModelOpenClasses(isGenerateModelOpenClasses());
273276
mappingConfig.setInitializeNullableTypes(isInitializeNullableTypes());
277+
mappingConfig.setGenerateSealedInterfaces(isGenerateSealedInterfaces());
274278

275279
try {
276280
instantiateCodegen(mappingConfig).generate();
@@ -612,6 +616,11 @@ public Boolean isInitializeNullableTypes() {
612616
return initializeNullableTypes;
613617
}
614618

619+
@Override
620+
public Boolean isGenerateSealedInterfaces() {
621+
return generateSealedInterfaces;
622+
}
623+
615624
public ParentInterfacesConfig getParentInterfaces() {
616625
return parentInterfaces;
617626
}

plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ trait GraphQLCodegenKeys {
124124

125125
val generateModelOpenClasses = settingKey[Boolean]("The class type of the generated model. If true, generate normal classes, else generate case class.")
126126

127+
val generateSealedInterfaces = settingKey[Boolean]("If true, generate sealed interfaces for GraphQL unions and interfaces, else generate normal interfaces.")
128+
127129
val generateJacksonTypeIdResolver = settingKey[Boolean]("Specifies whether generated union interfaces should be annotated with a custom Jackson type id resolver generated in model package")
128130

129131
//for version

plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
7171
graphqlJavaCodegenVersion := None,
7272
// suffix/prefix/strategies:
7373
generateModelOpenClasses := MappingConfigConstants.DEFAULT_GENERATE_MODEL_OPEN_CLASSES,
74+
generateSealedInterfaces := MappingConfigConstants.DEFAULT_GENERATE_SEALED_INTERFACES,
7475
generatedLanguage := MappingConfigConstants.DEFAULT_GENERATED_LANGUAGE,
7576
apiNamePrefix := None,
7677
apiNameSuffix := MappingConfigConstants.DEFAULT_RESOLVER_SUFFIX,

src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLCodegen.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ protected void initDefaultValues(MappingConfig mappingConfig) {
5252
if (mappingConfig.isInitializeNullableTypes() == null) {
5353
mappingConfig.setInitializeNullableTypes(false);
5454
}
55+
if (mappingConfig.isGenerateSealedInterfaces() == null) {
56+
mappingConfig.setGenerateSealedInterfaces(false);
57+
}
5558
if (mappingConfig.getGenerateBuilder() == null) {
5659
// functional expression
5760
mappingConfig.setGenerateBuilder(false);

src/main/java/com/kobylynskyi/graphql/codegen/mapper/InterfaceDefinitionToDataModelMapper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.FIELDS;
1616
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_ANNOTATION;
1717
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_INFO;
18+
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATE_SEALED_INTERFACES;
1819
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMMUTABLE_MODELS;
1920
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMPLEMENTS;
2021
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.JAVA_DOC;
@@ -63,6 +64,7 @@ public Map<String, Object> map(MappingContext mappingContext, ExtendedInterfaceT
6364
dataModel.put(ENUM_IMPORT_IT_SELF_IN_SCALA, mappingContext.getEnumImportItSelfInScala());
6465
dataModel.put(IMMUTABLE_MODELS, mappingContext.getGenerateImmutableModels());
6566
dataModel.put(PARENT_INTERFACE_PROPERTIES, mappingContext.getParentInterfaceProperties());
67+
dataModel.put(GENERATE_SEALED_INTERFACES, mappingContext.isGenerateSealedInterfaces());
6668
return dataModel;
6769
}
6870

src/main/java/com/kobylynskyi/graphql/codegen/mapper/RequestResponseDefinitionToDataModelMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_ANNOTATION;
3030
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_INFO;
3131
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATE_ALL_METHOD_IN_PROJECTION;
32+
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATE_SEALED_INTERFACES;
3233
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.JAVA_DOC;
3334
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.METHOD_NAME;
3435
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.OPERATION_NAME;

src/main/java/com/kobylynskyi/graphql/codegen/mapper/TypeDefinitionToDataModelMapper.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.stream.Collectors;
1919

2020
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.ANNOTATIONS;
21-
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.INITIALIZE_NULLABLE_TYPES;
2221
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.BUILDER;
2322
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.CLASS_NAME;
2423
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.ENUM_IMPORT_IT_SELF_IN_SCALA;
@@ -27,8 +26,10 @@
2726
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_ANNOTATION;
2827
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_INFO;
2928
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATE_MODEL_OPEN_CLASSES;
29+
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATE_SEALED_INTERFACES;
3030
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMMUTABLE_MODELS;
3131
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMPLEMENTS;
32+
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.INITIALIZE_NULLABLE_TYPES;
3233
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.JAVA_DOC;
3334
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.PACKAGE;
3435
import static com.kobylynskyi.graphql.codegen.model.DataModelFields.PARENT_INTERFACE_PROPERTIES;
@@ -104,6 +105,7 @@ public Map<String, Object> map(MappingContext mappingContext,
104105
dataModel.put(PARENT_INTERFACE_PROPERTIES, mappingContext.getParentInterfaceProperties());
105106
dataModel.put(GENERATE_MODEL_OPEN_CLASSES, mappingContext.isGenerateModelOpenClasses());
106107
dataModel.put(INITIALIZE_NULLABLE_TYPES, mappingContext.isInitializeNullableTypes());
108+
dataModel.put(GENERATE_SEALED_INTERFACES, mappingContext.isGenerateSealedInterfaces());
107109
return dataModel;
108110
}
109111

0 commit comments

Comments
 (0)