com.google.devtools.build.lib.analysis.config.transitions.ComposingSplitTransition.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.build.lib.analysis.config.transitions.ComposingSplitTransition.java

Source

// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.lib.analysis.config.transitions;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.util.List;
import java.util.Objects;

/**
 * A configuration transition that composes two other transitions in an ordered sequence.
 *
 * <p>Example:
 *
 * <pre>
 *   transition1: { someSetting = $oldVal + " foo" }
 *   transition2: { someSetting = $oldVal + " bar" }
 *   ComposingSplitTransition(transition1, transition2): { someSetting = $oldVal + " foo bar" }
 * </pre>
 *
 * <p>Child transitions can be {@link SplitTransition}s, {@link PatchTransition}s, or any
 * combination thereof. We implement this class as a {@link SplitTransition} since that abstraction
 * captures all possible combinations.
 */
@AutoCodec
public class ComposingSplitTransition implements SplitTransition {
    private ConfigurationTransition transition1;
    private ConfigurationTransition transition2;

    @Override
    public String getName() {
        return "(" + transition1.getName() + " + " + transition2.getName() + ")";
    }

    /**
     * Creates a {@link ComposingSplitTransition} that applies the sequence: {@code fromOptions ->
     * transition1 -> transition2 -> toOptions }.
     *
     * <p>Note that it's possible to create silly transitions with this constructor (e.g., if one or
     * both of the transitions is NoTransition). Use composeTransitions instead, which checks for
     * these states and avoids instantiation appropriately.
     *
     * @see TransitionResolver#composeTransitions
     */
    @AutoCodec.Instantiator
    public ComposingSplitTransition(ConfigurationTransition transition1, ConfigurationTransition transition2) {
        this.transition1 = transition1;
        this.transition2 = transition2;
    }

    @Override
    public List<BuildOptions> split(BuildOptions buildOptions) {
        ImmutableList.Builder<BuildOptions> toOptions = ImmutableList.builder();
        for (BuildOptions transition1Options : transition1.apply(buildOptions)) {
            toOptions.addAll(transition2.apply(transition1Options));
        }
        return toOptions.build();
    }

    @Override
    public int hashCode() {
        return Objects.hash(transition1, transition2);
    }

    @Override
    public boolean equals(Object other) {
        return other instanceof ComposingSplitTransition
                && ((ComposingSplitTransition) other).transition1.equals(this.transition1)
                && ((ComposingSplitTransition) other).transition2.equals(this.transition2);
    }

    /**
     * Returns whether this transition contains only patches (and is thus suitable as a delegate
     * for {@link ComposingPatchTransition}).
     */
    public boolean isPatchOnly() {
        return transition1 instanceof PatchTransition && transition2 instanceof PatchTransition;
    }

    /**
     * Allows this transition to be used in patch-only contexts if it contains only
     * {@link PatchTransition}s.
     *
     * <p>Can only be called if {@link #isPatchOnly()} returns true.
     */
    public ComposingPatchTransition asPatch() {
        return new ComposingPatchTransition(this);
    }
}