Skip to content

Commit df4e47b

Browse files
committed
fix(amazonq): allow polymorphic deserialization of getConfigurationFromServer response
this is still janky and will probably need to be revisited. however, the return type as modeled is 'LSPAny' so this will need to be somewhat organic
1 parent 5de10f3 commit df4e47b

File tree

5 files changed

+67
-8
lines changed

5 files changed

+67
-8
lines changed

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererCon
5555
import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT
5656
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
5757
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerParams
58-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LspServerConfigurations
58+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.Workspaces
5959
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager
6060
import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor
6161
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator
@@ -706,12 +706,12 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable {
706706
)
707707
}
708708

709-
private fun getWorkspaceIds(project: Project): CompletableFuture<LspServerConfigurations> {
709+
private fun getWorkspaceIds(project: Project): CompletableFuture<Workspaces> {
710710
val payload = GetConfigurationFromServerParams(
711711
section = "aws.q.workspaceContext"
712712
)
713713
return AmazonQLspService.executeIfRunning(project) { server ->
714-
server.getConfigurationFromServer(payload)
714+
server.getConfigurationFromServer(payload) as CompletableFuture<Workspaces>
715715
} ?: (CompletableFuture.failedFuture(IllegalStateException("LSP Server not running")))
716716
}
717717

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLanguageServer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
88
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest
99
import org.eclipse.lsp4j.services.LanguageServer
1010
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerParams
11-
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LspServerConfigurations
11+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerResponse
1212
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayload
1313
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.dependencies.DidChangeDependencyPathsParams
1414
import java.util.concurrent.CompletableFuture
@@ -28,5 +28,5 @@ interface AmazonQLanguageServer : LanguageServer {
2828
fun deleteTokenCredentials(): CompletableFuture<Unit>
2929

3030
@JsonRequest("aws/getConfigurationFromServer")
31-
fun getConfigurationFromServer(params: GetConfigurationFromServerParams): CompletableFuture<LspServerConfigurations>
31+
fun getConfigurationFromServer(params: GetConfigurationFromServerParams): CompletableFuture<GetConfigurationFromServerResponse>
3232
}

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.artifacts.ArtifactMa
5050
import software.aws.toolkits.jetbrains.services.amazonq.lsp.auth.DefaultAuthCredentialsService
5151
import software.aws.toolkits.jetbrains.services.amazonq.lsp.dependencies.DefaultModuleDependenciesService
5252
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
53+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.adapter.GetConfigurationFromServerResponseTypeAdapterFactory
5354
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.createExtendedClientMetadata
5455
import software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument.TextDocumentServiceHandler
5556
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.WorkspaceFolderUtil.createWorkspaceFolders
@@ -272,6 +273,9 @@ private class AmazonQServerInstance(private val project: Project, private val cs
272273

273274
// otherwise Gson treats all numbers as double which causes deser issues
274275
it.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
276+
277+
// type adapter factory for polymorphic deserialization
278+
it.registerTypeAdapterFactory(GetConfigurationFromServerResponseTypeAdapterFactory())
275279
}.traceMessages(
276280
PrintWriter(
277281
object : StringWriter() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.adapter
5+
6+
import com.google.gson.Gson
7+
import com.google.gson.JsonElement
8+
import com.google.gson.TypeAdapter
9+
import com.google.gson.TypeAdapterFactory
10+
import com.google.gson.reflect.TypeToken
11+
import com.google.gson.stream.JsonReader
12+
import com.google.gson.stream.JsonWriter
13+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.Customizations
14+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerResponse
15+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.Workspaces
16+
17+
class GetConfigurationFromServerResponseTypeAdapterFactory : TypeAdapterFactory {
18+
override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
19+
// Only handle GetConfigurationFromServerResponse
20+
if (GetConfigurationFromServerResponse::class.java != type.rawType) {
21+
return null
22+
}
23+
24+
val delegateAdapter = gson.getDelegateAdapter(this, type)
25+
val elementAdapter = gson.getAdapter(JsonElement::class.java)
26+
27+
@Suppress("UNCHECKED_CAST")
28+
return object : TypeAdapter<T>() {
29+
override fun write(out: JsonWriter, value: T) {
30+
delegateAdapter.write(out, value)
31+
}
32+
33+
override fun read(reader: JsonReader): T? {
34+
val jsonElement = elementAdapter.read(reader)
35+
if (!jsonElement.isJsonObject) {
36+
return null
37+
}
38+
39+
val jsonObject = jsonElement.asJsonObject
40+
41+
val ret = when {
42+
jsonObject.has("workspaces") -> gson.fromJson(jsonElement, Workspaces::class.java)
43+
jsonObject.has("customizations") -> gson.fromJson(jsonElement, Customizations::class.java)
44+
else -> delegateAdapter.fromJsonTree(jsonElement)
45+
} as T
46+
47+
return ret
48+
}
49+
}
50+
}
51+
}
52+

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/LspServerConfigurations.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33

44
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws
55

6-
// This represents each item in the array
7-
data class WorkspaceInfo(val workspaceRoot: String, val workspaceId: String)
6+
interface GetConfigurationFromServerResponse
87

98
// This represents the entire array
10-
data class LspServerConfigurations(val workspaces: List<WorkspaceInfo>)
9+
data class Workspaces(val workspaces: List<WorkspaceInfo>): GetConfigurationFromServerResponse
10+
data class Customizations(val customizations: List<Customization>): GetConfigurationFromServerResponse
11+
12+
data class WorkspaceInfo(val workspaceRoot: String, val workspaceId: String)
13+
data class Customization(val arn: String, val name: String, val description: String)

0 commit comments

Comments
 (0)