Search in sources :

Example 1 with ArtifactState

use of com.google.idea.blaze.base.filecache.ArtifactState in project intellij by bazelbuild.

the class BlazeIdeInterfaceAspectsImpl method updateState.

@Nullable
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());
        // 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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) ArtifactState(com.google.idea.blaze.base.filecache.ArtifactState) PerformanceWarning(com.google.idea.blaze.base.scope.output.PerformanceWarning) TimingScope(com.google.idea.blaze.base.scope.scopes.TimingScope) OutputArtifact(com.google.idea.blaze.base.command.buildresult.OutputArtifact) ExecutionException(java.util.concurrent.ExecutionException) LanguageClass(com.google.idea.blaze.base.model.primitives.LanguageClass) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) Instant(java.time.Instant) StatusOutput(com.google.idea.blaze.base.scope.output.StatusOutput) TargetIdeInfo(com.google.idea.blaze.base.ideinfo.TargetIdeInfo) AtomicLong(java.util.concurrent.atomic.AtomicLong) AspectStrategy(com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategy) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) TargetKey(com.google.idea.blaze.base.ideinfo.TargetKey) TargetMap(com.google.idea.blaze.base.ideinfo.TargetMap) Nullable(javax.annotation.Nullable)

Example 2 with ArtifactState

use of com.google.idea.blaze.base.filecache.ArtifactState in project intellij by bazelbuild.

the class BlazeIdeInterfaceState method fromProto.

public static BlazeIdeInterfaceState fromProto(ProjectData.BlazeIdeInterfaceState proto) {
    ImmutableMap<String, TargetKey> targets = ProtoWrapper.map(proto.getFileToTargetMap(), ArtifactState::migrateOldKeyFormat, TargetKey::fromProto);
    ImmutableMap.Builder<String, ArtifactState> artifacts = ImmutableMap.builder();
    for (LocalFileOrOutputArtifact output : proto.getIdeInfoFilesList()) {
        ArtifactState state = ArtifactStateProtoConverter.fromProto(output);
        if (state == null) {
            continue;
        }
        artifacts.put(state.getKey(), state);
    }
    return new BlazeIdeInterfaceState(artifacts.build(), ImmutableBiMap.copyOf(targets));
}
Also used : ArtifactState(com.google.idea.blaze.base.filecache.ArtifactState) TargetKey(com.google.idea.blaze.base.ideinfo.TargetKey) LocalFileOrOutputArtifact(com.google.devtools.intellij.model.ProjectData.LocalFileOrOutputArtifact) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 3 with ArtifactState

use of com.google.idea.blaze.base.filecache.ArtifactState in project intellij by bazelbuild.

the class PackageManifestReader method readPackageManifestFiles.

/**
 * @return A map from java source absolute file path to declared package string.
 */
