Skip to content

Replace moshi with kotlinx-serialization #152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ plugins {
id("com.android.library").version("4.0.1").apply(false)
id("com.yelp.codegen.plugin").version("1.4.1").apply(false)
id("io.gitlab.arturbosch.detekt").version("1.14.2").apply(false)
kotlin("android").version("1.3.72").apply(false)
kotlin("android").version("1.5.20").apply(false)
id("org.jetbrains.kotlin.plugin.serialization").version("1.5.20").apply(false)
}

project.extra.apply {
set("kotlinVersion", "1.5.20")
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,7 @@ open class KotlinGenerator : SharedCodegen() {
"CollectionFormats.kt",
"EnumToValueConverterFactory.kt",
"GeneratedCodeConverters.kt",
"TypesAdapters.kt",
"WrapperConverterFactory.kt",
"XNullable.kt",
"XNullableAdapterFactory.kt"
"WrapperConverterFactory.kt"
)
supportingFiles.addAll(toolsFiles.map { SupportingFile("tools/$it.mustache", toolsFolder, it) })
return supportingFiles
Expand Down Expand Up @@ -206,21 +203,14 @@ open class KotlinGenerator : SharedCodegen() {
internal fun addRequiredImports(codegenModel: CodegenModel) {
// If there are any vars, we will mark them with the @Json annotation so we have to make sure to import it
if (codegenModel.allVars.isNotEmpty() || codegenModel.isEnum) {
codegenModel.imports.add("com.squareup.moshi.Json")
codegenModel.imports.add("kotlinx.serialization.Serializable")
codegenModel.imports.add("kotlinx.serialization.SerialName")
}

if (!codegenModel.isAlias) {
// If we are rendering a model (or enum) we are annotating it with @JsonClass,
// so we need to make sure that we're importing it
codegenModel.imports.add("com.squareup.moshi.JsonClass")
}

// Add import for @XNullable annotation if there are any XNullable properties
for (property in codegenModel.allVars) {
if (X_NULLABLE in property.vendorExtensions) {
codegenModel.imports.add("$toolsPackage.XNullable")
break
}
codegenModel.imports.add("kotlinx.serialization.Serializable")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ object KotlinLangUtils {
"float" to "Float",
"long" to "Long",
"double" to "Double",
"number" to "BigDecimal",
"number" to "Double",
"date" to "LocalDate",
"DateTime" to "ZonedDateTime",
"date-time" to "ZonedDateTime",
"DateTime" to "Instant",
"date-time" to "Instant",
"file" to "File",
"array" to "List",
"list" to "List",
"map" to "Map",
"object" to "Map<String, Any?>",
"object" to "JsonObject",
"binary" to "List<Byte>"
)

Expand All @@ -137,14 +137,13 @@ object KotlinLangUtils {
"Float" to "kotlin.Float",
"Long" to "kotlin.Long",
"Double" to "kotlin.Double",
"BigDecimal" to "java.math.BigDecimal",
"LocalDate" to "java.time.LocalDate",
"ZonedDateTime" to "java.time.ZonedDateTime",
"LocalDate" to "kotlinx.datetime.LocalDate",
"Instant" to "kotlinx.datetime.Instant",
"File" to "java.io.File",
"List" to "kotlin.collections.List",
"List<Byte>" to "kotlin.collections.List",
"Map" to "kotlin.collections.Map",
"Map<String, Any?>" to "kotlin.collections.Map",
"JsonObject" to "kotlinx.serialization.json.JsonObject",
"Timestamp" to "java.sql.Timestamp",
"UUID" to "java.util.UUID"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @property {{{name}}}{{#description}} {{description}}{{/description}}
{{/vars}}
*/
@JsonClass(generateAdapter = true)
@Serializable
{{#hasVars}}data {{/hasVars}}class {{classname}}{{#hasVars}}(
{{#requiredVars}}
{{>data_class_req_var}}{{^-last}},
Expand All @@ -18,7 +18,7 @@
* {{{description}}}{{/description}}
* Values:{{#allowableValues}} {{#enumVars}}{{&name}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}
*/
@JsonClass(generateAdapter = false)
enum class {{enumName}}(val value: {{complexType}}) {
{{#allowableValues}}{{#enumVars}} @Json(name = {{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{{newline}}}{{/enumVars}}{{/allowableValues}} }
@Serializable
enum class {{enumName}}() {
{{#allowableValues}}{{#enumVars}} @SerialName({{{value}}}) {{&name}}{{^-last}},{{/-last}}{{{newline}}}{{/enumVars}}{{/allowableValues}} }
{{/isEnum}}{{/vars}}}{{/hasEnums}}{{/hasVars}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@Json(name = "{{{baseName}}}") @field:Json(name = "{{{baseName}}}") {{#vendorExtensions.x-nullable}}@XNullable {{/vendorExtensions.x-nullable}}var {{{name}}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}} = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}
@SerialName("{{{baseName}}}") var {{{name}}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}} = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@Json(name = "{{{baseName}}}") @field:Json(name = "{{{baseName}}}") var {{{name}}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}
@SerialName("{{{baseName}}}") var {{{name}}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
* {{{description}}}{{/description}}
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
*/
@JsonClass(generateAdapter = false)
enum class {{classname}}(val value: {{dataType}}) {
{{#allowableValues}}{{#enumVars}} @Json(name = {{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{{newline}}}{{/enumVars}}{{/allowableValues}}}
@Serializable
enum class {{classname}}() {
{{#allowableValues}}{{#enumVars}} @SerialName({{{value}}}) {{&name}}{{^-last}},{{/-last}}{{{newline}}}{{/enumVars}}{{/allowableValues}}}
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package {{packageName}}.tools

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.squareup.moshi.Moshi
import kotlinx.serialization.json.Json
import okhttp3.MediaType
import retrofit2.Converter
import retrofit2.converter.moshi.MoshiConverterFactory

object GeneratedCodeConverters {
private val moshi = Moshi.Builder()
.add(XNullableAdapterFactory())
.add(TypesAdapterFactory())
.build()

/**
* Creates everything needed for retrofit to make it work with the client lib, including a
* [Moshi] instance. If you want to use your own instance of moshi, use
Expand All @@ -18,19 +15,11 @@ object GeneratedCodeConverters {
*/
@JvmStatic
fun converterFactory(): Converter.Factory {
val contentType = MediaType.get("application/json")
return WrapperConverterFactory(
CollectionFormatConverterFactory(),
EnumToValueConverterFactory(),
MoshiConverterFactory.create(moshi)
)
}

@JvmStatic
fun converterFactory(moshi: Moshi): Converter.Factory {
return WrapperConverterFactory(
CollectionFormatConverterFactory(),
EnumToValueConverterFactory(),
MoshiConverterFactory.create(moshi)
Json.asConverterFactory(contentType)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* {{{description}}}
* Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}
*/
enum class {{enumName}}(val value: String) {
{{#allowableValues}}{{#enumVars}}@Json(name = {{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}}{{/-last}}{{/enumVars}}{{/allowableValues}}
enum class {{enumName}}() {
{{#allowableValues}}{{#enumVars}}@SerialName({{{value}}}) {{&name}}{{^-last}},{{/-last}}{{#-last}}{{/-last}}{{/enumVars}}{{/allowableValues}}
}
{{/vars}}{{/hasEnums}}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class KotlinGeneratorTest {

KotlinGenerator().addRequiredImports(model)

assertTrue(model.imports.contains("com.squareup.moshi.Json"))
assertTrue(model.imports.contains("com.squareup.moshi.JsonClass"))
assertTrue(model.imports.contains("kotlinx.serialization.Serializable"))
assertTrue(model.imports.contains("kotlinx.serialization.SerialName"))
assertFalse(model.imports.contains("com.yelp.test.tools.XNullable"))
}

Expand All @@ -60,8 +60,8 @@ class KotlinGeneratorTest {

KotlinGenerator().addRequiredImports(model)

assertTrue(model.imports.contains("com.squareup.moshi.Json"))
assertTrue(model.imports.contains("com.squareup.moshi.JsonClass"))
assertTrue(model.imports.contains("kotlinx.serialization.Serializable"))
assertTrue(model.imports.contains("kotlinx.serialization.SerialName"))
assertFalse(model.imports.contains("com.yelp.test.tools.XNullable"))
}

Expand All @@ -72,29 +72,11 @@ class KotlinGeneratorTest {

KotlinGenerator().addRequiredImports(model)

assertFalse(model.imports.contains("com.squareup.moshi.Json"))
assertFalse(model.imports.contains("com.squareup.moshi.JsonClass"))
assertFalse(model.imports.contains("kotlinx.serialization.Serializable"))
assertFalse(model.imports.contains("kotlinx.serialization.Serializable"))
assertFalse(model.imports.contains("com.yelp.test.tools.XNullable"))
}

@Test
fun addRequiredImports_withXNullable() {
val generator = KotlinGenerator()
generator.additionalProperties()[GROUP_ID] = "com.yelp"
generator.additionalProperties()[ARTIFACT_ID] = "test"
val model = CodegenModel()
val xNullableProperty = CodegenProperty()
xNullableProperty.vendorExtensions = mutableMapOf()
xNullableProperty.vendorExtensions[X_NULLABLE] = true
model.allVars.add(xNullableProperty)

generator.addRequiredImports(model)

assertTrue(model.imports.contains("com.squareup.moshi.Json"))
assertTrue(model.imports.contains("com.squareup.moshi.JsonClass"))
assertTrue(model.imports.contains("com.yelp.test.tools.XNullable"))
}

@Test
fun postProcessModelProperty() {
val generator = KotlinGenerator()
Expand Down
9 changes: 4 additions & 5 deletions samples/groovy-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id("com.android.library")
id("kotlin-android")
id("com.yelp.codegen.plugin")
id("kotlin-kapt")
id("org.jetbrains.kotlin.plugin.serialization")
}

android {
Expand All @@ -22,16 +22,15 @@ android {

dependencies {
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${project.kotlinVersion}"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"

// Moshi + OkHttp + Retrofit
implementation "com.squareup.moshi:moshi:1.11.0"
implementation "com.squareup.moshi:moshi-adapters:1.11.0"
implementation "com.squareup.okhttp3:okhttp:3.12.12"
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.11.0"

// Date Support via Desugaring
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
Expand Down
12 changes: 7 additions & 5 deletions samples/junit-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ plugins {
id("kotlin")
id("com.yelp.codegen.plugin")
id("io.gitlab.arturbosch.detekt")
id("kotlin-kapt")
id("org.jetbrains.kotlin.plugin.serialization")
}

dependencies {
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${project.kotlinVersion}"
// api "org.jetbrains.kotlinx:kotlinx-serialization-core:1.2.2"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.2"
implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.2.1"

// Moshi + OkHttp + Retrofit
implementation "com.squareup.moshi:moshi:1.11.0"
implementation "com.squareup.moshi:moshi-adapters:1.11.0"
implementation "com.squareup.okhttp3:okhttp:3.12.12"
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.11.0"
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"


// RxJava
implementation "io.reactivex.rxjava2:rxjava:2.2.20"
Expand Down
54 changes: 54 additions & 0 deletions samples/junit-tests/junit_tests_specs.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,39 @@
"type": "object",
"x-model": "type_responses"
},
"xnullable_format_request": {
"properties": {
"date_property": {
"format": "date",
"type": "string"
},
"datetime_property": {
"format": "date-time",
"type": "string"
},
"double_property": {
"format": "double",
"type": "number"
},
"xnullable_date_property": {
"format": "date",
"type": "string",
"x-nullable": true
},
"xnullable_datetime_property": {
"format": "date-time",
"type": "string",
"x-nullable": true
},
"xnullable_double_property": {
"format": "double",
"type": "number",
"x-nullable": true
}
},
"type": "object",
"x-model": "xnullable_format_request"
},
"xnullable_format_responses": {
"properties": {
"date_property": {
Expand Down Expand Up @@ -935,6 +968,27 @@
"tags": [
"xnullable"
]
},
"post": {
"operationId": "post_xnullable_format_endpoint",
"parameters": [
{
"in": "body",
"name": "property_format",
"required": true,
"schema": {
"$ref": "#/definitions/xnullable_format_request"
}
}
],
"responses": {
"201": {
"description": "Created"
}
},
"tags": [
"xnullable"
]
}
},
"/xnullable/nested_additional_properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.yelp.codegen.generatecodesamples.apis

import com.yelp.codegen.generatecodesamples.models.XnullableFormatRequest
import com.yelp.codegen.generatecodesamples.models.XnullableFormatResponses
import com.yelp.codegen.generatecodesamples.models.XnullableNestedAdditionalProperties
import com.yelp.codegen.generatecodesamples.models.XnullablePropertyArray
Expand All @@ -14,9 +15,11 @@ import com.yelp.codegen.generatecodesamples.models.XnullableRequiredPropertyArra
import com.yelp.codegen.generatecodesamples.models.XnullableRequiredPropertyMap
import com.yelp.codegen.generatecodesamples.models.XnullableRequiredTypeResponses
import com.yelp.codegen.generatecodesamples.models.XnullableTypeResponses
import io.reactivex.Completable
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST

@JvmSuppressWildcards
interface XnullableApi {
Expand Down Expand Up @@ -109,4 +112,15 @@ interface XnullableApi {
fun getXnullableTypeEndpoint(
@retrofit2.http.Path("property_type") propertyType: String
): Single<XnullableTypeResponses>
/**
* The endpoint is owned by junittests service owner
* @param propertyFormat (required)
*/
@Headers(
"X-Operation-ID: post_xnullable_format_endpoint"
)
@POST("/xnullable/format_endpoint/{property_format}")
fun postXnullableFormatEndpoint(
@retrofit2.http.Body propertyFormat: XnullableFormatRequest
): Completable
}
Loading