blob: e35e9e480733415766a8de3e94c1ed8ed8947222 [file] [log] [blame]
// Copyright 2014 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.query2.engine;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import java.util.Collection;
import java.util.concurrent.ForkJoinPool;
/**
* Base class for expressions in the Blaze query language, revision 2.
*
* <p>All queries return a subgraph of the dependency graph, represented
* as a set of target nodes.
*
* <p>All queries must ensure that sufficient graph edges are created in the
* QueryEnvironment so that all nodes in the result are correctly ordered
* according to the type of query. For example, "deps" queries require that
* all the nodes in the transitive closure of its argument set are correctly
* ordered w.r.t. each other; "somepath" queries require that the order of the
* nodes on the resulting path are correctly ordered; algebraic set operations
* such as intersect and union are inherently unordered.
*
* <h2>Package overview</h2>
*
* <p>This package consists of two basic class hierarchies. The first, {@code
* QueryExpression}, is the set of different query expressions in the language,
* and the {@link #eval} method of each defines the semantics. The result of
* evaluating a query is set of Blaze {@code Target}s (a file or rule). The
* set may be interpreted as either a set or as nodes of a DAG, depending on
* the context.
*
* <p>The second hierarchy is {@code OutputFormatter}. Its subclasses define
* different ways of printing out the result of a query. Each accepts a {@code
* Digraph} of {@code Target}s, and an output stream.
*/
@ThreadSafe
public abstract class QueryExpression {
/**
* Scan and parse the specified query expression.
*/
public static QueryExpression parse(String query, QueryEnvironment<?> env)
throws QueryException {
return QueryParser.parse(query, env);
}
protected QueryExpression() {}
/**
* Evaluates this query in the specified environment, and notifies the callback with a result.
* Note that it is allowed to notify the callback with partial results instead of just one final
* result.
*
* <p>Failures resulting from evaluation of an ill-formed query cause
* QueryException to be thrown.
*
* <p>The reporting of failures arising from errors in BUILD files depends on
* the --keep_going flag. If enabled (the default), then QueryException is
* thrown. If disabled, evaluation will stumble on to produce a (possibly
* inaccurate) result, but a result nonetheless.
*/
public final <T> void eval(
QueryEnvironment<T> env,
VariableContext<T> context,
Callback<T> callback) throws QueryException, InterruptedException {
env.getEvalListener().onEval(this, env, context, callback);
evalImpl(env, context, callback);
}
protected abstract <T> void evalImpl(
QueryEnvironment<T> env,
VariableContext<T> context,
Callback<T> callback) throws QueryException, InterruptedException;
/**
* Evaluates this query in the specified environment, as in
* {@link #eval(QueryEnvironment, VariableContext, Callback)}, using {@code forkJoinPool} to
* achieve parallelism.
*
* <p>The caller must ensure that {@code env} is thread safe.
*/
@ThreadSafe
public final <T> void parEval(
QueryEnvironment<T> env,
VariableContext<T> context,
ThreadSafeCallback<T> callback,
ForkJoinPool forkJoinPool)
throws QueryException, InterruptedException {
env.getEvalListener().onParEval(this, env, context, callback, forkJoinPool);
parEvalImpl(env, context, callback, forkJoinPool);
}
protected <T> void parEvalImpl(
QueryEnvironment<T> env,
VariableContext<T> context,
ThreadSafeCallback<T> callback,
ForkJoinPool forkJoinPool)
throws QueryException, InterruptedException {
evalImpl(env, context, callback);
}
/**
* Collects all target patterns that are referenced anywhere within this query expression and adds
* them to the given collection, which must be mutable.
*/
public abstract void collectTargetPatterns(Collection<String> literals);
/* Implementations should just be {@code return mapper.map(this)}. */
public abstract QueryExpression getMapped(QueryExpressionMapper mapper);
/**
* Returns this query expression pretty-printed.
*/
@Override
public abstract String toString();
}