/*
* Copyright 2016-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.cxx;
import com.facebook.buck.util.immutables.BuckStyleImmutable;
import com.facebook.buck.util.immutables.BuckStyleTuple;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import org.immutables.value.Value;
/**
* Tracks flags passed to the preprocessor or compiler.
*
* <p>Flags derived from the "platform" are differentiated from flags derived from the "rule" to
* allow for rule flags to override platform flags. This is particularly important when the platform
* and rule flags from different sources are merged together.
*
* <p>Users should use the API in this class instead of the concrete implementations.
*/
public abstract class CxxToolFlags {
private static final CxxToolFlags EMPTY_FLAGS = CxxToolFlags.explicitBuilder().build();
/** Flags that precede flags from {@code #getRuleFlags()}. */
public abstract Iterable<String> getPlatformFlags();
/** Flags that succeed flags from {@code #getPlatformFlags()}. */
public abstract Iterable<String> getRuleFlags();
/** Returns all flags in the appropriate order. */
public final Iterable<String> getAllFlags() {
return Iterables.concat(getPlatformFlags(), getRuleFlags());
}
/** Returns a builder for explicitly specifying the flags. */
public static ExplicitCxxToolFlags.Builder explicitBuilder() {
return ExplicitCxxToolFlags.builder();
}
/** Returns the empty lists of flags. */
public static CxxToolFlags of() {
return EMPTY_FLAGS;
}
/** Directly construct an instance from the given members. */
public static CxxToolFlags copyOf(Iterable<String> platformFlags, Iterable<String> ruleFlags) {
return ExplicitCxxToolFlags.of(platformFlags, ruleFlags);
}
/** Concatenate multiple flags in a pairwise manner. */
public static CxxToolFlags concat(CxxToolFlags... parts) {
Iterable<String> platformFlags = ImmutableList.of();
Iterable<String> ruleFlags = ImmutableList.of();
for (CxxToolFlags part : parts) {
platformFlags = Iterables.concat(platformFlags, part.getPlatformFlags());
ruleFlags = Iterables.concat(ruleFlags, part.getRuleFlags());
}
return IterableCxxToolFlags.of(platformFlags, ruleFlags);
}
}
interface CxxToolFlagsBuilder {
CxxToolFlags build();
}
/** {@code CxxToolFlags} implementation where the flags are stored explicitly as lists. */
@Value.Immutable
@BuckStyleImmutable
abstract class AbstractExplicitCxxToolFlags extends CxxToolFlags {
public abstract static class Builder implements CxxToolFlagsBuilder {}
@Override
@Value.Parameter
public abstract ImmutableList<String> getPlatformFlags();
@Override
@Value.Parameter
public abstract ImmutableList<String> getRuleFlags();
public static void addCxxToolFlags(ExplicitCxxToolFlags.Builder builder, CxxToolFlags flags) {
builder.addAllPlatformFlags(flags.getPlatformFlags());
builder.addAllRuleFlags(flags.getRuleFlags());
}
}
/**
* {@code CxxToolFlags} implementation where the flags are stored as composed Iterables.
*
* <p>This improves sharing and reduce copying and memory pressure.
*/
@Value.Immutable
@BuckStyleTuple
abstract class AbstractIterableCxxToolFlags extends CxxToolFlags {
@Override
public abstract Iterable<String> getPlatformFlags();
@Override
public abstract Iterable<String> getRuleFlags();
}