Skip to content

Commit 16fa109

Browse files
authored
Add ApolloCompilerPlugin.schemaDocumentListener() (#6165)
* Add ApolloCompilerPlugin.schemaDocumentListener() * fix integration tests
1 parent df6ab99 commit 16fa109

File tree

23 files changed

+382
-56
lines changed

23 files changed

+382
-56
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.apollographql.apollo.ast
2+
3+
import com.apollographql.apollo.annotations.ApolloExperimental
4+
5+
/**
6+
* A known foreign schema
7+
*
8+
* @param name the name of the foreign schema as in https://specs.apollo.dev/link/v1.0/#@link.url
9+
* @param version the version of the foreign schema as in https://specs.apollo.dev/link/v1.0/#@link.url
10+
* @param definitions the definitions in the foreign schema
11+
* @param directivesToStrip the name of directives that must be stripped before being sent to the server
12+
* without the leading '@'.
13+
* For an example: `"catch"`
14+
*/
15+
@ApolloExperimental
16+
class ForeignSchema(
17+
val name: String,
18+
val version: String,
19+
val definitions: List<GQLDefinition>,
20+
val directivesToStrip: List<String> = definitions.filterIsInstance<GQLDirective>().map { it.name },
21+
)

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo/ast/api.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ fun GQLDocument.validateAsSchemaAndAddApolloDefinition(): GQLResult<Schema> {
212212
definitions,
213213
SchemaValidationOptions(
214214
true,
215-
supportedForeignSchemas()
215+
builtinForeignSchemas()
216216
)
217217
)
218218
}

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo/ast/gqldocument.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.apollographql.apollo.annotations.ApolloDeprecatedSince
44
import com.apollographql.apollo.annotations.ApolloExperimental
55
import com.apollographql.apollo.annotations.ApolloInternal
66
import com.apollographql.apollo.ast.internal.ExtensionsMerger
7-
import com.apollographql.apollo.ast.internal.ForeignSchema
87
import com.apollographql.apollo.ast.internal.builtinsDefinitionsStr
98
import com.apollographql.apollo.ast.internal.ensureSchemaDefinition
109
import com.apollographql.apollo.ast.internal.kotlinLabsDefinitions_0_3
@@ -103,7 +102,7 @@ fun kotlinLabsDefinitions(version: String): List<GQLDefinition> {
103102
* This is exported in case users want to validate documents meant for Apollo Kotlin.
104103
*/
105104
@ApolloExperimental
106-
fun supportedForeignSchemas(): List<ForeignSchema> {
105+
fun builtinForeignSchemas(): List<ForeignSchema> {
107106
return listOf(
108107
ForeignSchema("kotlin_labs", "v0.2", kotlinLabsDefinitions("v0.2"), listOf("optional", "nonnull")),
109108
ForeignSchema("kotlin_labs", "v0.3", kotlinLabsDefinitions("v0.3"), listOf("optional", "nonnull")),

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo/ast/internal/SchemaValidationScope.kt

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.apollographql.apollo.annotations.ApolloExperimental
44
import com.apollographql.apollo.annotations.ApolloInternal
55
import com.apollographql.apollo.ast.ConflictResolution
66
import com.apollographql.apollo.ast.DirectiveRedefinition
7+
import com.apollographql.apollo.ast.ForeignSchema
78
import com.apollographql.apollo.ast.GQLDefinition
89
import com.apollographql.apollo.ast.GQLDirective
910
import com.apollographql.apollo.ast.GQLDirectiveDefinition
@@ -285,24 +286,6 @@ private class Import(
285286
val newNames: Map<String, String>,
286287
)
287288

288-
/**
289-
* A known foreign schema
290-
*
291-
* @param name the name of the foreign schema as in https://specs.apollo.dev/link/v1.0/#@link.url
292-
* @param version the version of the foreign schema as in https://specs.apollo.dev/link/v1.0/#@link.url
293-
* @param definitions the definitions in the foreign schema
294-
* @param directivesToStrip the name of directives that must be stripped before being sent to the server
295-
* without the leading '@'.
296-
* For an example: `"catch"`
297-
*/
298-
@ApolloExperimental
299-
class ForeignSchema(
300-
val name: String,
301-
val version: String,
302-
val definitions: List<GQLDefinition>,
303-
val directivesToStrip: List<String> = definitions.filterIsInstance<GQLDirective>().map { it.name },
304-
)
305-
306289
private class UrlParseResult(val name: String, val version: String)
307290

308291
private fun String.parseLink(): UrlParseResult? {

libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo/graphql/ast/test/SchemaTest.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package com.apollographql.apollo.graphql.ast.test
22

3-
import com.apollographql.apollo.ast.GQLDirectiveDefinition
4-
import com.apollographql.apollo.ast.GQLDirectiveLocation
5-
import com.apollographql.apollo.ast.GQLInputValueDefinition
6-
import com.apollographql.apollo.ast.internal.ForeignSchema
3+
import com.apollographql.apollo.ast.ForeignSchema
74
import com.apollographql.apollo.ast.internal.SchemaValidationOptions
85
import com.apollographql.apollo.ast.parseAsGQLDocument
96
import com.apollographql.apollo.ast.toGQLDocument
107
import com.apollographql.apollo.ast.toSchema
118
import com.apollographql.apollo.ast.validateAsSchema
129
import kotlin.test.Test
1310
import kotlin.test.assertEquals
14-
import kotlin.test.assertTrue
1511

1612
class SchemaTest {
1713
@Test

libraries/apollo-compiler/api/apollo-compiler.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ public final class com/apollographql/apollo/compiler/AdapterInitializer$Companio
99
public final class com/apollographql/apollo/compiler/ApolloCompiler {
1010
public static final field INSTANCE Lcom/apollographql/apollo/compiler/ApolloCompiler;
1111
public final fun buildCodegenSchema (Ljava/util/List;Lcom/apollographql/apollo/compiler/ApolloCompiler$Logger;Lcom/apollographql/apollo/compiler/CodegenSchemaOptions;)Lcom/apollographql/apollo/compiler/CodegenSchema;
12+
public final fun buildCodegenSchema (Ljava/util/List;Lcom/apollographql/apollo/compiler/ApolloCompiler$Logger;Lcom/apollographql/apollo/compiler/CodegenSchemaOptions;Ljava/util/List;)Lcom/apollographql/apollo/compiler/CodegenSchema;
1213
public final fun buildIrOperations (Lcom/apollographql/apollo/compiler/CodegenSchema;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lcom/apollographql/apollo/compiler/IrOptions;Lcom/apollographql/apollo/compiler/DocumentTransform;Lcom/apollographql/apollo/compiler/ApolloCompiler$Logger;)Lcom/apollographql/apollo/compiler/ir/IrOperations;
14+
public final fun buildSchemaAndOperationsSources (Lcom/apollographql/apollo/compiler/CodegenSchema;Ljava/util/List;Lcom/apollographql/apollo/compiler/IrOptions;Lcom/apollographql/apollo/compiler/CodegenOptions;Lcom/apollographql/apollo/compiler/LayoutFactory;Lcom/apollographql/apollo/compiler/OperationOutputGenerator;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/DocumentTransform;Lcom/apollographql/apollo/compiler/ApolloCompiler$Logger;Ljava/io/File;)Lcom/apollographql/apollo/compiler/codegen/SourceOutput;
1315
public final fun buildSchemaAndOperationsSources (Ljava/util/List;Ljava/util/List;Lcom/apollographql/apollo/compiler/CodegenSchemaOptions;Lcom/apollographql/apollo/compiler/IrOptions;Lcom/apollographql/apollo/compiler/CodegenOptions;Lcom/apollographql/apollo/compiler/LayoutFactory;Lcom/apollographql/apollo/compiler/OperationOutputGenerator;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/DocumentTransform;Lcom/apollographql/apollo/compiler/ApolloCompiler$Logger;Ljava/io/File;)Lcom/apollographql/apollo/compiler/codegen/SourceOutput;
1416
public final fun buildSchemaAndOperationsSourcesFromIr (Lcom/apollographql/apollo/compiler/CodegenSchema;Lcom/apollographql/apollo/compiler/ir/IrOperations;Lcom/apollographql/apollo/compiler/UsedCoordinates;Ljava/util/List;Lcom/apollographql/apollo/compiler/CodegenOptions;Lcom/apollographql/apollo/compiler/codegen/SchemaAndOperationsLayout;Lcom/apollographql/apollo/compiler/OperationOutputGenerator;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;Ljava/io/File;)Lcom/apollographql/apollo/compiler/codegen/SourceOutput;
1517
public final fun buildSchemaSources (Lcom/apollographql/apollo/compiler/CodegenSchema;Lcom/apollographql/apollo/compiler/UsedCoordinates;Lcom/apollographql/apollo/compiler/CodegenOptions;Lcom/apollographql/apollo/compiler/codegen/SchemaLayout;Lcom/apollographql/apollo/compiler/Transform;Lcom/apollographql/apollo/compiler/Transform;)Lcom/apollographql/apollo/compiler/codegen/SourceOutput;

libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/ApolloCompiler.kt

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package com.apollographql.apollo.compiler
33
import com.apollographql.apollo.ast.DeprecatedUsage
44
import com.apollographql.apollo.ast.DifferentShape
55
import com.apollographql.apollo.ast.DirectiveRedefinition
6+
import com.apollographql.apollo.ast.ForeignSchema
67
import com.apollographql.apollo.ast.GQLDefinition
7-
import com.apollographql.apollo.ast.GQLDirectiveDefinition
88
import com.apollographql.apollo.ast.GQLDocument
99
import com.apollographql.apollo.ast.GQLFragmentDefinition
1010
import com.apollographql.apollo.ast.GQLOperationDefinition
@@ -13,21 +13,20 @@ import com.apollographql.apollo.ast.GQLSchemaDefinition
1313
import com.apollographql.apollo.ast.GQLTypeDefinition
1414
import com.apollographql.apollo.ast.IncompatibleDefinition
1515
import com.apollographql.apollo.ast.Issue
16-
import com.apollographql.apollo.ast.KOTLIN_LABS_VERSION
1716
import com.apollographql.apollo.ast.ParserOptions
1817
import com.apollographql.apollo.ast.QueryDocumentMinifier
1918
import com.apollographql.apollo.ast.Schema
2019
import com.apollographql.apollo.ast.UnknownDirective
2120
import com.apollographql.apollo.ast.UnusedFragment
2221
import com.apollographql.apollo.ast.UnusedVariable
2322
import com.apollographql.apollo.ast.checkEmpty
24-
import com.apollographql.apollo.ast.kotlinLabsDefinitions
23+
import com.apollographql.apollo.ast.internal.SchemaValidationOptions
2524
import com.apollographql.apollo.ast.parseAsGQLDocument
2625
import com.apollographql.apollo.ast.pretty
26+
import com.apollographql.apollo.ast.builtinForeignSchemas
2727
import com.apollographql.apollo.ast.toGQLDocument
2828
import com.apollographql.apollo.ast.validateAsExecutable
29-
import com.apollographql.apollo.ast.validateAsSchemaAndAddApolloDefinition
30-
import com.apollographql.apollo.compiler.codegen.LayoutImpl
29+
import com.apollographql.apollo.ast.validateAsSchema
3130
import com.apollographql.apollo.compiler.codegen.SchemaAndOperationsLayout
3231
import com.apollographql.apollo.compiler.codegen.SchemaLayout
3332
import com.apollographql.apollo.compiler.codegen.SourceOutput
@@ -49,7 +48,6 @@ import com.apollographql.apollo.compiler.ir.IrOperations
4948
import com.apollographql.apollo.compiler.ir.IrOperationsBuilder
5049
import com.apollographql.apollo.compiler.ir.IrSchema
5150
import com.apollographql.apollo.compiler.ir.IrSchemaBuilder
52-
import com.apollographql.apollo.compiler.ir.IrTargetObject
5351
import com.apollographql.apollo.compiler.operationoutput.OperationDescriptor
5452
import com.apollographql.apollo.compiler.pqm.toPersistedQueryManifest
5553
import java.io.File
@@ -63,6 +61,20 @@ object ApolloCompiler {
6361
schemaFiles: List<InputFile>,
6462
logger: Logger?,
6563
codegenSchemaOptions: CodegenSchemaOptions,
64+
): CodegenSchema {
65+
return buildCodegenSchema(
66+
schemaFiles,
67+
logger,
68+
codegenSchemaOptions,
69+
emptyList()
70+
)
71+
}
72+
73+
fun buildCodegenSchema(
74+
schemaFiles: List<InputFile>,
75+
logger: Logger?,
76+
codegenSchemaOptions: CodegenSchemaOptions,
77+
foreignSchemas: List<ForeignSchema>,
6678
): CodegenSchema {
6779
val schemaDocuments = schemaFiles.map {
6880
it.normalizedPath to it.file.toGQLDocument(allowJson = true)
@@ -106,10 +118,15 @@ object ApolloCompiler {
106118
sourceLocation = null
107119
)
108120

109-
/**
110-
* TODO: use `validateAsSchema` to not automatically add the apollo definitions
111-
*/
112-
val result = schemaDocument.validateAsSchemaAndAddApolloDefinition()
121+
val result = schemaDocument.validateAsSchema(
122+
validationOptions = SchemaValidationOptions(
123+
/**
124+
* TODO: switch to false
125+
*/
126+
addKotlinLabsDefinitions = true,
127+
builtinForeignSchemas() + foreignSchemas
128+
)
129+
)
113130

114131
val issueGroup = result.issues.group(warnOnDeprecatedUsages = true, fieldsOnDisjointTypesMustMerge = true)
115132

@@ -485,9 +502,44 @@ object ApolloCompiler {
485502
val codegenSchema = buildCodegenSchema(
486503
schemaFiles = schemaFiles,
487504
logger = logger,
488-
codegenSchemaOptions = codegenSchemaOptions
505+
codegenSchemaOptions = codegenSchemaOptions,
506+
foreignSchemas = emptyList()
507+
)
508+
509+
return buildSchemaAndOperationsSources(
510+
codegenSchema,
511+
executableFiles,
512+
irOptions,
513+
codegenOptions,
514+
layoutFactory,
515+
operationOutputGenerator,
516+
irOperationsTransform,
517+
javaOutputTransform,
518+
kotlinOutputTransform,
519+
documentTransform,
520+
logger,
521+
operationManifestFile
489522
)
523+
}
490524

525+
526+
/**
527+
* Compiles a set of files without serializing the intermediate results
528+
*/
529+
fun buildSchemaAndOperationsSources(
530+
codegenSchema: CodegenSchema,
531+
executableFiles: List<InputFile>,
532+
irOptions: IrOptions,
533+
codegenOptions: CodegenOptions,
534+
layoutFactory: LayoutFactory?,
535+
@Suppress("DEPRECATION") operationOutputGenerator: OperationOutputGenerator?,
536+
irOperationsTransform: Transform<IrOperations>?,
537+
javaOutputTransform: Transform<JavaOutput>?,
538+
kotlinOutputTransform: Transform<KotlinOutput>?,
539+
documentTransform: DocumentTransform?,
540+
logger: Logger?,
541+
operationManifestFile: File?,
542+
): SourceOutput {
491543
val irOperations = buildIrOperations(
492544
codegenSchema = codegenSchema,
493545
executableFiles = executableFiles,

libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo/compiler/ApolloCompilerPlugin.kt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.apollographql.apollo.compiler
22

33
import com.apollographql.apollo.annotations.ApolloExperimental
4+
import com.apollographql.apollo.ast.ForeignSchema
5+
import com.apollographql.apollo.ast.GQLDocument
46
import com.apollographql.apollo.ast.GQLFragmentDefinition
57
import com.apollographql.apollo.ast.GQLOperationDefinition
68
import com.apollographql.apollo.ast.Schema
@@ -10,13 +12,15 @@ import com.apollographql.apollo.compiler.codegen.kotlin.KotlinOutput
1012
import com.apollographql.apollo.compiler.ir.IrOperations
1113
import com.apollographql.apollo.compiler.operationoutput.OperationDescriptor
1214
import com.apollographql.apollo.compiler.operationoutput.OperationId
15+
import java.io.File
1316

1417
/**
1518
* [ApolloCompilerPlugin] allows to customize the behaviour of the Apollo Compiler.
1619
*
17-
* [ApolloCompilerPlugin] is run in an isolated classloader. You may throw from [ApolloCompilerPlugin] methods to fail the build
18-
* but custom exception classes are not accessible from the calling environment like Gradle for an example.
19-
* Prefer throwing regular Java exception classes.
20+
* [ApolloCompilerPlugin] may be instantiated several times in a codegen run. Each instance is create in a
21+
* separate classloader.
22+
* The classloaders contains `apollo-compiler` classes and the runtime classpath of the [ApolloCompilerPlugin].
23+
* You may throw from [ApolloCompilerPlugin] methods to fail the build.
2024
*/
2125
interface ApolloCompilerPlugin {
2226
/**
@@ -65,8 +69,37 @@ interface ApolloCompilerPlugin {
6569
fun irOperationsTransform(): Transform<IrOperations>? {
6670
return null
6771
}
72+
73+
/**
74+
* @return A list of [ForeignSchema] supported by this plugin
75+
*/
76+
@ApolloExperimental
77+
fun foreignSchemas(): List<ForeignSchema> {
78+
return emptyList()
79+
}
80+
81+
/**
82+
* @return A [SchemaDocumentListener] called whenever the schema changed
83+
*/
84+
@ApolloExperimental
85+
fun schemaDocumentListener(): SchemaDocumentListener? {
86+
return null
87+
}
6888
}
6989

90+
@ApolloExperimental
91+
interface SchemaDocumentListener {
92+
/**
93+
* Called when the schema changed and codegen needs to be updated
94+
*
95+
* @param schema the validated schema document.
96+
* @param outputDirectory the compiler output directory. This directory is shared with the compiler, make sure to use a specific
97+
* package name to avoid clobbering other files.
98+
*/
99+
fun onSchemaDocument(schema: GQLDocument, outputDirectory: File)
100+
}
101+
102+
70103
/**
71104
* A [DocumentTransform] transforms operations and fragments at build time. [DocumentTransform] can add or remove fields automatically for an example.
72105
*/

libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo/compiler/CodegenTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ private fun ApolloCompiler.buildSchemaAndOperationsSourcesAndReturnIrOperations(
470470
val codegenSchema = buildCodegenSchema(
471471
schemaFiles = schemaFiles,
472472
logger = logger,
473-
codegenSchemaOptions = codegenSchemaOptions
473+
codegenSchemaOptions = codegenSchemaOptions,
474+
foreignSchemas = emptyList()
474475
)
475476

476477
val irOperations = buildIrOperations(

libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo/compiler/MetadataTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class MetadataTest {
4444
schemaFiles = setOf(File("src/test/metadata/schema.graphqls")).toInputFiles(),
4545
logger = null,
4646
codegenSchemaOptions = codegenSchemaOptionsFile.toCodegenSchemaOptions(),
47+
foreignSchemas = emptyList(),
4748
).writeTo(codegenSchemaFile)
4849

4950
ApolloCompiler.buildIrOperations(

0 commit comments

Comments
 (0)