fun generate()

in graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/generators/java/InterfaceGenerator.kt [48:116]


    fun generate(
        definition: InterfaceTypeDefinition,
        extensions: List<InterfaceTypeExtensionDefinition>,
    ): CodeGenResult {
        if (definition.shouldSkip(config)) {
            return CodeGenResult.EMPTY
        }

        logger.info("Generating type {}", definition.name)
        val javaType =
            TypeSpec
                .interfaceBuilder(definition.name)
                .addOptionalGeneratedAnnotation(config)
                .addModifiers(Modifier.PUBLIC)

        if (definition.description != null) {
            javaType.addJavadoc("\$L", definition.description.content)
        }

        definition.implements
            .filterIsInstance<TypeName>()
            .forEach {
                javaType.addSuperinterface(typeUtils.findJavaInterfaceName(it.name, packageName))
            }

        val mergedFieldDefinitions = definition.fieldDefinitions + extensions.flatMap { it.fieldDefinitions }

        mergedFieldDefinitions.filterSkipped().forEach {
            // Only generate getters/setters for fields that are not interfaces.
            //
            // interface Pet {
            // 	 parent: Pet
            // }
            // type Dog implements Pet {
            // 	 parent: Dog
            // }
            // type Bird implements Pet {
            // 	 parent: Bird
            // }
            // For the schema above, we currently generate Dog::setParent(Dog dog), but the interface
            // would have Pet::setParent(Pet pet) leading to missing overrides in the generated
            // implementation classes. This is not an issue if the overridden field has the same base type,
            // however.
            // Ref: https://github.com/graphql/graphql-js/issues/776
            if (!isFieldAnInterface(it) || config.generateInterfaceMethodsForInterfaceFields) {
                addInterfaceMethod(it, javaType)
            }
        }

        val implementations =
            document
                .getDefinitionsOfType(ObjectTypeDefinition::class.java)
                .asSequence()
                .filter { node -> node.implements.any { it.isEqualTo(TypeName(definition.name)) } }
                .map { node ->
                    typeUtils.findJavaInterfaceName(node.name, packageName)
                }.filterIsInstance<ClassName>()
                .toList()

        // Add JsonSubType annotations only if there are no generated concrete types that implement the interface
        if (implementations.isNotEmpty() && config.generateDataTypes) {
            javaType.addAnnotation(jsonTypeInfoAnnotation())
            javaType.addAnnotation(jsonSubTypeAnnotation(implementations))
        }

        val javaFile = JavaFile.builder(packageName, javaType.build()).build()

        return CodeGenResult(javaInterfaces = listOf(javaFile))
    }