public Map<TargetKey, Map<ArtifactLocation, String>> readPackageManifestFiles(Project project, BlazeContext context, ArtifactLocationDecoder decoder, Map<TargetKey, ArtifactLocation> javaPackageManifests, ListeningExecutorService executorService) {
    Map<OutputArtifact, TargetKey> fileToLabelMap = Maps.newHashMap();
    for (Map.Entry<TargetKey, ArtifactLocation> entry : javaPackageManifests.entrySet()) {
        TargetKey key = entry.getKey();
        BlazeArtifact artifact = decoder.resolveOutput(entry.getValue());
        if (artifact instanceof OutputArtifact) {
            fileToLabelMap.put((OutputArtifact) artifact, key);
        }
    }
    ArtifactsDiff diff;
    try {
        diff = ArtifactsDiff.diffArtifacts(artifactState, fileToLabelMap.keySet());
        artifactState = diff.getNewState();
    } catch (InterruptedException e) {
        throw new ProcessCanceledException(e);
    } catch (ExecutionException e) {
        context.setHasError();
        IssueOutput.error("Updating package manifest files failed: " + e).submit(context);
        throw new AssertionError("Unhandled exception", e);
    }
    // Find all not cached {@link RemoteOutputArtifact} and download them before parsing manifest
    // file
    ImmutableList.Builder<RemoteOutputArtifact> toDownload = ImmutableList.builder();
    for (OutputArtifact outputArtifact : diff.getUpdatedOutputs()) {
        if (!(outputArtifact instanceof RemoteOutputArtifact)) {
            continue;
        }
        if (findArtifactInCache(project, outputArtifact) != null) {
            continue;
        }
        toDownload.add((RemoteOutputArtifact) outputArtifact);
    }
    ListenableFuture<?> fetchRemoteArtifactFuture = RemoteArtifactPrefetcher.getInstance().downloadArtifacts(project.getName(), toDownload.build());
    ListenableFuture<?> fetchFuture = PrefetchService.getInstance().prefetchFiles(BlazeArtifact.getLocalFiles(diff.getUpdatedOutputs()), true, false);
    if (!FutureUtil.waitForFuture(context, Futures.allAsList(fetchRemoteArtifactFuture, fetchFuture)).timed("FetchPackageManifests", EventType.Prefetching).withProgressMessage("Reading package manifests...").run().success()) {
        return null;
    }
    List<ListenableFuture<Void>> futures = Lists.newArrayList();
    for (OutputArtifact file : diff.getUpdatedOutputs()) {
        futures.add(executorService.submit(() -> {
            Map<ArtifactLocation, String> manifest = parseManifestFile(project, file);
            manifestMap.put(fileToLabelMap.get(file), manifest);
            return null;
        }));
    }
    for (ArtifactState file : diff.getRemovedOutputs()) {
        TargetKey key = this.fileToLabelMap.get(file);
        if (key != null) {
            manifestMap.remove(key);
        }
    }
    this.fileToLabelMap = fileToLabelMap.entrySet().stream().filter(e -> diff.getNewState().containsKey(e.getKey().getKey())).collect(toImmutableMap(e -> e.getKey().toArtifactState(), Map.Entry::getValue));
    try {
        Futures.allAsList(futures).get();
    } catch (ExecutionException | InterruptedException e) {
        logger.error(e);
        throw new IllegalStateException("Could not read sources");
    }
    return manifestMap;
}
Also used : ArtifactsDiff(com.google.idea.blaze.base.filecache.ArtifactsDiff) ImmutableList(com.google.common.collect.ImmutableList) ArtifactState(com.google.idea.blaze.base.filecache.ArtifactState) BlazeArtifact(com.google.idea.blaze.base.command.buildresult.BlazeArtifact) RemoteOutputArtifact(com.google.idea.blaze.base.command.buildresult.RemoteOutputArtifact) ArtifactLocation(com.google.idea.blaze.base.ideinfo.ArtifactLocation) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) TargetKey(com.google.idea.blaze.base.ideinfo.TargetKey) OutputArtifact(com.google.idea.blaze.base.command.buildresult.OutputArtifact) RemoteOutputArtifact(com.google.idea.blaze.base.command.buildresult.RemoteOutputArtifact) ExecutionException(java.util.concurrent.ExecutionException) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) ProcessCanceledException(com.intellij.openapi.progress.ProcessCanceledException)

Example 4 with ArtifactState

use of com.google.idea.blaze.base.filecache.ArtifactState in project intellij by bazelbuild.

the class EmptyJarTracker method fromProto.

public static EmptyJarTracker fromProto(ProjectData.EmptyJarTracker proto) {
    if (proto.getEntriesCount() == 0) {
        return EmptyJarTracker.builder().build();
    }
    Builder emptyJarTrackerBuilder = builder();
    for (ProjectData.EmptyJarTracker.Entry entry : proto.getEntriesList()) {
        ArtifactState artifactState = ArtifactStateProtoConverter.fromProto(entry.getArtifact());
        if (artifactState == null) {
            continue;
        }
        emptyJarTrackerBuilder.addEntry(artifactState, entry.getIsEmpty());
    }
    return emptyJarTrackerBuilder.build();
}
Also used : ArtifactState(com.google.idea.blaze.base.filecache.ArtifactState)

Example 5 with ArtifactState

use of com.google.idea.blaze.base.filecache.ArtifactState in project intellij by bazelbuild.

