in generator/src/main/kotlin/space/jetbrains/api/generator/GenerateResources.kt [13:122]
fun generateResources(model: HttpApiEntitiesById): List<FileSpec> {
return model.resources.values.groupBy { displayPath(it, model) }.map { (displayPath, resourceGroup) ->
val className = ClassName(
resourcePackage(displayPath.dropLast(1)),
resourceGroup.first().displayPlural.displayNameToClassName()
)
FileSpec.builder(className.packageName, className.simpleName).also { fileBuilder ->
fileBuilder.indent(INDENT)
fileBuilder.addAnnotation(
AnnotationSpec.builder(Suppress::class)
.addMember("%S", "UNUSED_VARIABLE")
.build()
)
fileBuilder.addAnnotation(
AnnotationSpec.builder(ClassName("kotlin", "OptIn")).also { ann ->
model.featureFlags.values.forEach {
ann.addMember("%T::class", it.annotationClassName())
}
}.build()
)
if (displayPath.size == 1) { // top-level resource
fileBuilder.addProperty(
PropertySpec.builder(resourceGroup.first().displayPlural.displayNameToMemberName(), className)
.receiver(clientType)
.getter(FunSpec.getterBuilder().addStatement("return %T(this)", className).build())
.build()
)
}
fileBuilder.addType(TypeSpec.classBuilder(className).also { typeBuilder ->
typeBuilder.primaryConstructor(FunSpec.constructorBuilder().addParameter("client", clientType).build())
typeBuilder.superclass(restResourceType)
typeBuilder.addSuperclassConstructorParameter("client")
typeBuilder.addProperties(
resourceGroup.asSequence()
.flatMap { it.nestedResources.asSequence() }
.groupBy { displayPath(it, model) }
.values
.map { nestedGroup ->
val nestedName = nestedGroup.first().displayPlural
val nestedType = ClassName(resourcePackage(displayPath), nestedName.displayNameToClassName())
PropertySpec
.builder(nestedName.displayNameToMemberName(), nestedType)
.initializer("%T(client)", nestedType)
.build()
}
)
typeBuilder.addFunctions(resourceGroup.flatMap { it.endpoints }.map { endpoint ->
val urlParams = endpoint.parameters.sortedBy { !it.path }.map { it.field }
val queryParams = endpoint.parameters.filter { !it.path }.map { it.field }
val bodyParams = (endpoint.requestBody as? HA_Type.Object)?.fields
val returnType = endpoint.responseBody?.kotlinPoet(model)
val (partial, batch) = endpoint.responseBody.partial()
val partialInterface = partial?.partialToPartialInterface(model)
val hasUrlBatchInfo = queryParams.any {
it.name == META_PARAMETERS_PREFIX + "skip" || it.name == META_PARAMETERS_PREFIX + "top"
}
val funcParams = getFuncParams(model, urlParams, bodyParams, hasUrlBatchInfo, partialInterface).let {
if (endpoint.requestBody is HA_RawRequestPayload)
it + (ParameterSpec.builder("payload", outgoingContentType).build() to "Request payload")
else
it
}
val fullPath = endpoint.path.segments.asReversed().plus(
ancestors(model.resources.getValue(endpoint.resource.id), model)
.flatMap { it.path.segments.asReversed().asSequence() }
).asReversed()
FunSpec.builder(endpoint.functionName).also { funcBuilder ->
val kDoc = buildString {
buildKDoc(endpoint.description)?.let {
append(it)
}
funcParams.mapNotNull { it.second }.joinToString("").takeUnless { it.isBlank() }?.let {
append(it)
}
}
kDoc.takeUnless { it.isBlank() }?.let { funcBuilder.addKdoc(it) }
funcBuilder.annotations.deprecation(endpoint.deprecation)
funcBuilder.annotations.featureFlag(endpoint.featureFlag, model)
funcBuilder.addModifiers(KModifier.PUBLIC, KModifier.SUSPEND)
funcBuilder.addParameters(funcParams.map { it.first })
if (returnType != null) funcBuilder.returns(returnType)
funcBuilder.addCode(
buildFnBody(
partialInterface,
batch,
endpoint,
fullPath,
queryParams,
hasUrlBatchInfo,
model,
partial
).build()
)
}.build()
})
}.build())
}.build()
}
}