My first Kotlin Symbol Processing Tool for Android

Background of requirements

When we communicate with server, we deliver many payloads. the payload type is mostly JSON. we sent and received lots of JSON payloads via HTTP.
For JSON, we are using Moshi
For HTTP, we are using Retrofit

1. KSP module config


2. SymbolProcessor

We are going to use SymbolProcessor as Google provided sample project.

fun init(
options: Map<String, String>,
kotlinVersion: KotlinVersion,
codeGenerator: CodeGenerator,
logger: KSPLogger
fun process(resolver: Resolver): List<KSAnnotated>fun finish()fun onError() {}
  1. in init() : Read Gradle script property. Set codeGenerator to member field
  2. in process() : Collect @JsonClass(generateAdapter = true)annotated class
  3. in finish() : Generate Grouped JsonAdapterFactory

3. Init()

4. process()

5. CustomKSVisitor.kt

KSVisitor is to help reading each KSNode information.

class KSVisitor<D, R> {
fun visitFile(file: KSFile, data: D): R
fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: D): R
fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: D): R
// and so on.. argument, property getter/setter

6. finish()

Before finishing KSP, we will generate GroupedJsonAdapterFactory.

val packageName = "com.example"
val outputStream: OutputStream = codeGenerator.createNewFile(
dependencies = Dependencies(
* { it.containingFile!! }
packageName = packageName,
fileName = "GroupJsonAdapterFactory"
|package $packageName
|import com.squareup.moshi.JsonAdapter
|import com.squareup.moshi.Moshi
|import com.squareup.moshi.Types
|// import target classes & target classes json adapter
|class GroupJsonAdapterFactory: JsonAdapter.Factory {
| override fun create(): JsonAdapter<*> {
| // declare logics
| }

7. Resources/

In, we should expose our SymboleProcessor explicitly.


7. Consumer module

8. Wth??? My IDEA isn’t aware of KSP generated file

Yes currently, KSP generated files isn’t indexed on IDE. To use it, you should do extra work in Gradle script.


If you are doing multi module project, Duplicated class name to generate file is not good idea. So we use this

// consumer build.gradle.kts
ksp {
// SymbolProcessor.kt
private lateinit var projectName: String
fun init(options: Map<String, String>) {
projectName = options["projectName"]
fun finish() { outputStream.write("""
|class ${projectName}JsonAdapterFactory


I have no idea KSP is really faster or easier than APT. Because I never write APT code generator before. but KSP is really simple and fast enough to use. And I am happy to use.


Github :
Sample for Android : google/ksp/playground-android
KSP adoption in AOSP :


com.sqaureup.moshi.internal.Util.generatedAdapter() is covering my work and internally it has ProguardConfiguration to prevent obfuscation of class also. Please refer this only for KSP usages. lol



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
SeongUg Steve Jung

SeongUg Steve Jung

Android Developer, Google Developers Experts