the class EmptyLibrary method doRemoveEmptyLibraries.

private static ImmutableMap<LibraryKey, BlazeJarLibrary> doRemoveEmptyLibraries(Project project, BlazeContext context, ArtifactLocationDecoder locationDecoder, Map<LibraryKey, BlazeJarLibrary> allLibraries, EmptyJarTracker oldProjectData, BlazeJavaImportResult.Builder importResultBuilder) {
    long startTime = System.currentTimeMillis();
    Set<OutputArtifact> currentOutputArtifacts = new HashSet<>();
    Map<LibraryKey, ArtifactState> libraryKeyToArtifactState = new HashMap<>();
    // `OutputArtifact` does not have an associated `ArtifactState`
    for (Map.Entry<LibraryKey, BlazeJarLibrary> entry : allLibraries.entrySet()) {
        ArtifactLocation libraryJar = entry.getValue().libraryArtifact.jarForIntellijLibrary();
        BlazeArtifact libraryArtifact = locationDecoder.resolveOutput(libraryJar);
        if (libraryArtifact instanceof OutputArtifact) {
            ArtifactState libraryArtifactState = ((OutputArtifact) libraryArtifact).toArtifactState();
            libraryKeyToArtifactState.put(entry.getKey(), libraryArtifactState);
            currentOutputArtifacts.add((OutputArtifact) libraryArtifact);
        }
    }
    // Update emptyJarTracker by reevaluating any artifact that might have changed since last sync
    EmptyJarTracker emptyJarTracker = getUpdatedEmptyJarTracker(project, context, currentOutputArtifacts, oldProjectData);
    // Put non-empty artifacts in `result`
    Map<LibraryKey, BlazeJarLibrary> result = new LinkedHashMap<>();
    for (Map.Entry<LibraryKey, BlazeJarLibrary> entry : allLibraries.entrySet()) {
        ArtifactState libraryArtifactState = libraryKeyToArtifactState.get(entry.getKey());
        if (libraryArtifactState == null || !emptyJarTracker.isKnownEmpty(libraryArtifactState)) {
            result.put(entry.getKey(), entry.getValue());
        }
    }
    context.output(PrintOutput.log(String.format("Filtered %d JARs, in %dms", allLibraries.size() - result.size(), System.currentTimeMillis() - startTime)));
    importResultBuilder.setEmptyJarTracker(emptyJarTracker);
    return ImmutableMap.copyOf(result);
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArtifactState(com.google.idea.blaze.base.filecache.ArtifactState) BlazeArtifact(com.google.idea.blaze.base.command.buildresult.BlazeArtifact) LinkedHashMap(java.util.LinkedHashMap) BlazeJarLibrary(com.google.idea.blaze.java.sync.model.BlazeJarLibrary) LibraryKey(com.google.idea.blaze.base.model.LibraryKey) ArtifactLocation(com.google.idea.blaze.base.ideinfo.ArtifactLocation) OutputArtifact(com.google.idea.blaze.base.command.buildresult.OutputArtifact) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashSet(java.util.HashSet)

Aggregations

ArtifactState (com.google.idea.blaze.base.filecache.ArtifactState)8 ImmutableMap (com.google.common.collect.ImmutableMap)4 OutputArtifact (com.google.idea.blaze.base.command.buildresult.OutputArtifact)4 TargetKey (com.google.idea.blaze.base.ideinfo.TargetKey)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ExecutionException (java.util.concurrent.ExecutionException)3 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)2 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)2 ProjectData (com.google.devtools.intellij.model.ProjectData)2 LocalFileOrOutputArtifact (com.google.devtools.intellij.model.ProjectData.LocalFileOrOutputArtifact)2 BlazeArtifact (com.google.idea.blaze.base.command.buildresult.BlazeArtifact)2 ArtifactsDiff (com.google.idea.blaze.base.filecache.ArtifactsDiff)2 ArtifactLocation (com.google.idea.blaze.base.ideinfo.ArtifactLocation)2 HashSet (java.util.HashSet)2 Nullable (javax.annotation.Nullable)2 AutoValue (com.google.auto.value.AutoValue)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)1