fun getProjectPayloadMetadata()

in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt [221:306]


    fun getProjectPayloadMetadata(): PayloadMetadata {
        val files = mutableSetOf<String>()
        val traversedDirectories = mutableSetOf<VirtualFile>()
        val stack = Stack<VirtualFile>()
        var currentTotalFileSize = 0L
        var currentTotalLines = 0L
        val languageCounts = mutableMapOf<CodeWhispererProgrammingLanguage, Int>()
        var gitDiffContent = ""

        moduleLoop@ for (module in project.modules) {
            val changeListManager = ChangeListManager.getInstance(module.project)
            module.guessModuleDir()?.let { moduleDir ->
                val gitIgnoreFilteringUtil = GitIgnoreFilteringUtil(moduleDir)
                stack.push(moduleDir)
                while (stack.isNotEmpty()) {
                    val current = stack.pop()

                    if (!current.isDirectory) {
                        if (current.isFile && !changeListManager.isIgnoredFile(current) &&
                            runBlocking { !gitIgnoreFilteringUtil.ignoreFile(current) } &&
                            runReadAction { !fileIndex.isInLibrarySource(current) }
                        ) {
                            if (willExceedPayloadLimit(currentTotalFileSize, current.length)) {
                                fileTooLarge()
                            } else {
                                try {
                                    val language = current.programmingLanguage()
                                    if (language !is CodeWhispererUnknownLanguage) {
                                        languageCounts[language] = (languageCounts[language] ?: 0) + 1
                                    }
                                    files.add(current.path)
                                    currentTotalFileSize += current.length
                                    currentTotalLines += countLinesInVirtualFile(current)
                                } catch (e: Exception) {
                                    LOG.debug { "Error parsing the file: ${current.path} with error: ${e.message}" }
                                    continue
                                }
                            }
                        }
                    } else {
                        try {
                            if (isGitRoot(current)) {
                                LOG.debug { "$current is git directory" }
                                gitDiffContent = buildString {
                                    append(runGitDiffHead(project.name, current))
                                    getUnstagedFiles(current).takeIf { it.isNotEmpty() }?.let { unstagedFiles ->
                                        unstagedFiles
                                            .asSequence()
                                            .map { relativePath -> runGitDiffHead(project.name, current, relativePath, true) }
                                            .filter { it.isNotEmpty() }
                                            .forEach { diff ->
                                                if (isNotEmpty()) append('\n')
                                                append(diff)
                                            }
                                    }
                                }
                            }
                        } catch (e: Exception) {
                            LOG.debug { "Error parsing the git diff for repository $current" }
                        }
                        // Directory case: only traverse if not ignored
                        if (!changeListManager.isIgnoredFile(current) &&
                            runBlocking { !gitIgnoreFilteringUtil.ignoreFile(current) } &&
                            !traversedDirectories.contains(current) && current.isValid &&
                            runReadAction { !fileIndex.isInLibrarySource(current) }
                        ) {
                            for (child in current.children) {
                                stack.push(child)
                            }
                        }
                        traversedDirectories.add(current)
                    }
                }
            }
        }

        val maxCount = languageCounts.maxByOrNull { it.value }?.value ?: 0
        val maxCountLanguage = languageCounts.filter { it.value == maxCount }.keys.firstOrNull()

        if (maxCountLanguage == null) {
            programmingLanguage = CodeWhispererUnknownLanguage.INSTANCE
            noSupportedFilesError()
        }
        programmingLanguage = maxCountLanguage
        return PayloadMetadata(files, currentTotalFileSize, currentTotalLines, maxCountLanguage.toTelemetryType(), gitDiffContent)
    }