private static TargetMapAndInterfaceState updateState()

in base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java [288:447]


  private static TargetMapAndInterfaceState updateState(
      Project project,
      BlazeContext parentContext,
      @Nullable BlazeIdeInterfaceState prevState,
      ArtifactsDiff fileState,
      BlazeConfigurationHandler configHandler,
      BlazeVersionData versionData,
      WorkspaceLanguageSettings languageSettings,
      ImportRoots importRoots,
      boolean mergeWithOldState,
      @Nullable TargetMap oldTargetMap) {
    AspectStrategy aspectStrategy = AspectStrategy.getInstance(versionData);
    Result<TargetMapAndInterfaceState> result =
        Scope.push(
            parentContext,
            context -> {
              context.push(new TimingScope("UpdateTargetMap", EventType.Other));
              context.output(new StatusOutput("Updating target map..."));

              // ideally, we'd flush through a per-build sync time parsed from BEP. For now, though
              // just set an approximate, batched sync time.
              Instant syncTime = Instant.now();
              Map<String, ArtifactState> nextFileState = new HashMap<>(fileState.getNewState());

              // If we're not removing we have to merge the old state
              // into the new one or we'll miss file removes next time
              if (mergeWithOldState && prevState != null) {
                prevState.ideInfoFileState.forEach(nextFileState::putIfAbsent);
              }

              BlazeIdeInterfaceState.Builder state = BlazeIdeInterfaceState.builder();
              state.ideInfoFileState = ImmutableMap.copyOf(nextFileState);

              Map<TargetKey, TargetIdeInfo> targetMap = Maps.newHashMap();
              if (prevState != null && oldTargetMap != null) {
                targetMap.putAll(oldTargetMap.map());
                state.ideInfoToTargetKey.putAll(prevState.ideInfoFileToTargetKey);
              }

              // Update removed unless we're merging with the old state
              if (!mergeWithOldState) {
                for (ArtifactState removed : fileState.getRemovedOutputs()) {
                  TargetKey key = state.ideInfoToTargetKey.remove(removed.getKey());
                  if (key != null) {
                    targetMap.remove(key);
                  }
                }
              }

              AtomicLong totalSizeLoaded = new AtomicLong(0);
              Set<LanguageClass> ignoredLanguages = Sets.newConcurrentHashSet();

              ListeningExecutorService executor = BlazeExecutor.getInstance().getExecutor();

              // Read protos from any new files
              List<ListenableFuture<TargetFilePair>> futures = Lists.newArrayList();
              for (OutputArtifact file : fileState.getUpdatedOutputs()) {
                futures.add(
                    executor.submit(
                        () -> {
                          totalSizeLoaded.addAndGet(file.getLength());
                          IntellijIdeInfo.TargetIdeInfo message =
                              aspectStrategy.readAspectFile(file);
                          TargetIdeInfo target =
                              protoToTarget(
                                  languageSettings,
                                  importRoots,
                                  message,
                                  ignoredLanguages,
                                  syncTime);
                          return new TargetFilePair(file, target);
                        }));
              }

              Set<TargetKey> newTargets = new HashSet<>();
              Set<String> configurations = new LinkedHashSet<>();
              configurations.add(configHandler.defaultConfigurationPathComponent);

              // Update state with result from proto files
              int duplicateTargetLabels = 0;
              try {
                for (TargetFilePair targetFilePair : Futures.allAsList(futures).get()) {
                  if (targetFilePair.target != null) {
                    OutputArtifact file = targetFilePair.file;
                    String config = file.getConfigurationMnemonic();
                    configurations.add(config);
                    TargetKey key = targetFilePair.target.getKey();
                    if (targetMap.putIfAbsent(key, targetFilePair.target) == null) {
                      state.ideInfoToTargetKey.forcePut(file.getKey(), key);
                    } else {
                      if (!newTargets.add(key)) {
                        duplicateTargetLabels++;
                      }
                      // prioritize the default configuration over build order
                      if (Objects.equals(config, configHandler.defaultConfigurationPathComponent)) {
                        targetMap.put(key, targetFilePair.target);
                        state.ideInfoToTargetKey.forcePut(file.getKey(), key);
                      }
                    }
                  }
                }
              } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return Result.error(null);
              } catch (ExecutionException e) {
                return Result.error(e);
              }

              context.output(
                  PrintOutput.log(
                      String.format(
                          "Loaded %d aspect files, total size %dkB",
                          fileState.getUpdatedOutputs().size(), totalSizeLoaded.get() / 1024)));
              if (duplicateTargetLabels > 0) {
                context.output(
                    new PerformanceWarning(
                        String.format(
                            "There were %d duplicate rules, built with the following "
                                + "configurations: %s.\nYour IDE sync is slowed down by ~%d%%.",
                            duplicateTargetLabels,
                            configurations,
                            (100 * duplicateTargetLabels / targetMap.size()))));
              }

              // remove previously synced targets which are now unsupported
              for (TargetKey key : ImmutableSet.copyOf(state.ideInfoToTargetKey.values())) {
                TargetIdeInfo target = targetMap.get(key);
                if (target != null
                    && shouldIgnoreTarget(
                        languageSettings, importRoots, target, ignoredLanguages)) {
                  state.ideInfoToTargetKey.inverse().remove(key);
                  targetMap.remove(key);
                }
              }

              // update sync time for unchanged targets
              for (String artifactKey : fileState.getNewState().keySet()) {
                TargetKey targetKey = state.ideInfoToTargetKey.get(artifactKey);
                TargetIdeInfo target = targetKey != null ? targetMap.get(targetKey) : null;
                if (target != null) {
                  targetMap.put(targetKey, target.updateSyncTime(syncTime));
                }
              }

              ignoredLanguages.retainAll(
                  LanguageSupport.availableAdditionalLanguages(
                      languageSettings.getWorkspaceType()));
              warnIgnoredLanguages(project, context, ignoredLanguages);

              return Result.of(
                  new TargetMapAndInterfaceState(
                      new TargetMap(ImmutableMap.copyOf(targetMap)), state.build()));
            });

    if (result.error != null) {
      logger.error(result.error);
      return null;
    }
    return result.result;
  }