suspend fun calculateRepoMapping()

in server/server/src/main/kotlin/org/jetbrains/bazel/server/bzlmod/RepoMapping.kt [20:90]


suspend fun calculateRepoMapping(
  workspaceContext: WorkspaceContext,
  bazelRunner: BazelRunner,
  bazelInfo: BazelInfo,
  bspClientLogger: BspClientLogger,
): RepoMapping {
  if (!bazelInfo.isBzlModEnabled) {
    return RepoMappingDisabled
  }
  val moduleResolver = ModuleResolver(bazelRunner, ModuleOutputParser(), workspaceContext)
  val moduleCanonicalNameToLocalPath = mutableMapOf<String, Path>()
  val moduleApparentNameToCanonicalName =
    try {
      // empty string is the name of the root module
      moduleResolver.getRepoMapping("")
    }
    catch (e: Exception) {
      bspClientLogger.error(e.toString())
      return RepoMappingDisabled
    }

  val moduleApparentNameToCanonicalNameForNeededTransitiveRules =
    rootRulesToNeededTransitiveRules.keys
      .mapNotNull { moduleApparentNameToCanonicalName[it] }
      .map { moduleResolver.getRepoMapping(it) }
      .reduceOrNull { acc, map -> acc + map }
      .orEmpty()

  moduleResolver.resolveModule(workspaceContext.externalRepositoriesTreatedAsInternal).forEach { externalRepo, showRepoResult ->
    try {
      when (showRepoResult) {
        is ShowRepoResult.LocalRepository -> moduleCanonicalNameToLocalPath[showRepoResult.name] = Path(showRepoResult.path)
        else -> {
          bspClientLogger.warn("Tried to import external module $externalRepo, but it was not `local_path_override`: $showRepoResult")
        }
      }
    }
    catch (e: Exception) {
      bspClientLogger.error(e.toString())
    }
  }

  val moduleCanonicalNameToPath = moduleCanonicalNameToLocalPath.toMutableMap()
  for (canonicalName in moduleApparentNameToCanonicalName.values) {
    if (canonicalName == "") {
      moduleCanonicalNameToPath[canonicalName] = bazelInfo.workspaceRoot
      continue
    }
    val localPath = moduleCanonicalNameToLocalPath[canonicalName]
    val repoPath =
      if (localPath != null) {
        bazelInfo.workspaceRoot.resolve(localPath)
      }
      else {
        // See https://bazel.build/external/overview#directory-layout
        bazelInfo.outputBase.resolve("external").resolve(canonicalName)
      }
    moduleCanonicalNameToPath[canonicalName] = repoPath
  }

  val apparentRepoNameToCanonicalName =
    BidirectionalMap
      .getTypedInstance<String, String>()
      .apply { putAll(moduleApparentNameToCanonicalNameForNeededTransitiveRules + moduleApparentNameToCanonicalName) }

  return BzlmodRepoMapping(
    moduleCanonicalNameToLocalPath,
    apparentRepoNameToCanonicalName,
    moduleCanonicalNameToPath,
  )
}