| // 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(); |
| } |