/* * Copyright 2015-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.rules.coercer; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.BuildTargetPattern; import com.facebook.buck.parser.BuildTargetPatternParser; import com.facebook.buck.rules.CellPathResolver; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.SourcePathResolver; import com.facebook.buck.util.immutables.BuckStyleImmutable; import com.facebook.buck.versions.TargetNodeTranslator; import com.facebook.buck.versions.TargetTranslatable; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedSet; import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import org.immutables.value.Value; @Value.Immutable @BuckStyleImmutable abstract class AbstractSourceList implements TargetTranslatable<SourceList> { public static final SourceList EMPTY = SourceList.ofUnnamedSources(ImmutableSortedSet.of()); public enum Type { UNNAMED, NAMED, } @Value.Parameter public abstract Type getType(); @Value.Parameter public abstract Optional<ImmutableSortedSet<SourcePath>> getUnnamedSources(); @Value.Parameter public abstract Optional<ImmutableSortedMap<String, SourcePath>> getNamedSources(); @Value.Check protected void check() { switch (getType()) { case UNNAMED: Preconditions.checkArgument(getUnnamedSources().isPresent()); Preconditions.checkArgument(!getNamedSources().isPresent()); break; case NAMED: Preconditions.checkArgument(!getUnnamedSources().isPresent()); Preconditions.checkArgument(getNamedSources().isPresent()); break; } } public static SourceList ofUnnamedSources(ImmutableSortedSet<SourcePath> unnamedSources) { return SourceList.of(Type.UNNAMED, Optional.of(unnamedSources), Optional.empty()); } public static SourceList ofNamedSources(ImmutableSortedMap<String, SourcePath> namedSources) { return SourceList.of(Type.NAMED, Optional.empty(), Optional.of(namedSources)); } public boolean isEmpty() { switch (getType()) { case UNNAMED: return getUnnamedSources().get().isEmpty(); case NAMED: return getNamedSources().get().isEmpty(); default: throw new IllegalStateException("unexpected type: " + getType()); } } public ImmutableMap<String, SourcePath> toNameMap( BuildTarget buildTarget, SourcePathResolver pathResolver, String parameterName, Predicate<SourcePath> filter, Function<SourcePath, SourcePath> transform) { ImmutableMap.Builder<String, SourcePath> sources = ImmutableMap.builder(); switch (getType()) { case NAMED: for (Map.Entry<String, SourcePath> ent : getNamedSources().get().entrySet()) { if (filter.test(ent.getValue())) { sources.put(ent.getKey(), transform.apply(ent.getValue())); } } break; case UNNAMED: pathResolver .getSourcePathNames( buildTarget, parameterName, getUnnamedSources().get(), filter, transform) .forEach((name, path) -> sources.put(name, transform.apply(path))); break; } return sources.build(); } public ImmutableMap<String, SourcePath> toNameMap( BuildTarget buildTarget, SourcePathResolver pathResolver, String parameterName) { return toNameMap(buildTarget, pathResolver, parameterName, x -> true, x -> x); } public ImmutableList<SourcePath> getPaths() { ImmutableList.Builder<SourcePath> sources = ImmutableList.builder(); switch (getType()) { case NAMED: sources.addAll(getNamedSources().get().values()); break; case UNNAMED: sources.addAll(getUnnamedSources().get()); break; } return sources.build(); } @Override public Optional<SourceList> translateTargets( CellPathResolver cellPathResolver, BuildTargetPatternParser<BuildTargetPattern> pattern, TargetNodeTranslator translator) { Optional<Optional<ImmutableSortedMap<String, SourcePath>>> namedSources = translator.translate(cellPathResolver, pattern, getNamedSources()); Optional<Optional<ImmutableSortedSet<SourcePath>>> unNamedSources = translator.translate(cellPathResolver, pattern, getUnnamedSources()); if (!namedSources.isPresent() && !unNamedSources.isPresent()) { return Optional.empty(); } SourceList.Builder builder = SourceList.builder(); builder.setType(getType()); builder.setNamedSources(namedSources.orElse(getNamedSources())); builder.setUnnamedSources(unNamedSources.orElse(getUnnamedSources())); return Optional.of(builder.build()); } }