/* * Copyright 2014-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.apple; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.SourceWithFlags; import com.facebook.buck.util.immutables.BuckStyleImmutable; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import java.nio.file.Path; import java.util.Collection; import java.util.List; import java.util.Optional; import org.immutables.value.Value; @Value.Immutable @BuckStyleImmutable abstract class AbstractGroupedSource { /** The type of grouped source entry this object represents. */ public enum Type { /** A single {@link SourceWithFlags}. */ SOURCE_WITH_FLAGS, /** A single {@link SourcePath} that shouldn't be included in the build phase. */ IGNORED_SOURCE, /** A single {@link SourcePath} representing a public header file. */ PUBLIC_HEADER, /** A single {@link SourcePath} representing a private header file. */ PRIVATE_HEADER, /** A source group (group name and one or more GroupedSource objects). */ SOURCE_GROUP, } @Value.Parameter protected abstract Type getType(); @Value.Parameter protected abstract Optional<SourceWithFlags> getSourceWithFlags(); @Value.Parameter protected abstract Optional<SourcePath> getSourcePath(); @Value.Parameter protected abstract Optional<String> getSourceGroupName(); @Value.Parameter protected abstract Optional<Path> getSourceGroupPathRelativeToTarget(); @Value.Parameter protected abstract Optional<List<GroupedSource>> getSourceGroup(); @Value.Check protected void check() { switch (getType()) { case SOURCE_WITH_FLAGS: Preconditions.checkArgument(getSourceWithFlags().isPresent()); Preconditions.checkArgument(!getSourcePath().isPresent()); Preconditions.checkArgument(!getSourceGroupName().isPresent()); Preconditions.checkArgument(!getSourceGroupPathRelativeToTarget().isPresent()); Preconditions.checkArgument(!getSourceGroup().isPresent()); break; case IGNORED_SOURCE: case PUBLIC_HEADER: case PRIVATE_HEADER: Preconditions.checkArgument(!getSourceWithFlags().isPresent()); Preconditions.checkArgument(getSourcePath().isPresent()); Preconditions.checkArgument(!getSourceGroupName().isPresent()); Preconditions.checkArgument(!getSourceGroupPathRelativeToTarget().isPresent()); Preconditions.checkArgument(!getSourceGroup().isPresent()); break; case SOURCE_GROUP: Preconditions.checkArgument(!getSourceWithFlags().isPresent()); Preconditions.checkArgument(!getSourcePath().isPresent()); Preconditions.checkArgument(getSourceGroupName().isPresent()); Preconditions.checkArgument(getSourceGroupPathRelativeToTarget().isPresent()); Preconditions.checkArgument(getSourceGroup().isPresent()); break; default: throw new RuntimeException("Unhandled type: " + getType()); } } public String getName(Function<SourcePath, Path> pathResolver) { SourcePath sourcePath; switch (getType()) { case SOURCE_WITH_FLAGS: sourcePath = getSourceWithFlags().get().getSourcePath(); return Preconditions.checkNotNull(pathResolver.apply(sourcePath)).getFileName().toString(); case IGNORED_SOURCE: sourcePath = getSourcePath().get(); return Preconditions.checkNotNull(pathResolver.apply(sourcePath)).getFileName().toString(); case PUBLIC_HEADER: case PRIVATE_HEADER: sourcePath = getSourcePath().get(); return Preconditions.checkNotNull(pathResolver.apply(sourcePath)).getFileName().toString(); case SOURCE_GROUP: return getSourceGroupName().get(); default: throw new RuntimeException("Unhandled type: " + getType()); } } /** Creates a {@link GroupedSource} given a {@link SourceWithFlags}. */ public static GroupedSource ofSourceWithFlags(SourceWithFlags sourceWithFlags) { return GroupedSource.of( Type.SOURCE_WITH_FLAGS, Optional.of(sourceWithFlags), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); } /** * Creates a {@link GroupedSource} given a {@link SourcePath} representing a file that should not * be included in sources. */ public static GroupedSource ofIgnoredSource(SourcePath sourcePath) { return GroupedSource.of( Type.IGNORED_SOURCE, Optional.empty(), Optional.of(sourcePath), Optional.empty(), Optional.empty(), Optional.empty()); } /** * Creates a {@link GroupedSource} given a {@link SourcePath} representing a public header file. */ public static GroupedSource ofPublicHeader(SourcePath headerPath) { return GroupedSource.of( Type.PUBLIC_HEADER, Optional.empty(), Optional.of(headerPath), Optional.empty(), Optional.empty(), Optional.empty()); } /** * Creates a {@link GroupedSource} given a {@link SourcePath} representing a private header file. */ public static GroupedSource ofPrivateHeader(SourcePath headerPath) { return GroupedSource.of( Type.PRIVATE_HEADER, Optional.empty(), Optional.of(headerPath), Optional.empty(), Optional.empty(), Optional.empty()); } /** Creates a {@link GroupedSource} given a source group name and a list of GroupedSources. */ public static GroupedSource ofSourceGroup( String sourceGroupName, Path sourceGroupPathRelativeToTarget, Collection<GroupedSource> sourceGroup) { return GroupedSource.of( Type.SOURCE_GROUP, Optional.empty(), Optional.empty(), Optional.of(sourceGroupName), Optional.of(sourceGroupPathRelativeToTarget), Optional.of((List<GroupedSource>) ImmutableList.copyOf(sourceGroup))); } public interface Visitor { void visitSourceWithFlags(SourceWithFlags sourceWithFlags); void visitIgnoredSource(SourcePath source); void visitPublicHeader(SourcePath publicHeader); void visitPrivateHeader(SourcePath privateHeader); void visitSourceGroup( String sourceGroupName, Path sourceGroupPathRelativeToTarget, List<GroupedSource> sourceGroup); } public void visit(Visitor visitor) { switch (getType()) { case SOURCE_WITH_FLAGS: visitor.visitSourceWithFlags(getSourceWithFlags().get()); break; case IGNORED_SOURCE: visitor.visitIgnoredSource(getSourcePath().get()); break; case PUBLIC_HEADER: visitor.visitPublicHeader(getSourcePath().get()); break; case PRIVATE_HEADER: visitor.visitPrivateHeader(getSourcePath().get()); break; case SOURCE_GROUP: visitor.visitSourceGroup( getSourceGroupName().get(), getSourceGroupPathRelativeToTarget().get(), getSourceGroup().get()); } } }