# kotlinx-metadata-jvm

This library provides an API to read and modify metadata of binary files generated by the Kotlin/JVM compiler, namely `.class` and `.kotlin_module` files.

## Usage

To use this library in your project, add a dependency on `org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinx_metadata_version` (where `kotlinx_metadata_version` is the version of the library).

Example usage in Maven:

```xml
<project>
    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlinx</groupId>
            <artifactId>kotlinx-metadata-jvm</artifactId>
            <version>${kotlinx_metadata_version}</version>
        </dependency>
    </dependencies>
    ...
</project>
```

Example usage in Gradle:

```gradle
repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinx_metadata_version"
}
```

## Overview

The entry point for reading the Kotlin metadata of a `.class` file is [`KotlinClassMetadata.read`](src/kotlinx/metadata/jvm/KotlinClassMetadata.kt).
The data it takes is the [`kotlin.Metadata`](../../stdlib/jvm/runtime/kotlin/Metadata.kt) annotation on the class file generated by the Kotlin compiler.
Obtain the `kotlin.Metadata` annotation reflectively or construct it from binary representation (e.g. by reading classfile with `org.objectweb.asm.ClassReader`),
and then use `KotlinClassMetadata.read` to obtain the correct instance of the class metadata.

```kotlin
val metadataAnnotation = Metadata(
    // pass arguments here
)
val metadata = KotlinClassMetadata.read(metadataAnnotation)
```

`KotlinClassMetadata` is a sealed class, with subclasses representing all the different kinds of classes generated by the Kotlin compiler.
Unless you're sure that you're reading a class of a specific kind and can do a simple cast, a `when` is a good choice to handle all the possibilities:

```kotlin
when (metadata) {
    is KotlinClassMetadata.Class -> ...
    is KotlinClassMetadata.FileFacade -> ...
    is KotlinClassMetadata.SyntheticClass -> ...
    is KotlinClassMetadata.MultiFileClassFacade -> ...
    is KotlinClassMetadata.MultiFileClassPart -> ...
    is KotlinClassMetadata.Unknown -> ...
}
```

Let's assume we've obtained an instance of `KotlinClassMetadata.Class`; other kinds of classes are handled similarly, except some of them have metadata in a slightly different form.
The main way to make sense of the underlying metadata is to invoke `toKmClass()`, which returns an instance of `KmClass` (`Km` is a shorthand for “Kotlin metadata”):

```kotlin
val klass = metadata.toKmClass()
println(klass.functions.map { it.name })
println(klass.properties.map { it.name })
```

Please refer to [`MetadataSmokeTest.listInlineFunctions`](test/kotlinx/metadata/test/MetadataSmokeTest.kt) for an example where all inline functions are read from the class metadata along with their JVM signatures.

## Flags

Numerous objects have a property named `flags` of type `Flags`. These flags represent modifiers or other boolean attributes of a declaration or a type.
To check if a certain flag is present, call one of the flags in [`Flag`](../src/kotlinx/metadata/Flag.kt) on the given integer value.
The set of applicable flags is documented for each Node property which has type `Flags`.
For example, functions have common declaration flags (visibility, modality) plus `Flag.Function` flags:

```kotlin
val function: KmFunction = ...
if (Flag.IS_PUBLIC(function.flags)) {
    println("function ${function.name} is public")
}
if (Flag.Function.IS_SUSPEND(function.flags)) {
    println("function ${function.name} has the 'suspend' modifier")
}
```

## Writing metadata

To create metadata of a Kotlin class file from scratch, construct an instance of `KmClass`/`KmPackage`/`KmLambda`, fill it with the data and call corresponding `KotlinClassMetadata.write` function.
Resulting `KotlinClassMetadata.annotationData` can be used to write `kotlin.Metadata` annotation on a class file.

When using metadata writers from Kotlin source code, it's very convenient to use Kotlin scoping functions such as `apply` to reduce boilerplate:

```kotlin
// Writing metadata of a class
val klass = KmClass().apply {
    // Setting the name and the modifiers of the class.
    // Flags are constructed by invoking "flagsOf(...)"
    name = "MyClass"
    flags = flagsOf(Flag.IS_PUBLIC)

    // Adding one public primary constructor
    constructors += KmConstructor(flagsOf(Flag.IS_PUBLIC, Flag.Constructor.IS_PRIMARY)).apply {
        // Setting the JVM signature (for example, to be used by kotlin-reflect)
        signature = JvmMethodSignature("<init>", "()V")
    }

    ...
}

val annotation = KotlinClassMetadata.writeClass(klass).annotationData

// Write annotation directly or use annotation.kind, annotation.data1, annotation.data2, etc.
```

Please refer to [`MetadataSmokeTest.produceKotlinClassFile`](test/kotlinx/metadata/test/MetadataSmokeTest.kt) for an example where metadata of a simple Kotlin class is created,
and then the class file is produced with ASM and loaded by Kotlin reflection.

## Module metadata

Similarly to how `KotlinClassMetadata` is used to read/write metadata of Kotlin `.class` files, [`KotlinModuleMetadata`](src/kotlinx/metadata/jvm/KotlinModuleMetadata.kt)
is the entry point for reading/writing `.kotlin_module` files. Use `KotlinModuleMetadata.read` or `KotlinModuleMetadata.write` in very much the same fashion as with the class files.
The only difference is that the source for the reader (and the result of the writer) is a simple byte array, not the structured data loaded from `kotlin.Metadata`:

```kotlin
// Read the module metadata
val bytes = File("META-INF/main.kotlin_module").readBytes()
val metadata = KotlinModuleMetadata.read(bytes)
val module = metadata.toKmModule()
...

// Write the module metadata
val bytes = KotlinModuleMetadata.write(module).bytes
File("META-INF/main.kotlin_module").writeBytes(bytes)
```

## Laziness

Note that until you load the actual underlying data of a `KotlinClassMetadata` or `KotlinModuleMetadata` instance by invoking one of the `toKm...` methods,
the data is not completely parsed and verified. If you need to check if the data is not horribly corrupted before proceeding, ensure that either of those is called:

```kotlin
val metadata: KotlinClassMetadata.Class = ...

try {
    // Guarantees eager parsing of the underlying data
    metadata.toKmClass()
} catch (e: Exception) {
    System.err.println("Metadata is corrupted!")
}
```



