suspend fun extractSupplementalFileContextForSrc()

in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererFileContextProvider.kt [222:328]


    suspend fun extractSupplementalFileContextForSrc(psiFile: PsiFile, targetContext: FileContextInfo): SupplementalContextInfo {
        if (!targetContext.programmingLanguage.isSupplementalContextSupported()) {
            return SupplementalContextInfo.emptyCrossFileContextInfo(targetContext.filename)
        }

        val query = generateQuery(targetContext)

        val contexts = withContext(coroutineContext) {
            val projectContextDeferred1 = async {
                val timedCodemapContext = measureTimedValue { fetchProjectContext(query, psiFile, targetContext) }
                val codemapContext = timedCodemapContext.value
                LOG.debug {
                    buildString {
                        append("time elapse for fetching project context=${timedCodemapContext.duration.inWholeMilliseconds}ms; ")
                        append("numberOfChunks=${codemapContext.contents.size}; ")
                        append("totalLength=${codemapContext.contentLength}")
                    }
                }

                codemapContext
            }

            val openTabsContextDeferred1 = async {
                val timedOpentabContext = measureTimedValue { fetchOpenTabsContext(query, psiFile, targetContext) }
                val opentabContext = timedOpentabContext.value
                LOG.debug {
                    buildString {
                        append("time elapse for open tabs context=${timedOpentabContext.duration.inWholeMilliseconds}ms; ")
                        append("numberOfChunks=${opentabContext.contents.size}; ")
                        append("totalLength=${opentabContext.contentLength}")
                    }
                }

                opentabContext
            }

            awaitAll(projectContextDeferred1, openTabsContextDeferred1)
        }

        val projectContext = contexts.find { it.strategy == CrossFileStrategy.Codemap }
        val openTabsContext = contexts.find { it.strategy == CrossFileStrategy.OpenTabsBM25 }

        /**
         * We're using both codemap and opentabs context
         * 1. If both are present, codemap should live in the first of supplemental context list, i.e [codemap, opentabs_0, opentabs_1...] with strategy name codemap
         * 2. If only one is present, return the one present with corresponding strategy name, either codemap or opentabs
         * 3. If none is present, return empty list with strategy name empty
         *
         * Service will throw 400 error when context length is greater than 20480, drop the last chunk until the total length fits in the cap
         */
        val contextBeforeTruncation = when {
            projectContext == null && openTabsContext == null -> SupplementalContextInfo.emptyCrossFileContextInfo(targetContext.filename)

            projectContext != null && openTabsContext != null -> {
                val context1 = projectContext.contents
                val context2 = openTabsContext.contents
                val mergedContext = (context1 + context2).filter { it.content.isNotEmpty() }

                val strategy = if (projectContext.contentLength != 0 && openTabsContext.contentLength != 0) {
                    CrossFileStrategy.Codemap
                } else if (projectContext.contentLength != 0) {
                    CrossFileStrategy.Codemap
                } else if (openTabsContext.contentLength != 0) {
                    CrossFileStrategy.OpenTabsBM25
                } else {
                    CrossFileStrategy.Empty
                }

                SupplementalContextInfo(
                    isUtg = false,
                    contents = mergedContext,
                    targetFileName = targetContext.filename,
                    strategy = strategy
                )
            }

            projectContext != null -> {
                return if (projectContext.contentLength == 0) {
                    SupplementalContextInfo.emptyCrossFileContextInfo(targetContext.filename)
                } else {
                    SupplementalContextInfo(
                        isUtg = false,
                        contents = projectContext.contents,
                        targetFileName = targetContext.filename,
                        strategy = CrossFileStrategy.Codemap
                    )
                }
            }

            openTabsContext != null -> {
                return if (openTabsContext.contentLength == 0) {
                    SupplementalContextInfo.emptyCrossFileContextInfo(targetContext.filename)
                } else {
                    SupplementalContextInfo(
                        isUtg = false,
                        contents = openTabsContext.contents,
                        targetFileName = targetContext.filename,
                        strategy = CrossFileStrategy.OpenTabsBM25
                    )
                }
            }

            else -> SupplementalContextInfo.emptyCrossFileContextInfo(targetContext.filename)
        }

        return truncateContext(contextBeforeTruncation)
    }