diff --git a/.idx/.gitignore b/.idx/.gitignore new file mode 100644 index 000000000..96be05fb6 --- /dev/null +++ b/.idx/.gitignore @@ -0,0 +1,2 @@ + +gc/ diff --git a/.idx/dev.nix b/.idx/dev.nix new file mode 100644 index 000000000..90de3c080 --- /dev/null +++ b/.idx/dev.nix @@ -0,0 +1,17 @@ +{ pkgs, ... }: { + + # Which nixpkgs channel to use. + channel = "stable-23.11"; # or "unstable" + + # Use https://search.nixos.org/packages to find packages + packages = [ + pkgs.jdk11 # Or jdk8, jdk17, etc. - match your project's requirements + pkgs.maven + pkgs.kotlin + ]; + + # Sets environment variables in the workspace + env = { + SOME_ENV_VAR = "hello"; + }; +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..7b016a89f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.compile.nullAnalysis.mode": "automatic" +} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b65dd279c..4f74815c0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,4 +89,4 @@ mvn com.coveo:fmt-maven-plugin:format [1]: https://cloud.google.com/docs/authentication/getting-started#creating_a_service_account [2]: https://maven.apache.org/settings.html#Active_Profiles -[3]: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md \ No newline at end of file +[3]: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md diff --git a/README.md b/README.md index 816c2e789..b0b3e92a3 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file: com.google.cloud libraries-bom - 26.39.0 + 26.31.0 pom import @@ -42,7 +42,7 @@ If you are using Maven without the BOM, add this to your dependencies: com.google.cloud google-cloud-firestore - 3.21.1 + 3.16.1 ``` @@ -57,13 +57,13 @@ implementation 'com.google.cloud:google-cloud-firestore' If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-firestore:3.21.1' +implementation 'com.google.cloud:google-cloud-firestore:3.21.3' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.21.1" +libraryDependencies += "com.google.cloud" % "google-cloud-firestore" % "3.21.3" ``` @@ -222,7 +222,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-firestore/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-firestore.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.21.1 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-firestore/3.21.3 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/google-cloud-firestore-admin/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreAdminStubSettings.java b/google-cloud-firestore-admin/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreAdminStubSettings.java index 6b445dcf5..fbcf2bc14 100644 --- a/google-cloud-firestore-admin/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreAdminStubSettings.java +++ b/google-cloud-firestore-admin/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreAdminStubSettings.java @@ -486,6 +486,15 @@ public FirestoreAdminStub createStub() throws IOException { "Transport not supported: %s", getTransportChannelProvider().getTransportName())); } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + /** Returns the default service name. */ @Override public String getServiceName() { @@ -1377,6 +1386,15 @@ public UnaryCallSettings.Builder restoreDatab return deleteBackupScheduleSettings; } + /** Returns the endpoint set by the user or the the service's default endpoint. */ + @Override + public String getEndpoint() { + if (super.getEndpoint() != null) { + return super.getEndpoint(); + } + return getDefaultEndpoint(); + } + @Override public FirestoreAdminStubSettings build() throws IOException { return new FirestoreAdminStubSettings(this); diff --git a/google-cloud-firestore/pom.xml b/google-cloud-firestore/pom.xml index 2cb088ef5..076938fd3 100644 --- a/google-cloud-firestore/pom.xml +++ b/google-cloud-firestore/pom.xml @@ -214,6 +214,42 @@ org.codehaus.mojo flatten-maven-plugin + + maven-assembly-plugin + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuery.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuery.java index 4e00e5f3c..25bbcc059 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuery.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuery.java @@ -17,6 +17,7 @@ package com.google.cloud.firestore; import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; import com.google.api.core.InternalExtensionOnly; import com.google.api.core.SettableApiFuture; import com.google.api.gax.rpc.ResponseObserver; @@ -24,6 +25,7 @@ import com.google.api.gax.rpc.StatusCode; import com.google.api.gax.rpc.StreamController; import com.google.cloud.Timestamp; +import com.google.cloud.firestore.pipeline.expressions.ExprWithAlias; import com.google.cloud.firestore.v1.FirestoreSettings; import com.google.common.collect.ImmutableMap; import com.google.firestore.v1.RunAggregationQueryRequest; @@ -65,6 +67,17 @@ public Query getQuery() { return query; } + @Nonnull + @BetaApi + public Pipeline pipeline() { + return getQuery() + .pipeline() + .aggregate( + this.aggregateFieldList.stream() + .map(PipelineUtils::toPipelineAggregatorTarget) + .toArray(ExprWithAlias[]::new)); + } + /** * Executes this query. * diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuerySnapshot.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuerySnapshot.java index ff7b99906..be98e61d2 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuerySnapshot.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/AggregateQuerySnapshot.java @@ -16,6 +16,7 @@ package com.google.cloud.firestore; +import com.google.api.core.InternalApi; import com.google.api.core.InternalExtensionOnly; import com.google.cloud.Timestamp; import com.google.firestore.v1.Value; @@ -189,4 +190,9 @@ public boolean equals(Object object) { public int hashCode() { return Objects.hash(query, data); } + + @InternalApi + Map getData() { + return data; + } } diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FieldPath.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FieldPath.java index e6939c445..c5b9a8173 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FieldPath.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FieldPath.java @@ -16,6 +16,7 @@ package com.google.cloud.firestore; +import com.google.api.core.InternalApi; import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -79,7 +80,8 @@ static boolean isDocumentId(String path) { } /** Returns a field path from a dot separated string. Does not support escaping. */ - static FieldPath fromDotSeparatedString(String field) { + @InternalApi + public static FieldPath fromDotSeparatedString(String field) { if (PROHIBITED_CHARACTERS.matcher(field).matches()) { throw new IllegalArgumentException("Use FieldPath.of() for field names containing '˜*/[]'."); } diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java index 5bbb1164a..7f5bc54b5 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Firestore.java @@ -66,6 +66,8 @@ public interface Firestore extends Service, AutoCloseable { */ CollectionGroup collectionGroup(@Nonnull String collectionId); + PipelineSource pipeline(); + /** * Executes the given updateFunction and then attempts to commit the changes applied within the * transaction. If any document read within the transaction has changed, the updateFunction will diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java index 82dfc5176..1290301e4 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreImpl.java @@ -18,6 +18,7 @@ import com.google.api.core.ApiClock; import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; import com.google.api.core.NanoClock; import com.google.api.core.SettableApiFuture; import com.google.api.gax.rpc.ApiStreamObserver; @@ -29,6 +30,8 @@ import com.google.api.gax.rpc.StreamController; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.Timestamp; +import com.google.cloud.firestore.Transaction.AsyncFunction; +import com.google.cloud.firestore.Transaction.Function; import com.google.cloud.firestore.spi.v1.FirestoreRpc; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -385,7 +388,14 @@ public CollectionGroup collectionGroup(@Nonnull final String collectionId) { @Nonnull @Override - public ApiFuture runTransaction(@Nonnull final Transaction.Function updateFunction) { + @BetaApi + public PipelineSource pipeline() { + return new PipelineSource(this); + } + + @Nonnull + @Override + public ApiFuture runTransaction(@Nonnull final Function updateFunction) { return runAsyncTransaction( new TransactionAsyncAdapter<>(updateFunction), TransactionOptions.create()); } @@ -393,22 +403,20 @@ public ApiFuture runTransaction(@Nonnull final Transaction.Function up @Nonnull @Override public ApiFuture runTransaction( - @Nonnull final Transaction.Function updateFunction, - @Nonnull TransactionOptions transactionOptions) { + @Nonnull final Function updateFunction, @Nonnull TransactionOptions transactionOptions) { return runAsyncTransaction(new TransactionAsyncAdapter<>(updateFunction), transactionOptions); } @Nonnull @Override - public ApiFuture runAsyncTransaction( - @Nonnull final Transaction.AsyncFunction updateFunction) { + public ApiFuture runAsyncTransaction(@Nonnull final AsyncFunction updateFunction) { return runAsyncTransaction(updateFunction, TransactionOptions.create()); } @Nonnull @Override public ApiFuture runAsyncTransaction( - @Nonnull final Transaction.AsyncFunction updateFunction, + @Nonnull final AsyncFunction updateFunction, @Nonnull TransactionOptions transactionOptions) { if (transactionOptions.getReadTime() != null) { @@ -519,10 +527,10 @@ public void shutdownNow() { closed = true; } - private static class TransactionAsyncAdapter implements Transaction.AsyncFunction { - private final Transaction.Function syncFunction; + private static class TransactionAsyncAdapter implements AsyncFunction { + private final Function syncFunction; - public TransactionAsyncAdapter(Transaction.Function syncFunction) { + public TransactionAsyncAdapter(Function syncFunction) { this.syncFunction = syncFunction; } diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Pipeline.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Pipeline.java new file mode 100644 index 000000000..bdbfbb747 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Pipeline.java @@ -0,0 +1,901 @@ +package com.google.cloud.firestore; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.rpc.ApiStreamObserver; +import com.google.api.gax.rpc.ResponseObserver; +import com.google.api.gax.rpc.StreamController; +import com.google.cloud.Timestamp; +import com.google.cloud.firestore.pipeline.expressions.Accumulator; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import com.google.cloud.firestore.pipeline.expressions.ExprWithAlias; +import com.google.cloud.firestore.pipeline.expressions.Field; +import com.google.cloud.firestore.pipeline.expressions.FilterCondition; +import com.google.cloud.firestore.pipeline.expressions.Function; +import com.google.cloud.firestore.pipeline.expressions.Ordering; +import com.google.cloud.firestore.pipeline.expressions.Selectable; +import com.google.cloud.firestore.pipeline.stages.AddFields; +import com.google.cloud.firestore.pipeline.stages.Aggregate; +import com.google.cloud.firestore.pipeline.stages.Collection; +import com.google.cloud.firestore.pipeline.stages.CollectionGroup; +import com.google.cloud.firestore.pipeline.stages.Database; +import com.google.cloud.firestore.pipeline.stages.Distinct; +import com.google.cloud.firestore.pipeline.stages.Documents; +import com.google.cloud.firestore.pipeline.stages.FindNearest; +import com.google.cloud.firestore.pipeline.stages.GenericStage; +import com.google.cloud.firestore.pipeline.stages.Limit; +import com.google.cloud.firestore.pipeline.stages.Offset; +import com.google.cloud.firestore.pipeline.stages.Select; +import com.google.cloud.firestore.pipeline.stages.Sort; +import com.google.cloud.firestore.pipeline.stages.Stage; +import com.google.cloud.firestore.pipeline.stages.StageUtils; +import com.google.cloud.firestore.pipeline.stages.Where; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; +import com.google.firestore.v1.StructuredPipeline; +import com.google.firestore.v1.Value; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Tracing; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * The Pipeline class provides a flexible and expressive framework for building complex data + * transformation and query pipelines for Firestore. + * + *

A pipeline takes data sources, such as Firestore collections or collection groups, and applies + * a series of stages that are chained together. Each stage takes the output from the previous stage + * (or the data source) and produces an output for the next stage (or as the final output of the + * pipeline). + * + *

Expressions from {@link com.google.cloud.firestore.pipeline.expressions} can be used within + * each stages to filter and transform data through the stage. + * + *

NOTE: The chained stages do not prescribe exactly how Firestore will execute the pipeline. + * Instead, Firestore only guarantees that the result is the same as if the chained stages were + * executed in order. + * + *

Usage Examples: + * + *

{@code
+ * Firestore firestore; // A valid firestore instance.
+ *
+ * // Example 1: Select specific fields and rename 'rating' to 'bookRating'
+ * List results1 = firestore.pipeline()
+ *     .collection("books")
+ *     .select("title", "author", Field.of("rating").as("bookRating"))
+ *     .execute()
+ *     .get();
+ *
+ * // Example 2: Filter documents where 'genre' is "Science Fiction" and 'published' is after 1950
+ * List results2 = firestore.pipeline()
+ *     .collection("books")
+ *     .where(and(eq("genre", "Science Fiction"), gt("published", 1950)))
+ *     .execute()
+ *     .get();
+ * // Same as above but using methods on expressions as opposed to static functions.
+ * results2 = firestore.pipeline()
+ *     .collection("books")
+ *     .where(and(Field.of("genre").eq("Science Fiction"), Field.of("published").gt(1950)))
+ *     .execute()
+ *     .get();
+ *
+ * // Example 3: Calculate the average rating of books published after 1980
+ * List results3 = firestore.pipeline()
+ *     .collection("books")
+ *     .where(gt("published", 1980))
+ *     .aggregate(avg("rating").as("averageRating"))
+ *     .execute()
+ *     .get();
+ * }
+ */ +@BetaApi +public final class Pipeline { + private static Logger logger = Logger.getLogger(Pipeline.class.getName()); + private final ImmutableList stages; + private final Firestore db; + + private Pipeline(Firestore db, List stages) { + this.db = db; + this.stages = ImmutableList.copyOf(stages); + } + + @InternalApi + Pipeline(Firestore db, Collection collection) { + this(db, Lists.newArrayList(collection)); + } + + @InternalApi + Pipeline(Firestore db, CollectionGroup group) { + this(db, Lists.newArrayList(group)); + } + + @InternalApi + Pipeline(Firestore firestore, Database db) { + this(firestore, Lists.newArrayList(db)); + } + + @InternalApi + Pipeline(Firestore db, Documents docs) { + this(db, Lists.newArrayList(docs)); + } + + /** + * Adds new fields to outputs from previous stages. + * + *

This stage allows you to compute values on-the-fly based on existing data from previous + * stages or constants. You can use this to create new fields or overwrite existing ones (if there + * is name overlaps). + * + *

The added fields are defined using {@link Selectable} expressions, which can be: + * + *

    + *
  • {@link Field}: References an existing document field. + *
  • {@link Function}: Performs a calculation using functions like `add`, `multiply` with + * assigned aliases using {@link + * com.google.cloud.firestore.pipeline.expressions.Expr#as(String)}. + *
+ * + *

Example: + * + *

{@code
+   * firestore.pipeline().collection("books")
+   *   .addFields(
+   *     Field.of("rating").as("bookRating"), // Rename 'rating' to 'bookRating'
+   *     add(5, Field.of("quantity")).as("totalCost")  // Calculate 'totalCost'
+   *   );
+   * }
+ * + * @param fields The fields to add to the documents, specified as {@link Selectable} expressions. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline addFields(Selectable... fields) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new AddFields(PipelineUtils.selectablesToMap(fields))) + .build()); + } + + /** + * Selects or creates a set of fields from the outputs of previous stages. + * + *

The selected fields are defined using {@link Selectable} expressions, which can be: + * + *

    + *
  • {@link Field}: References an existing document field. + *
  • {@link Function}: Represents the result of a function with an assigned alias name using + * {@link com.google.cloud.firestore.pipeline.expressions.Expr#as(String)} + *
+ * + *

If no selections are provided, the output of this stage is empty. Use {@link + * com.google.cloud.firestore.Pipeline#addFields(Selectable...)} instead if only additions are + * desired. + * + *

Example: + * + *

{@code
+   * firestore.pipeline().collection("books")
+   *   .select(
+   *     Field.of("name"),
+   *     Field.of("address").toUppercase().as("upperAddress"),
+   *   );
+   * }
+ * + * @param selections The fields to include in the output documents, specified as {@link + * Selectable} expressions. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline select(Selectable... selections) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new Select(PipelineUtils.selectablesToMap(selections))) + .build()); + } + + /** + * Selects a set of fields from the outputs of previous stages. + * + *

If no selections are provided, the output of this stage is empty. Use {@link + * com.google.cloud.firestore.Pipeline#addFields(Selectable...)} instead if only additions are + * desired. + * + *

Example: + * + *

{@code
+   * firestore.collection("books")
+   *   .select("name", "address");
+   *
+   * // The above is a shorthand of this:
+   * firestore.pipeline().collection("books")
+   *    .select(Field.of("name"), Field.of("address"));
+   * }
+ * + * @param fields The name of the fields to include in the output documents. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline select(String... fields) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new Select(PipelineUtils.fieldNamesToMap(fields))) + .build()); + } + + /** + * Filters the documents from previous stages to only include those matching the specified {@link + * FilterCondition}. + * + *

This stage allows you to apply conditions to the data, similar to a "WHERE" clause in SQL. + * You can filter documents based on their field values, using implementions of {@link + * FilterCondition}, typically including but not limited to: + * + *

    + *
  • field comparators: {@link Function#eq}, {@link Function#lt} (less than), {@link + * Function#gt} (greater than), etc. + *
  • logical operators: {@link Function#and}, {@link Function#or}, {@link Function#not}, etc. + *
  • advanced functions: {@link Function#regexMatch(String, String)}, {@link + * Function#arrayContains(Expr, Expr)}, etc. + *
+ * + *

Example: + * + *

{@code
+   * firestore.pipeline().collection("books")
+   *   .where(
+   *     and(
+   *         gt("rating", 4.0),   // Filter for ratings greater than 4.0
+   *         Field.of("genre").eq("Science Fiction") // Equivalent to gt("genre", "Science Fiction")
+   *     )
+   *   );
+   * }
+ * + * @param condition The {@link FilterCondition} to apply. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline where(FilterCondition condition) { + return new Pipeline( + this.db, ImmutableList.builder().addAll(stages).add(new Where(condition)).build()); + } + + /** + * Skips the first `offset` number of documents from the results of previous stages. + * + *

This stage is useful for implementing pagination in your pipelines, allowing you to retrieve + * results in chunks. It is typically used in conjunction with {@link #limit(int)} to control the + * size of each page. + * + *

Example: + * + *

{@code
+   * // Retrieve the second page of 20 results
+   * firestore.pipeline().collection("books")
+   *     .sort(Field.of("published").descending())
+   *     .offset(20)  // Skip the first 20 results
+   *     .limit(20);   // Take the next 20 results
+   * }
+ * + * @param offset The number of documents to skip. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline offset(int offset) { + return new Pipeline( + this.db, ImmutableList.builder().addAll(stages).add(new Offset(offset)).build()); + } + + /** + * Limits the maximum number of documents returned by previous stages to `limit`. + * + *

This stage is particularly useful when you want to retrieve a controlled subset of data from + * a potentially large result set. It's often used for: + * + *

    + *
  • **Pagination:** In combination with {@link #offset(int)} to retrieve specific pages of + * results. + *
  • **Limiting Data Retrieval:** To prevent excessive data transfer and improve performance, + * especially when dealing with large collections. + *
+ * + *

Example: + * + *

{@code
+   * // Limit the results to the top 10 highest-rated books
+   * firestore.pipeline().collection("books")
+   *     .sort(Field.of("rating").descending())
+   *     .limit(10);
+   * }
+ * + * @param limit The maximum number of documents to return. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline limit(int limit) { + return new Pipeline( + this.db, ImmutableList.builder().addAll(stages).add(new Limit(limit)).build()); + } + + /** + * Performs aggregation operations on the documents from previous stages. + * + *

This stage allows you to calculate aggregate values over a set of documents. You define the + * aggregations to perform using {@link ExprWithAlias} expressions which are typically results of + * calling {@link Expr#as(String)} on {@link Accumulator} instances. + * + *

Example: + * + *

{@code
+   * // Calculate the average rating and the total number of books
+   * firestore.pipeline().collection("books")
+   *     .aggregate(
+   *         Field.of("rating").avg().as("averageRating"),
+   *         countAll().as("totalBooks")
+   *     );
+   * }
+ * + * @param accumulators The {@link ExprWithAlias} expressions, each wrapping an {@link Accumulator} + * and provide a name for the accumulated results. + * @return A new Pipeline object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline aggregate(ExprWithAlias... accumulators) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(Aggregate.withAccumulators(accumulators)) + .build()); + } + + /** + * Performs optionally grouped aggregation operations on the documents from previous stages. + * + *

This stage allows you to calculate aggregate values over a set of documents, optionally + * grouped by one or more fields or functions. You can specify: + * + *

    + *
  • **Grouping Fields or Functions:** One or more fields or functions to group the documents + * by. For each distinct combination of values in these fields, a separate group is created. + * If no grouping fields are provided, a single group containing all documents is used. Not + * specifying groups is the same as putting the entire inputs into one group. + *
  • **Accumulators:** One or more accumulation operations to perform within each group. These + * are defined using {@link ExprWithAlias} expressions, which are typically created by + * calling {@link Expr#as(String)} on {@link Accumulator} instances. Each aggregation + * calculates a value (e.g., sum, average, count) based on the documents within its group. + *
+ * + *

Example: + * + *

{@code
+   * // Calculate the average rating for each genre.
+   * firestore.pipeline().collection("books")
+   *   .aggregate(
+   *     Aggregate
+   *       .withAccumulators(avg("rating").as("avg_rating"))
+   *       .withGroups("genre"));
+   * }
+ * + * @param aggregate An {@link Aggregate} object that specifies the grouping fields (if any) and + * the aggregation operations to perform. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline aggregate(Aggregate aggregate) { + return new Pipeline( + this.db, ImmutableList.builder().addAll(stages).add(aggregate).build()); + } + + /** + * Returns a set of distinct field values from the inputs to this stage. + * + *

This stage run through the results from previous stages to include only results with unique + * combinations of values for the specified fields and produce these fields as the output. + * + *

Example: + * + *

{@code
+   * // Get a list of unique genres.
+   * firestore.pipeline().collection("books")
+   *     .distinct("genre");
+   * }
+ * + * @param fields The fields to consider when determining distinct values. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline distinct(String... fields) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new Distinct(PipelineUtils.fieldNamesToMap(fields))) + .build()); + } + + /** + * Returns a set of distinct {@link Expr} values from the inputs to this stage. + * + *

This stage run through the results from previous stages to include only results with unique + * combinations of {@link Expr} values ({@link Field}, {@link Function}, etc). + * + *

The parameters to this stage are defined using {@link Selectable} expressions, which can be: + * + *

    + *
  • {@link Field}: References an existing document field. + *
  • {@link Function}: Represents the result of a function with an assigned alias name using + * {@link com.google.cloud.firestore.pipeline.expressions.Expr#as(String)} + *
+ * + *

Example: + * + *

{@code
+   * // Get a list of unique author names in uppercase and genre combinations.
+   * firestore.pipeline().collection("books")
+   *     .distinct(toUppercase(Field.of("author")).as("authorName"), Field.of("genre"))
+   *     .select("authorName");
+   * }
+ * + * @param selectables The {@link Selectable} expressions to consider when determining distinct + * value combinations. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline distinct(Selectable... selectables) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new Distinct(PipelineUtils.selectablesToMap(selectables))) + .build()); + } + + /** + * Performs vector distance (similarity) search with given parameters to the stage inputs. + * + *

This stage adds a "nearest neighbor search" capability to your pipelines. Given a field that + * stores vectors and a target vector, this stage will identify and return the inputs whose vector + * field is closest to the target vector, using the parameters specified in `options`. + * + *

Example: + * + *

{@code
+   * // Find books with similar "topicVectors" to the given targetVector
+   * firestore.pipeline().collection("books")
+   *     .findNearest("topicVectors", targetVector,
+   *        FindNearestOptions
+   *          .withLimitAndMeasure(10, DistanceMeasure.cosine())
+   *          .withOutputField("distance"));
+   * }
+ * + * @param fieldName The name of the field containing the vector data. This field should store + * {@link VectorValue}. + * @param vector The target vector to compare against. + * @param options Configuration options for the nearest neighbor search, such as the distance + * metric to use. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline findNearest( + String fieldName, double[] vector, FindNearest.FindNearestOptions options) { + return findNearest(Field.of(fieldName), vector, options); + } + + /** + * Performs vector distance (similarity) search with given parameters to the stage inputs. + * + *

This stage adds a "nearest neighbor search" capability to your pipelines. Given an + * expression that evaluates to a vector and a target vector, this stage will identify and return + * the inputs whose vector expression is closest to the target vector, using the parameters + * specified in `options`. + * + *

Example: + * + *

{@code
+   * // Find books with similar "topicVectors" to the given targetVector
+   * firestore.pipeline().collection("books")
+   *     .findNearest(Field.of("topicVectors"), targetVector,
+   *        FindNearestOptions
+   *          .withLimitAndMeasure(10, DistanceMeasure.cosine())
+   *          .withOutputField("distance"));
+   * }
+ * + * @param property The expression that evaluates to a vector value using the stage inputs. + * @param vector The target vector to compare against. + * @param options Configuration options for the nearest neighbor search, such as the distance + * metric to use. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline findNearest( + Expr property, double[] vector, FindNearest.FindNearestOptions options) { + // Implementation for findNearest (add the FindNearest stage if needed) + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add( + new FindNearest( + property, vector, options)) // Assuming FindNearest takes these arguments + .build()); + } + + /** + * Sorts the documents from previous stages based on one or more {@link Ordering} criteria. + * + *

This stage allows you to order the results of your pipeline. You can specify multiple {@link + * Ordering} instances to sort by multiple fields in ascending or descending order. If documents + * have the same value for a field used for sorting, the next specified ordering will be used. If + * all orderings result in equal comparison, the documents are considered equal, and the order is + * unspecified. + * + *

Example: + * + *

{@code
+   * // Sort books by rating in descending order, and then by title in ascending order for books
+   * // with the same rating, with density required and truncation disabled.
+   * firestore.pipeline().collection("books")
+   *     .sort(
+   *         Arrays.asList(Ordering.of("rating").descending(), Ordering.of("title")),
+   *         Sort.Density.REQUIRED,
+   *         Sort.Truncation.DISABLED,
+   *         10);
+   * }
+ * + * @param orders One or more {@link Ordering} instances specifying the sorting criteria. + * @param density Specifies the index density semantics. See {@link + * com.google.cloud.firestore.pipeline.stages.Sort.Density} for more information on density + * sorting. + * @param truncation Specifies the index truncation semantics. See {@link + * com.google.cloud.firestore.pipeline.stages.Sort.Truncation} for more information on + * truncation options. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline sort(List orders, Sort.Density density, Sort.Truncation truncation) { + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new Sort(orders, density, truncation)) + .build()); + } + + /** + * Sorts the documents from previous stages based on one or more {@link Ordering} criteria. + * + *

This stage allows you to order the results of your pipeline. You can specify multiple {@link + * Ordering} instances to sort by multiple fields in ascending or descending order. If documents + * have the same value for a field used for sorting, the next specified ordering will be used. If + * all orderings result in equal comparison, the documents are considered equal and the order is + * unspecified. + * + *

Example: + * + *

{@code
+   * // Sort books by rating in descending order, and then by title in ascending order for books with the same rating
+   * firestore.pipeline().collection("books")
+   *     .sort(
+   *         Ordering.of("rating").descending(),
+   *         Ordering.of("title")  // Ascending order is the default
+   *     );
+   * }
+ * + * @param orders One or more {@link Ordering} instances specifying the sorting criteria. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline sort(Ordering... orders) { + return sort(Arrays.asList(orders), Sort.Density.UNSPECIFIED, Sort.Truncation.UNSPECIFIED); + } + + /** + * Adds a generic stage to the pipeline. + * + *

This method provides a flexible way to extend the pipeline's functionality by adding custom + * stages. Each generic stage is defined by a unique `name` and a set of `params` that control its + * behavior. + * + *

Example (Assuming there is no "where" stage available in SDK): + * + *

{@code
+   * // Assume we don't have a built-in "where" stage
+   * Map whereParams = new HashMap<>();
+   * whereParams.put("condition", Field.of("published").lt(1900));
+   *
+   * firestore.pipeline().collection("books")
+   *     .genericStage("where", Lists.newArrayList(Field.of("published").lt(1900))) // Custom "where" stage
+   *     .select("title", "author");
+   * }
+ * + * @param name The unique name of the generic stage to add. + * @param params A map of parameters to configure the generic stage's behavior. + * @return A new {@code Pipeline} object with this stage appended to the stage list. + */ + @BetaApi + public Pipeline genericStage(String name, List params) { + // Implementation for genericStage (add the GenericStage if needed) + return new Pipeline( + this.db, + ImmutableList.builder() + .addAll(stages) + .add(new GenericStage(name, params)) // Assuming GenericStage takes a list of params + .build()); + } + + /** + * Executes this pipeline and returns a future to represent the asynchronous operation. + * + *

The returned {@link ApiFuture} can be used to track the progress of the pipeline execution + * and retrieve the results (or handle any errors) asynchronously. + * + *

The pipeline results are returned as a list of {@link PipelineResult} objects. Each {@link + * PipelineResult} typically represents a single key/value map that has passed through all the + * stages of the pipeline, however this might differ depends on the stages involved in the + * pipeline. For example: + * + *

    + *
  • If there are no stages or only transformation stages, each {@link PipelineResult} + * represents a single document. + *
  • If there is an aggregation, only a single {@link PipelineResult} is returned, + * representing the aggregated results over the entire dataset . + *
  • If there is an aggregation stage with grouping, each {@link PipelineResult} represents a + * distinct group and its associated aggregated values. + *
+ * + *

Example: + * + *

{@code
+   * ApiFuture> futureResults = firestore.pipeline().collection("books")
+   *     .where(gt("rating", 4.5))
+   *     .select("title", "author", "rating")
+   *     .execute();
+   * }
+ * + * @return An {@link ApiFuture} representing the asynchronous pipeline execution. + */ + @BetaApi + public ApiFuture> execute() { + if (db instanceof FirestoreImpl) { + FirestoreImpl firestoreImpl = (FirestoreImpl) db; + Value pipelineValue = toProto(); + ExecutePipelineRequest request = + ExecutePipelineRequest.newBuilder() + .setDatabase(firestoreImpl.getResourcePath().getDatabaseName().toString()) + .setStructuredPipeline( + StructuredPipeline.newBuilder() + .setPipeline(pipelineValue.getPipelineValue()) + .build()) + .build(); + + SettableApiFuture> futureResult = SettableApiFuture.create(); + + pipelineInternalStream( // Assuming you have this method + firestoreImpl, + request, + new PipelineResultObserver() { + final List results = new ArrayList<>(); + + @Override + public void onCompleted() { + futureResult.set(results); + } + + @Override + public void onNext(PipelineResult result) { + results.add(result); + } + + @Override + public void onError(Throwable t) { + futureResult.setException(t); + } + }); + + return futureResult; + } else { + // Handle unsupported Firestore types + throw new IllegalArgumentException("Unsupported Firestore type"); + } + } + + /** + * Executes this pipeline, providing results to the given {@link ApiStreamObserver} as they become + * available. + * + *

This method allows you to process pipeline results in a streaming fashion, rather than + * waiting for the entire pipeline execution to complete. The provided {@link ApiStreamObserver} + * will receive: + * + *

    + *
  • **onNext(PipelineResult):** Called for each {@link PipelineResult} produced by the + * pipeline. Each {@link PipelineResult} typically represents a single key/value map that + * has passed through all the stages. However, the exact structure might differ based on the + * stages involved in the pipeline (as described in {@link #execute()}). + *
  • **onError(Throwable):** Called if an error occurs during pipeline execution. + *
  • **onCompleted():** Called when the pipeline has finished processing all documents. + *
+ * + *

Example: + * + *

{@code
+   * firestore.pipeline().collection("books")
+   *     .where(gt("rating", 4.5))
+   *     .select("title", "author", "rating")
+   *     .execute(new ApiStreamObserver() {
+   *         @Override
+   *         public void onNext(PipelineResult result) {
+   *             // Process each result as it arrives
+   *             System.out.println(result.getData());
+   *         }
+   *
+   *         @Override
+   *         public void onError(Throwable t) {
+   *             // Handle errors during execution
+   *             t.printStackTrace();
+   *         }
+   *
+   *         @Override
+   *         public void onCompleted() {
+   *             System.out.println("Pipeline execution completed.");
+   *         }
+   *     });
+   * }
+ * + * @param observer The {@link ApiStreamObserver} to receive pipeline results and events. + */ + @BetaApi + public void execute(ApiStreamObserver observer) { + if (db instanceof FirestoreImpl) { + FirestoreImpl firestoreImpl = (FirestoreImpl) db; + Value pipelineValue = toProto(); + ExecutePipelineRequest request = + ExecutePipelineRequest.newBuilder() + .setDatabase(firestoreImpl.getResourcePath().getDatabaseName().toString()) + .setStructuredPipeline( + StructuredPipeline.newBuilder() + .setPipeline(pipelineValue.getPipelineValue()) + .build()) + .build(); + + pipelineInternalStream( + firestoreImpl, + request, + new PipelineResultObserver() { + @Override + public void onCompleted() { + observer.onCompleted(); + } + + @Override + public void onNext(PipelineResult result) { + observer.onNext(result); + } + + @Override + public void onError(Throwable t) { + observer.onError(t); + } + }); + } else { + // Handle unsupported Firestore types + throw new IllegalArgumentException("Unsupported Firestore type"); + } + } + + private Value toProto() { + return Value.newBuilder() + .setPipelineValue( + com.google.firestore.v1.Pipeline.newBuilder() + .addAllStages( + stages.stream() + .map(StageUtils::toStageProto) + .collect(Collectors.toList())) // Use the static method + ) + .build(); + } + + private void pipelineInternalStream( + FirestoreImpl rpcContext, + ExecutePipelineRequest request, + PipelineResultObserver resultObserver) { + ResponseObserver observer = + new ResponseObserver() { + Timestamp executionTime = null; + boolean firstResponse = false; + int numDocuments = 0; + boolean hasCompleted = false; + + @Override + public void onStart(StreamController controller) { + // No action needed in onStart + } + + @Override + public void onResponse(ExecutePipelineResponse response) { + if (!firstResponse) { + firstResponse = true; + Tracing.getTracer() + .getCurrentSpan() + .addAnnotation( + "Firestore.Query: First response"); // Assuming Tracing class exists + } + if (response.getResultsCount() > 0) { + numDocuments += response.getResultsCount(); + if (numDocuments % 100 == 0) { + Tracing.getTracer() + .getCurrentSpan() + .addAnnotation("Firestore.Query: Received 100 documents"); + } + for (Document doc : response.getResultsList()) { + resultObserver.onNext( + PipelineResult.fromDocument( + rpcContext, Timestamp.fromProto(response.getExecutionTime()), doc)); + } + } + + if (executionTime == null) { + executionTime = Timestamp.fromProto(response.getExecutionTime()); + } + } + + @Override + public void onError(Throwable throwable) { + Tracing.getTracer().getCurrentSpan().addAnnotation("Firestore.Query: Error"); + resultObserver.onError(throwable); + } + + @Override + public void onComplete() { + if (hasCompleted) { + return; + } + hasCompleted = true; + + Tracing.getTracer() + .getCurrentSpan() + .addAnnotation( + "Firestore.ExecutePipeline: Completed", + ImmutableMap.of( + "numDocuments", AttributeValue.longAttributeValue((long) numDocuments))); + resultObserver.onCompleted(executionTime); + } + }; + + logger.log(Level.INFO, "Sending pipeline request: " + request.getStructuredPipeline()); + + rpcContext.streamRequest(request, observer, rpcContext.getClient().executePipelineCallable()); + } +} + +@InternalExtensionOnly +abstract class PipelineResultObserver implements ApiStreamObserver { + private Timestamp executionTime; // Remove optional since Java doesn't have it + + public void onCompleted(Timestamp executionTime) { + this.executionTime = executionTime; + this.onCompleted(); + } + + public Timestamp getExecutionTime() { // Add getter for executionTime + return executionTime; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineResult.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineResult.java new file mode 100644 index 000000000..e99190b41 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineResult.java @@ -0,0 +1,448 @@ +/* + * Copyright 2017 Google LLC + * + * 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.cloud.firestore; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.Timestamp; +import com.google.common.base.Preconditions; +import com.google.firestore.v1.Document; +import com.google.firestore.v1.Value; +import com.google.firestore.v1.Write; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * A PipelineResult contains data read from a Firestore Pipeline. The data can be extracted with the + * {@link #getData()} or {@link #get(String)} methods. + * + *

If the PipelineResult represents a non-document result, getReference() will return a null + * value. + * + *

Subclassing Note: Firestore classes are not meant to be subclassed except for use in + * test mocks. Subclassing is not supported in production code and new SDK releases may break code + * that does so. + */ +@InternalExtensionOnly +@BetaApi +public final class PipelineResult { + + private final FirestoreRpcContext rpcContext; + @Nullable private final DocumentReference docRef; + @Nullable private final Map fields; + @Nonnull private final Timestamp executionTime; + @Nullable private final Timestamp updateTime; + @Nullable private final Timestamp createTime; + + PipelineResult( + FirestoreRpcContext rpcContext, + @Nullable DocumentReference docRef, + @Nullable Map fields, + @Nonnull Timestamp executionTime, + @Nullable Timestamp updateTime, + @Nullable Timestamp createTime) { // Elevated access level for mocking. + this.rpcContext = rpcContext; + this.docRef = docRef; + this.fields = fields; + this.executionTime = executionTime; + this.updateTime = updateTime; + this.createTime = createTime; + } + + /** + * Returns the ID of the document represented by this result. Returns null if this result is not + * corresponding to a Firestore document. + */ + @Nullable + @BetaApi + public String getId() { + return docRef.getId(); + } + + static PipelineResult fromDocument( + FirestoreRpcContext rpcContext, Timestamp readTime, Document document) { + return new PipelineResult( + rpcContext, + document.getName().isEmpty() + ? null + : new DocumentReference(rpcContext, ResourcePath.create(document.getName())), + document.getFieldsMap(), + readTime, + Timestamp.fromProto(document.getUpdateTime()), + Timestamp.fromProto(document.getCreateTime())); + } + + /** Returns the time at which the pipeline producing this result is executed. */ + @Nullable + @BetaApi + public Timestamp getExecutionTime() { + return executionTime; + } + + /** + * Returns the time at which this document was last updated. Returns null if this result is not + * corresponding to a Firestore document. + */ + @Nullable + @BetaApi + public Timestamp getUpdateTime() { + return updateTime; + } + + /** + * Returns the time at which this document was created. Returns null if this result is not + * corresponding to a Firestore document. + */ + @Nullable + @BetaApi + public Timestamp getCreateTime() { + return createTime; + } + + /** + * Returns whether or not the field exists in the document. Returns false if the document does not + * exist. + * + * @return whether the document existed in this snapshot. + */ + @BetaApi + public boolean exists() { + return fields != null; + } + + /** + * Returns the fields of the result as a Map or null if the result doesn't exist. Field values + * will be converted to their native Java representation. + * + * @return The fields of the document as a Map or null if the result doesn't exist. + */ + @Nonnull + @BetaApi + public Map getData() { + if (fields == null) { + return null; + } + + Map decodedFields = new HashMap<>(); + for (Map.Entry entry : fields.entrySet()) { + Object decodedValue = UserDataConverter.decodeValue(rpcContext, entry.getValue()); + decodedFields.put(entry.getKey(), decodedValue); + } + return decodedFields; + } + + /** + * Returns the contents of the document converted to a POJO or null if the result doesn't exist. + * + * @param valueType The Java class to create + * @return The contents of the document in an object of type T or null if the result doesn't + * exist. + */ + @Nullable + @BetaApi + public T toObject(@Nonnull Class valueType) { + Map data = getData(); + return data == null ? null : CustomClassMapper.convertToCustomClass(data, valueType, docRef); + } + + /** + * Returns whether or not the field exists in the document. Returns false if the result does not + * exist. + * + * @param field the path to the field. + * @return true iff the field exists. + */ + @BetaApi + public boolean contains(@Nonnull String field) { + return contains(FieldPath.fromDotSeparatedString(field)); + } + + /** + * Returns whether or not the field exists in the document. Returns false if the result does not + * exist. + * + * @param fieldPath the path to the field. + * @return true iff the field exists. + */ + @BetaApi + public boolean contains(@Nonnull FieldPath fieldPath) { + return this.extractField(fieldPath) != null; + } + + /** + * Returns the value at the field or null if the field doesn't exist. + * + * @param field The path to the field. + * @return The value at the given field or null. + */ + @Nullable + @BetaApi + public Object get(@Nonnull String field) { + return get(FieldPath.fromDotSeparatedString(field)); + } + + /** + * Returns the value at the field, converted to a POJO, or null if the field or result doesn't + * exist. + * + * @param field The path to the field + * @param valueType The Java class to convert the field value to. + * @return The value at the given field or null. + */ + @Nullable + @BetaApi + public T get(@Nonnull String field, @Nonnull Class valueType) { + return get(FieldPath.fromDotSeparatedString(field), valueType); + } + + /** + * Returns the value at the field or null if the field doesn't exist. + * + * @param fieldPath The path to the field. + * @return The value at the given field or null. + */ + @Nullable + @BetaApi + public Object get(@Nonnull FieldPath fieldPath) { + Value value = extractField(fieldPath); + + if (value == null) { + return null; + } + + return UserDataConverter.decodeValue(rpcContext, value); + } + + /** + * Returns the value at the field, converted to a POJO, or null if the field or result doesn't + * exist. + * + * @param fieldPath The path to the field + * @param valueType The Java class to convert the field value to. + * @return The value at the given field or null. + */ + @Nullable + @BetaApi + public T get(@Nonnull FieldPath fieldPath, Class valueType) { + Object data = get(fieldPath); + return data == null ? null : CustomClassMapper.convertToCustomClass(data, valueType, docRef); + } + + /** Returns the Value Proto at 'fieldPath'. Returns null if the field was not found. */ + @Nullable + Value extractField(@Nonnull FieldPath fieldPath) { + Value value = null; + + if (fields != null) { + Iterator components = fieldPath.getSegments().iterator(); + value = fields.get(components.next()); + + while (value != null && components.hasNext()) { + if (value.getValueTypeCase() != Value.ValueTypeCase.MAP_VALUE) { + return null; + } + value = value.getMapValue().getFieldsOrDefault(components.next(), null); + } + } + + return value; + } + + /** + * Returns the value of the field as a boolean. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Boolean. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Boolean getBoolean(@Nonnull String field) { + return (Boolean) get(field); + } + + /** + * Returns the value of the field as a double. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Number. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Double getDouble(@Nonnull String field) { + Number number = (Number) get(field); + return number == null ? null : number.doubleValue(); + } + + /** + * Returns the value of the field as a String. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a String. + * @return The value of the field. + */ + @Nullable + @BetaApi + public String getString(@Nonnull String field) { + return (String) get(field); + } + + /** + * Returns the value of the field as a long. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Number. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Long getLong(@Nonnull String field) { + Number number = (Number) get(field); + return number == null ? null : number.longValue(); + } + + /** + * Returns the value of the field as a Date. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Date. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Date getDate(@Nonnull String field) { + Timestamp timestamp = getTimestamp(field); + return timestamp == null ? null : timestamp.toDate(); + } + + /** + * Returns the value of the field as a {@link Timestamp}. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Date. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Timestamp getTimestamp(@Nonnull String field) { + return (Timestamp) get(field); + } + + /** + * Returns the value of the field as a Blob. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a Blob. + * @return The value of the field. + */ + @Nullable + @BetaApi + public Blob getBlob(@Nonnull String field) { + return (Blob) get(field); + } + + /** + * Returns the value of the field as a GeoPoint. + * + * @param field The path to the field. + * @throws RuntimeException if the value is not a GeoPoint. + * @return The value of the field. + */ + @Nullable + @BetaApi + public GeoPoint getGeoPoint(@Nonnull String field) { + return (GeoPoint) get(field); + } + + /** + * Gets the reference to the document. + * + * @return The reference to the document. + */ + @BetaApi + public DocumentReference getReference() { + return docRef; + } + + /** Checks whether this DocumentSnapshot contains any fields. */ + boolean isEmpty() { + return fields == null || fields.isEmpty(); + } + + Map getProtoFields() { + return fields; + } + + Write.Builder toPb() { + Preconditions.checkState(exists(), "Can't call toDocument() on a document that doesn't exist"); + Write.Builder write = Write.newBuilder(); + Document.Builder document = write.getUpdateBuilder(); + document.setName(docRef.getName()); + document.putAllFields(fields); + return write; + } + + Document.Builder toDocumentPb() { + Preconditions.checkState(exists(), "Can't call toDocument() on a document that doesn't exist"); + Document.Builder document = Document.newBuilder(); + return document + .setName(docRef.getName()) + .putAllFields(fields) + .setCreateTime(createTime.toProto()) + .setUpdateTime(updateTime.toProto()); + } + + /** + * Returns true if the document's data and path in this DocumentSnapshot equals the provided + * snapshot. + * + * @param obj The object to compare against. + * @return Whether this DocumentSnapshot is equal to the provided object. + */ + @Override + @BetaApi + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof PipelineResult)) { + return false; + } + PipelineResult that = (PipelineResult) obj; + return Objects.equals(rpcContext, that.rpcContext) + && Objects.equals(docRef, that.docRef) + && Objects.equals(fields, that.fields); + } + + @Override + public int hashCode() { + return Objects.hash(rpcContext, docRef, fields); + } + + @Override + public String toString() { + return String.format( + "%s{doc=%s, fields=%s, readTime=%s, updateTime=%s, createTime=%s}", + getClass().getSimpleName(), docRef, fields, executionTime, updateTime, createTime); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineSource.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineSource.java new file mode 100644 index 000000000..740de02d1 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineSource.java @@ -0,0 +1,98 @@ +package com.google.cloud.firestore; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.stages.Collection; +import com.google.cloud.firestore.pipeline.stages.CollectionGroup; +import com.google.cloud.firestore.pipeline.stages.Database; +import com.google.cloud.firestore.pipeline.stages.Documents; +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; + +/** + * A factory for creating {@link Pipeline} instances, which provide a framework for building data + * transformation and query pipelines for Firestore. + * + *

Start by calling {@link Firestore#pipeline()} to obtain an instance of {@code PipelineSource}. + * From there, you can use the provided methods (like {@link #collection(String)}) to specify the + * data source for your pipeline. + * + *

This class is typically used to start building Firestore pipelines. It allows you to define + * the initial data source for a pipeline. + * + *

Example Usage: + * + *

{@code
+ * firestore.pipeline() // Get a PipelineSource instance
+ *   .collection("users") // Create a pipeline that operates on a collection
+ *   .select("name"); // Add stages to the pipeline
+ * }
+ */ +@BetaApi +public class PipelineSource { + private final Firestore db; + + @InternalApi + PipelineSource(Firestore db) { + this.db = db; + } + + /** + * Creates a new {@link Pipeline} that operates on the specified Firestore collection. + * + * @param path The path to the Firestore collection (e.g., "users"). + * @return A new {@code Pipeline} instance targeting the specified collection. + */ + @Nonnull + @BetaApi + public Pipeline collection(@Nonnull String path) { + return new Pipeline(this.db, new Collection(path)); + } + + /** + * Creates a new {@link Pipeline} that operates on all documents in a collection group. + * + *

A collection group consists of all collections with the same ID. For example, if you have + * collections named "users" under different documents, you can query them together using a + * collection group query. + * + * @param collectionId The ID of the collection group. + * @return A new {@code Pipeline} instance targeting the specified collection group. + */ + @Nonnull + @BetaApi + public Pipeline collectionGroup(@Nonnull String collectionId) { + Preconditions.checkArgument( + !collectionId.contains("/"), + "Invalid collectionId '%s'. Collection IDs must not contain '/'.", + collectionId); + return new Pipeline(this.db, new CollectionGroup(collectionId)); + } + + /** + * Creates a new {@link Pipeline} that operates on all documents in the Firestore database. + * + *

Use this method with caution as it can lead to very large result sets. It is usually only + * useful at development stage. + * + * @return A new {@code Pipeline} instance targeting all documents in the database. + */ + @Nonnull + @BetaApi + public Pipeline database() { + return new Pipeline(this.db, new Database()); + } + + /** + * Creates a new {@link Pipeline} that operates on a specific set of Firestore documents. + * + * @param docs The {@link DocumentReference} instances representing the documents to include in + * the pipeline. + * @return A new {@code Pipeline} instance targeting the specified documents. + */ + @Nonnull + @BetaApi + public Pipeline documents(DocumentReference... docs) { + return new Pipeline(this.db, Documents.of(docs)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineUtils.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineUtils.java new file mode 100644 index 000000000..21b916e0c --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/PipelineUtils.java @@ -0,0 +1,181 @@ +package com.google.cloud.firestore; + +import static com.google.cloud.firestore.pipeline.expressions.Function.and; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayContainsAny; +import static com.google.cloud.firestore.pipeline.expressions.Function.countAll; +import static com.google.cloud.firestore.pipeline.expressions.Function.inAny; +import static com.google.cloud.firestore.pipeline.expressions.Function.not; +import static com.google.cloud.firestore.pipeline.expressions.Function.or; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.Query.ComparisonFilterInternal; +import com.google.cloud.firestore.Query.CompositeFilterInternal; +import com.google.cloud.firestore.Query.FilterInternal; +import com.google.cloud.firestore.Query.LimitType; +import com.google.cloud.firestore.Query.UnaryFilterInternal; +import com.google.cloud.firestore.pipeline.expressions.Accumulator; +import com.google.cloud.firestore.pipeline.expressions.AccumulatorTarget; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import com.google.cloud.firestore.pipeline.expressions.ExprWithAlias; +import com.google.cloud.firestore.pipeline.expressions.Field; +import com.google.cloud.firestore.pipeline.expressions.Fields; +import com.google.cloud.firestore.pipeline.expressions.FilterCondition; +import com.google.cloud.firestore.pipeline.expressions.Selectable; +import com.google.common.collect.Lists; +import com.google.firestore.v1.Cursor; +import com.google.firestore.v1.Value; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@InternalApi +public class PipelineUtils { + @InternalApi + public static Value encodeValue(Object value) { + return UserDataConverter.encodeValue(FieldPath.empty(), value, UserDataConverter.ARGUMENT); + } + + @InternalApi + static FilterCondition toPipelineFilterCondition(FilterInternal f) { + if (f instanceof ComparisonFilterInternal) { + ComparisonFilterInternal comparisonFilter = (ComparisonFilterInternal) f; + Field field = Field.of(comparisonFilter.fieldReference.getFieldPath()); + Value value = comparisonFilter.value; + switch (comparisonFilter.operator) { + case LESS_THAN: + return and(field.exists(), field.lt(value)); + case LESS_THAN_OR_EQUAL: + return and(field.exists(), field.lte(value)); + case GREATER_THAN: + return and(field.exists(), field.gt(value)); + case GREATER_THAN_OR_EQUAL: + return and(field.exists(), field.gte(value)); + case EQUAL: + return and(field.exists(), field.eq(value)); + case NOT_EQUAL: + return and(field.exists(), not(field.eq(value))); + case ARRAY_CONTAINS: + return and(field.exists(), field.arrayContains(value)); + case IN: + List valuesList = value.getArrayValue().getValuesList(); + return and(field.exists(), inAny(field, Lists.newArrayList(valuesList))); + case ARRAY_CONTAINS_ANY: + List valuesListAny = value.getArrayValue().getValuesList(); + return and(field.exists(), arrayContainsAny(field, valuesListAny.toArray())); + case NOT_IN: + List notInValues = value.getArrayValue().getValuesList(); + return and(field.exists(), not(inAny(field, Lists.newArrayList(notInValues)))); + default: + // Handle OPERATOR_UNSPECIFIED and UNRECOGNIZED cases as needed + throw new IllegalArgumentException("Unsupported operator: " + comparisonFilter.operator); + } + } else if (f instanceof CompositeFilterInternal) { + CompositeFilterInternal compositeFilter = (CompositeFilterInternal) f; + switch (compositeFilter.getOperator()) { + case AND: + List conditions = + compositeFilter.getFilters().stream() + .map(PipelineUtils::toPipelineFilterCondition) + .collect(Collectors.toList()); + return and( + conditions.get(0), + conditions.subList(1, conditions.size()).toArray(new FilterCondition[0])); + case OR: + List orConditions = + compositeFilter.getFilters().stream() + .map(PipelineUtils::toPipelineFilterCondition) + .collect(Collectors.toList()); + return or( + orConditions.get(0), + orConditions.subList(1, orConditions.size()).toArray(new FilterCondition[0])); + default: + // Handle OPERATOR_UNSPECIFIED and UNRECOGNIZED cases as needed + throw new IllegalArgumentException( + "Unsupported operator: " + compositeFilter.getOperator()); + } + } else if (f instanceof UnaryFilterInternal) { + UnaryFilterInternal unaryFilter = (UnaryFilterInternal) f; + Field field = Field.of(unaryFilter.fieldReference.getFieldPath()); + switch (unaryFilter.getOperator()) { + case IS_NAN: + return and(field.exists(), field.isNaN()); + case IS_NULL: + return and(field.exists(), field.isNull()); + case IS_NOT_NAN: + return and(field.exists(), not(field.isNaN())); + case IS_NOT_NULL: + return and(field.exists(), not(field.isNull())); + default: + // Handle OPERATOR_UNSPECIFIED and UNRECOGNIZED cases as needed + throw new IllegalArgumentException("Unsupported operator: " + unaryFilter.getOperator()); + } + } else { + // Handle other FilterInternal types as needed + throw new IllegalArgumentException("Unsupported filter type: " + f.getClass().getName()); + } + } + + @InternalApi + static Pipeline toPaginatedPipeline( + Pipeline pipeline, + Cursor start, + Cursor end, + Integer limit, + LimitType limitType, + Integer offset) { + throw new UnsupportedOperationException( + "Converting to pagination pipeline is not support yet."); + } + + @InternalApi + static ExprWithAlias toPipelineAggregatorTarget(AggregateField f) { + String operator = f.getOperator(); + String fieldPath = f.getFieldPath(); + + switch (operator) { + case "sum": + return Field.of(fieldPath).sum().as(f.getAlias()); + + case "count": + return countAll().as(f.getAlias()); + case "average": + return Field.of(fieldPath).avg().as(f.getAlias()); + default: + // Handle the 'else' case appropriately in your Java code + throw new IllegalArgumentException("Unsupported operator: " + operator); + } + } + + @InternalApi + public static Map selectablesToMap(Selectable... selectables) { + Map projMap = new HashMap<>(); + for (Selectable proj : selectables) { + if (proj instanceof Field) { + Field fieldProj = (Field) proj; + projMap.put(fieldProj.getPath().getEncodedPath(), fieldProj); + } else if (proj instanceof AccumulatorTarget) { + AccumulatorTarget aggregatorProj = (AccumulatorTarget) proj; + projMap.put(aggregatorProj.getFieldName(), aggregatorProj.getAccumulator()); + } else if (proj instanceof Fields) { + Fields fieldsProj = (Fields) proj; + if (fieldsProj.getFields() != null) { + fieldsProj.getFields().forEach(f -> projMap.put(f.getPath().getEncodedPath(), f)); + } + } else if (proj instanceof ExprWithAlias) { + ExprWithAlias exprWithAlias = (ExprWithAlias) proj; + projMap.put(exprWithAlias.getAlias(), exprWithAlias.getExpr()); + } + } + return projMap; + } + + @InternalApi + public static Map fieldNamesToMap(String... fields) { + Map projMap = new HashMap<>(); + for (String field : fields) { + projMap.put(field, Field.of(field)); + } + return projMap; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java index d71bc5a30..600848d9b 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/Query.java @@ -16,6 +16,9 @@ package com.google.cloud.firestore; +import static com.google.cloud.firestore.PipelineUtils.toPaginatedPipeline; +import static com.google.cloud.firestore.PipelineUtils.toPipelineFilterCondition; +import static com.google.cloud.firestore.pipeline.expressions.Function.and; import static com.google.common.collect.Lists.reverse; import static com.google.firestore.v1.StructuredQuery.FieldFilter.Operator.ARRAY_CONTAINS; import static com.google.firestore.v1.StructuredQuery.FieldFilter.Operator.ARRAY_CONTAINS_ANY; @@ -29,6 +32,7 @@ import static com.google.firestore.v1.StructuredQuery.FieldFilter.Operator.NOT_IN; import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; import com.google.api.core.InternalExtensionOnly; import com.google.api.core.SettableApiFuture; import com.google.api.gax.rpc.ApiStreamObserver; @@ -38,6 +42,12 @@ import com.google.auto.value.AutoValue; import com.google.cloud.Timestamp; import com.google.cloud.firestore.Query.QueryOptions.Builder; +import com.google.cloud.firestore.pipeline.expressions.Exists; +import com.google.cloud.firestore.pipeline.expressions.Field; +import com.google.cloud.firestore.pipeline.expressions.Ordering; +import com.google.cloud.firestore.pipeline.expressions.Selectable; +import com.google.cloud.firestore.pipeline.stages.Sort.Density; +import com.google.cloud.firestore.pipeline.stages.Sort.Truncation; import com.google.cloud.firestore.v1.FirestoreSettings; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -54,6 +64,7 @@ import com.google.firestore.v1.StructuredQuery.FieldReference; import com.google.firestore.v1.StructuredQuery.Filter; import com.google.firestore.v1.StructuredQuery.Order; +import com.google.firestore.v1.StructuredQuery.UnaryFilter; import com.google.firestore.v1.Value; import com.google.protobuf.ByteString; import com.google.protobuf.Int32Value; @@ -74,6 +85,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; +import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.threeten.bp.Duration; @@ -172,6 +184,11 @@ public List getFilters() { return filters; } + @Nonnull + CompositeFilter.Operator getOperator() { + return this.operator; + } + @Nullable @Override public FieldReference getFirstInequalityField() { @@ -237,7 +254,7 @@ public List getFlattenedFilters() { } } - private static class UnaryFilterInternal extends FieldFilterInternal { + static class UnaryFilterInternal extends FieldFilterInternal { private final StructuredQuery.UnaryFilter.Operator operator; @@ -264,6 +281,11 @@ Filter toProto() { return result.build(); } + @Nonnull + UnaryFilter.Operator getOperator() { + return this.operator; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -2100,6 +2122,85 @@ public AggregateQuery aggregate( return new AggregateQuery(this, aggregateFieldList); } + @Nonnull + @BetaApi + public Pipeline pipeline() { + // From + Pipeline ppl = + this.options.getAllDescendants() + ? new PipelineSource(this.getFirestore()) + .collectionGroup(this.options.getCollectionId()) + : new PipelineSource(this.getFirestore()) + .collection( + this.options.getParentPath().append(this.options.getCollectionId()).getPath()); + + // Filters + for (FilterInternal f : this.options.getFilters()) { + ppl = ppl.where(toPipelineFilterCondition(f)); + } + + // Projections + if (this.options.getFieldProjections() != null + && !this.options.getFieldProjections().isEmpty()) { + ppl = + ppl.select( + this.options.getFieldProjections().stream() + .map(fieldReference -> Field.of(fieldReference.getFieldPath())) + .toArray(Selectable[]::new)); + } + + // Orders + List normalizedOrderbys = this.createImplicitOrderBy(); + if (normalizedOrderbys != null && !normalizedOrderbys.isEmpty()) { + // Add exists filters to match Query's implicit orderby semantics. + List exists = + normalizedOrderbys.stream() + // .filter(order -> !order.fieldReference.getFieldPath().equals("__name__")) + .map(order -> Field.of(order.fieldReference.getFieldPath()).exists()) + .collect(Collectors.toList()); + if (exists.size() > 1) { + ppl = + ppl.where( + and(exists.get(0), exists.subList(1, exists.size()).toArray(new Exists[] {}))); + } else if (exists.size() == 1) { + ppl = ppl.where(exists.get(0)); + } + + List orders = + normalizedOrderbys.stream() + .map( + fieldOrder -> + fieldOrder.direction == Direction.ASCENDING + ? Field.of(fieldOrder.fieldReference.getFieldPath()).ascending() + : Field.of(fieldOrder.fieldReference.getFieldPath()).descending()) + .collect(Collectors.toList()); + ppl = ppl.sort(orders, Density.REQUIRED, Truncation.UNSPECIFIED); + } + + // Cursors, Limit and Offset + if (this.options.getStartCursor() != null + || this.options.getEndCursor() != null + || this.options.getLimitType() == LimitType.Last) { + ppl = + toPaginatedPipeline( + ppl, + options.getStartCursor(), + options.getEndCursor(), + options.getLimit(), + options.getLimitType(), + options.getOffset()); + } else { // Limit & Offset without cursors + if (this.options.getOffset() != null) { + ppl = ppl.offset(this.options.getOffset()); + } + if (this.options.getLimit() != null) { + ppl = ppl.limit(this.options.getLimit()); + } + } + + return ppl; + } + /** * Returns true if this Query is equal to the provided object. * diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java index e1fec41af..bfbddc86f 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java @@ -16,7 +16,10 @@ package com.google.cloud.firestore; +import static com.google.cloud.firestore.pipeline.expressions.FunctionUtils.exprToValue; + import com.google.cloud.Timestamp; +import com.google.cloud.firestore.pipeline.expressions.Expr; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -156,6 +159,8 @@ static Value encodeValue( } else if (sanitizedObject instanceof Blob) { Blob blob = (Blob) sanitizedObject; return Value.newBuilder().setBytesValue(blob.toByteString()).build(); + } else if (sanitizedObject instanceof Expr) { + return exprToValue((Expr) sanitizedObject); } else if (sanitizedObject instanceof Value) { return (Value) sanitizedObject; } else if (sanitizedObject instanceof DocumentReference) { diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/PaginatingPipeline.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/PaginatingPipeline.java new file mode 100644 index 000000000..e6289808b --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/PaginatingPipeline.java @@ -0,0 +1,75 @@ +package com.google.cloud.firestore.pipeline; + +import com.google.cloud.firestore.Pipeline; +import com.google.cloud.firestore.PipelineResult; +import com.google.cloud.firestore.pipeline.expressions.Ordering; +import com.google.firestore.v1.Cursor; +import java.util.List; + +public class PaginatingPipeline { + private final Pipeline p; + private final int pageSize; + private final List orders; + private final Integer offset; + private final Cursor startCursor; + private final Cursor endCursor; + + public PaginatingPipeline(Pipeline p, int pageSize, List orders) { + this(p, pageSize, orders, null, null, null); + } + + private PaginatingPipeline( + Pipeline p, + int pageSize, + List orders, + Integer offset, + Cursor startCursor, + Cursor endCursor) { + this.p = p; + this.pageSize = pageSize; + this.orders = orders; + this.offset = offset; + this.startCursor = startCursor; + this.endCursor = endCursor; + } + + public Pipeline firstPage() { + return this.p; + } + + public Pipeline lastPage() { + return this.p; + } + + public PaginatingPipeline startAt(PipelineResult result) { + return this; + } + + public PaginatingPipeline startAfter(PipelineResult result) { + return this; + } + + public PaginatingPipeline endAt(PipelineResult result) { + return this; + } + + public PaginatingPipeline endBefore(PipelineResult result) { + return this; + } + + public PaginatingPipeline offset(int offset) { + return this; + } + + public PaginatingPipeline limit(int limit) { + return this; + } + + public PaginatingPipeline withStartCursor(Cursor cursor) { + return this; + } + + public PaginatingPipeline withEndCursor(Cursor cursor) { + return this; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Accumulator.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Accumulator.java new file mode 100644 index 000000000..e851d28e3 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Accumulator.java @@ -0,0 +1,12 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; + +@BetaApi +public interface Accumulator extends Expr { + @BetaApi + @Override + default ExprWithAlias as(String fieldName) { + return new ExprWithAlias<>(this, fieldName); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/AccumulatorTarget.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/AccumulatorTarget.java new file mode 100644 index 000000000..fce6184af --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/AccumulatorTarget.java @@ -0,0 +1,27 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; + +@BetaApi +public final class AccumulatorTarget implements Selectable { + private final Accumulator accumulator; + private final String fieldName; + + @InternalApi + AccumulatorTarget(Accumulator accumulator, String fieldName, boolean distinct) { + this.accumulator = accumulator; + this.fieldName = fieldName; + } + + // Getters (for accumulator, fieldName, and distinct) + @InternalApi + public Accumulator getAccumulator() { + return accumulator; + } + + @InternalApi + public String getFieldName() { + return fieldName; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Add.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Add.java new file mode 100644 index 000000000..e2768b7d5 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Add.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Add extends Function { + @InternalApi + Add(Expr left, Expr right) { + super("add", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/And.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/And.java new file mode 100644 index 000000000..296fb532a --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/And.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import java.util.List; + +@BetaApi +public final class And extends Function implements FilterCondition { + @InternalApi + And(List conditions) { + super("and", conditions); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayConcat.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayConcat.java new file mode 100644 index 000000000..945832c36 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayConcat.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.List; + +@BetaApi +public final class ArrayConcat extends Function { + @InternalApi + ArrayConcat(Expr array, List rest) { + super("array_concat", Lists.asList(array, rest.toArray(new Expr[] {}))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContains.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContains.java new file mode 100644 index 000000000..99fc5754b --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContains.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ArrayContains extends Function implements FilterCondition { + @InternalApi + ArrayContains(Expr array, Expr element) { + super("array_contains", Lists.newArrayList(array, element)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAll.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAll.java new file mode 100644 index 000000000..b011081a4 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAll.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.List; + +@BetaApi +public final class ArrayContainsAll extends Function implements FilterCondition { + @InternalApi + ArrayContainsAll(Expr array, List elements) { + super("array_contains_all", Lists.newArrayList(array, new ListOfExprs(elements))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAny.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAny.java new file mode 100644 index 000000000..fb7e40d7b --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayContainsAny.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.List; + +@BetaApi +public final class ArrayContainsAny extends Function implements FilterCondition { + @InternalApi + ArrayContainsAny(Expr array, List elements) { + super("array_contains_any", Lists.newArrayList(array, new ListOfExprs(elements))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayElement.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayElement.java new file mode 100644 index 000000000..903e528f7 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayElement.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public class ArrayElement extends Function { + @InternalApi + ArrayElement() { + super("array_element", Lists.newArrayList()); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayFilter.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayFilter.java new file mode 100644 index 000000000..d367f7412 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayFilter.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ArrayFilter extends Function { + @InternalApi + ArrayFilter(Expr array, FilterCondition filter) { + super("array_filter", Lists.newArrayList(array, filter)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayLength.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayLength.java new file mode 100644 index 000000000..d9232457b --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayLength.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ArrayLength extends Function { + @InternalApi + ArrayLength(Expr array) { + super("array_length", Lists.newArrayList(array)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayTransform.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayTransform.java new file mode 100644 index 000000000..3278e8f84 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ArrayTransform.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ArrayTransform extends Function { + @InternalApi + ArrayTransform(Expr array, Function transform) { + super("array_transform", Lists.newArrayList(array, transform)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Avg.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Avg.java new file mode 100644 index 000000000..355236076 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Avg.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Avg extends Function implements Accumulator { + @InternalApi + Avg(Expr value, boolean distinct) { + super("avg", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CollectionId.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CollectionId.java new file mode 100644 index 000000000..e05066ad3 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CollectionId.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class CollectionId extends Function { + + @InternalApi + CollectionId(Expr value) { + super("collection_id", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Concat.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Concat.java new file mode 100644 index 000000000..283cedca5 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Concat.java @@ -0,0 +1,9 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import java.util.List; + +public final class Concat extends Function { + Concat(List exprs) { + super("concat", exprs); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Constant.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Constant.java new file mode 100644 index 000000000..d6d0d4bcd --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Constant.java @@ -0,0 +1,124 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import static com.google.cloud.firestore.PipelineUtils.encodeValue; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.Timestamp; +import com.google.cloud.firestore.Blob; +import com.google.cloud.firestore.DocumentReference; +import com.google.cloud.firestore.GeoPoint; +import com.google.firestore.v1.Value; +import java.util.Arrays; +import java.util.Date; +import java.util.Map; +import java.util.stream.Collectors; + +@BetaApi +public final class Constant implements Expr { + private final Object value; + + private Constant(Object value) { + this.value = value; + } + + @BetaApi + public static Constant of(String value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(Number value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(Date value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(Timestamp value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(Boolean value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(GeoPoint value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(Blob value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(DocumentReference value) { + return new Constant(value); + } + + @InternalApi + public static Constant of(Value value) { + return new Constant(value); + } + + @BetaApi + static Constant of(Object value) { + if (value == null) { + return new Constant(null); + } + + if (value instanceof String) { + return of((String) value); + } else if (value instanceof Number) { + return of((Number) value); + } else if (value instanceof Date) { + return of((Date) value); + } else if (value instanceof Timestamp) { + return of((Timestamp) value); + } else if (value instanceof Boolean) { + return of((Boolean) value); + } else if (value instanceof GeoPoint) { + return of((GeoPoint) value); + } else if (value instanceof Blob) { + return of((Blob) value); + } else if (value instanceof DocumentReference) { + return of((DocumentReference) value); + } else if (value instanceof Value) { + return of((Value) value); + } else { + throw new IllegalArgumentException("Unknown type: " + value); + } + } + + @BetaApi + public static Constant of(Iterable value) { + return new Constant(value); + } + + @BetaApi + public static Constant of(T[] value) { + return new Constant(Arrays.asList(value)); // Convert array to list + } + + @BetaApi + public static Constant of(Map value) { + return new Constant(value); + } + + @BetaApi + public static Constant ofVector(double[] value) { + // Convert double array to List + return new Constant(Arrays.stream(value).boxed().collect(Collectors.toList())); + } + + @InternalApi + public Value toProto() { + return encodeValue(value); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CosineDistance.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CosineDistance.java new file mode 100644 index 000000000..adec5b369 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CosineDistance.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class CosineDistance extends Function { + @InternalApi + CosineDistance(Expr vector1, Expr vector2) { + super("cosine_distance", Lists.newArrayList(vector1, vector2)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Count.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Count.java new file mode 100644 index 000000000..4c2cfc827 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Count.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.Collections; + +@BetaApi +public final class Count extends Function implements Accumulator { + @InternalApi + Count(Expr value, boolean distinct) { + super("count", (value != null) ? Lists.newArrayList(value) : Collections.emptyList()); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CountIf.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CountIf.java new file mode 100644 index 000000000..5db4c1dd7 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/CountIf.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.Collections; + +@BetaApi +public final class CountIf extends Function implements Accumulator { + @InternalApi + CountIf(Expr value, boolean distinct) { + super("count_if", (value != null) ? Lists.newArrayList(value) : Collections.emptyList()); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Divide.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Divide.java new file mode 100644 index 000000000..f99f1c8b3 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Divide.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Divide extends Function { + @InternalApi + Divide(Expr left, Expr right) { + super("divide", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/DotProductDistance.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/DotProductDistance.java new file mode 100644 index 000000000..8fefb863c --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/DotProductDistance.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class DotProductDistance extends Function { + @InternalApi + DotProductDistance(Expr vector1, Expr vector2) { + super("dot_product", Lists.newArrayList(vector1, vector2)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EndsWith.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EndsWith.java new file mode 100644 index 000000000..b2608bfa2 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EndsWith.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class EndsWith extends Function implements FilterCondition { + @InternalApi + EndsWith(Expr expr, Expr postfix) { + super("ends_with", Lists.newArrayList(expr, postfix)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Eq.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Eq.java new file mode 100644 index 000000000..4c86da7a5 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Eq.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Eq extends Function implements FilterCondition { + @InternalApi + Eq(Expr left, Expr right) { + super("eq", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EuclideanDistance.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EuclideanDistance.java new file mode 100644 index 000000000..1fd0808dd --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/EuclideanDistance.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class EuclideanDistance extends Function { + @InternalApi + EuclideanDistance(Expr vector1, Expr vector2) { + super("euclidean_distance", Lists.newArrayList(vector1, vector2)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Exists.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Exists.java new file mode 100644 index 000000000..44a573926 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Exists.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Exists extends Function implements FilterCondition { + @InternalApi + Exists(Expr expr) { + super("exists", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expr.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expr.java new file mode 100644 index 000000000..a9aac6c34 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Expr.java @@ -0,0 +1,1241 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import static com.google.cloud.firestore.pipeline.expressions.FunctionUtils.toExprList; + +import com.google.api.core.BetaApi; +import java.util.Arrays; + +/** + * Represents an expression that can be evaluated to a value within the execution of a {@link + * com.google.cloud.firestore.Pipeline}. + * + *

Expressions are the building blocks for creating complex queries and transformations in + * Firestore pipelines. They can represent: + * + *

    + *
  • **Field references:** Access values from document fields. + *
  • **Literals:** Represent constant values (strings, numbers, booleans). + *
  • **Function calls:** Apply functions to one or more expressions. + *
  • **Aggregations:** Calculate aggregate values (e.g., sum, average) over a set of documents. + *
+ * + *

The `Expr` interface provides a fluent API for building expressions. You can chain together + * method calls to create complex expressions. + */ +@BetaApi +public interface Expr { + + // Arithmetic Operators + + /** + * Creates an expression that adds this expression to another expression. + * + *

Example: + * + *

{@code
+   * // Add the value of the 'quantity' field and the 'reserve' field.
+   * Field.of("quantity").add(Field.of("reserve"));
+   * }
+ * + * @param other The expression to add to this expression. + * @return A new {@code Expr} representing the addition operation. + */ + @BetaApi + default Add add(Expr other) { + return new Add(this, other); + } + + /** + * Creates an expression that adds this expression to a constant value. + * + *

Example: + * + *

{@code
+   * // Add 5 to the value of the 'age' field
+   * Field.of("age").add(5);
+   * }
+ * + * @param other The constant value to add. + * @return A new {@code Expr} representing the addition operation. + */ + @BetaApi + default Add add(Object other) { + return new Add(this, Constant.of(other)); + } + + /** + * Creates an expression that subtracts another expression from this expression. + * + *

Example: + * + *

{@code
+   * // Subtract the 'discount' field from the 'price' field
+   * Field.of("price").subtract(Field.of("discount"));
+   * }
+ * + * @param other The expression to subtract from this expression. + * @return A new {@code Expr} representing the subtraction operation. + */ + @BetaApi + default Subtract subtract(Expr other) { + return new Subtract(this, other); + } + + /** + * Creates an expression that subtracts a constant value from this expression. + * + *

Example: + * + *

{@code
+   * // Subtract 20 from the value of the 'total' field
+   * Field.of("total").subtract(20);
+   * }
+ * + * @param other The constant value to subtract. + * @return A new {@code Expr} representing the subtraction operation. + */ + @BetaApi + default Subtract subtract(Object other) { + return new Subtract(this, Constant.of(other)); + } + + /** + * Creates an expression that multiplies this expression by another expression. + * + *

Example: + * + *

{@code
+   * // Multiply the 'quantity' field by the 'price' field
+   * Field.of("quantity").multiply(Field.of("price"));
+   * }
+ * + * @param other The expression to multiply by. + * @return A new {@code Expr} representing the multiplication operation. + */ + @BetaApi + default Multiply multiply(Expr other) { + return new Multiply(this, other); + } + + /** + * Creates an expression that multiplies this expression by a constant value. + * + *

Example: + * + *

{@code
+   * // Multiply the 'value' field by 2
+   * Field.of("value").multiply(2);
+   * }
+ * + * @param other The constant value to multiply by. + * @return A new {@code Expr} representing the multiplication operation. + */ + @BetaApi + default Multiply multiply(Object other) { + return new Multiply(this, Constant.of(other)); + } + + /** + * Creates an expression that divides this expression by another expression. + * + *

Example: + * + *

{@code
+   * // Divide the 'total' field by the 'count' field
+   * Field.of("total").divide(Field.of("count"));
+   * }
+ * + * @param other The expression to divide by. + * @return A new {@code Expr} representing the division operation. + */ + @BetaApi + default Divide divide(Expr other) { + return new Divide(this, other); + } + + /** + * Creates an expression that divides this expression by a constant value. + * + *

Example: + * + *

{@code
+   * // Divide the 'value' field by 10
+   * Field.of("value").divide(10);
+   * }
+ * + * @param other The constant value to divide by. + * @return A new {@code Expr} representing the division operation. + */ + @BetaApi + default Divide divide(Object other) { + return new Divide(this, Constant.of(other)); + } + + // Comparison Operators + + /** + * Creates an expression that checks if this expression is equal to another expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'age' field is equal to 21
+   * Field.of("age").eq(21);
+   * }
+ * + * @param other The expression to compare for equality. + * @return A new {@code Expr} representing the equality comparison. + */ + @BetaApi + default Eq eq(Expr other) { + return new Eq(this, other); + } + + /** + * Creates an expression that checks if this expression is equal to a constant value. + * + *

Example: + * + *

{@code
+   * // Check if the 'city' field is equal to "London"
+   * Field.of("city").eq("London");
+   * }
+ * + * @param other The constant value to compare for equality. + * @return A new {@code Expr} representing the equality comparison. + */ + @BetaApi + default Eq eq(Object other) { + return new Eq(this, Constant.of(other)); + } + + /** + * Creates an expression that checks if this expression is not equal to another expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'status' field is not equal to "completed"
+   * Field.of("status").neq("completed");
+   * }
+ * + * @param other The expression to compare for inequality. + * @return A new {@code Expr} representing the inequality comparison. + */ + @BetaApi + default Neq neq(Expr other) { + return new Neq(this, other); + } + + /** + * Creates an expression that checks if this expression is not equal to a constant value. + * + *

Example: + * + *

{@code
+   * // Check if the 'country' field is not equal to "USA"
+   * Field.of("country").neq("USA");
+   * }
+ * + * @param other The constant value to compare for inequality. + * @return A new {@code Expr} representing the inequality comparison. + */ + @BetaApi + default Neq neq(Object other) { + return new Neq(this, Constant.of(other)); + } + + /** + * Creates an expression that checks if this expression is greater than another expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'age' field is greater than the 'limit' field
+   * Field.of("age").gt(Field.of("limit"));
+   * }
+ * + * @param other The expression to compare for greater than. + * @return A new {@code Expr} representing the greater than comparison. + */ + @BetaApi + default Gt gt(Expr other) { + return new Gt(this, other); + } + + /** + * Creates an expression that checks if this expression is greater than a constant value. + * + *

Example: + * + *

{@code
+   * // Check if the 'price' field is greater than 100
+   * Field.of("price").gt(100);
+   * }
+ * + * @param other The constant value to compare for greater than. + * @return A new {@code Expr} representing the greater than comparison. + */ + @BetaApi + default Gt gt(Object other) { + return new Gt(this, Constant.of(other)); + } + + /** + * Creates an expression that checks if this expression is greater than or equal to another + * expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'quantity' field is greater than or equal to field 'requirement' plus 1
+   * Field.of("quantity").gte(Field.of('requirement').add(1));
+   * }
+ * + * @param other The expression to compare for greater than or equal to. + * @return A new {@code Expr} representing the greater than or equal to comparison. + */ + @BetaApi + default Gte gte(Expr other) { + return new Gte(this, other); + } + + /** + * Creates an expression that checks if this expression is greater than or equal to a constant + * value. + * + *

Example: + * + *

{@code
+   * // Check if the 'score' field is greater than or equal to 80
+   * Field.of("score").gte(80);
+   * }
+ * + * @param other The constant value to compare for greater than or equal to. + * @return A new {@code Expr} representing the greater than or equal to comparison. + */ + @BetaApi + default Gte gte(Object other) { + return new Gte(this, Constant.of(other)); + } + + /** + * Creates an expression that checks if this expression is less than another expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'age' field is less than 'limit'
+   * Field.of("age").lt(Field.of('limit'));
+   * }
+ * + * @param other The expression to compare for less than. + * @return A new {@code Expr} representing the less than comparison. + */ + @BetaApi + default Lt lt(Expr other) { + return new Lt(this, other); + } + + /** + * Creates an expression that checks if this expression is less than a constant value. + * + *

Example: + * + *

{@code
+   * // Check if the 'price' field is less than 50
+   * Field.of("price").lt(50);
+   * }
+ * + * @param other The constant value to compare for less than. + * @return A new {@code Expr} representing the less than comparison. + */ + @BetaApi + default Lt lt(Object other) { + return new Lt(this, Constant.of(other)); + } + + /** + * Creates an expression that checks if this expression is less than or equal to another + * expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'quantity' field is less than or equal to 20
+   * Field.of("quantity").lte(Constant.of(20));
+   * }
+ * + * @param other The expression to compare for less than or equal to. + * @return A new {@code Expr} representing the less than or equal to comparison. + */ + @BetaApi + default Lte lte(Expr other) { + return new Lte(this, other); + } + + /** + * Creates an expression that checks if this expression is less than or equal to a constant value. + * + *

Example: + * + *

{@code
+   * // Check if the 'score' field is less than or equal to 70
+   * Field.of("score").lte(70);
+   * }
+ * + * @param other The constant value to compare for less than or equal to. + * @return A new {@code Expr} representing the less than or equal to comparison. + */ + @BetaApi + default Lte lte(Object other) { + return new Lte(this, Constant.of(other)); + } + + // IN operator + /** + * Creates an expression that checks if this expression is equal to any of the provided values or + * expressions. + * + *

Example: + * + *

{@code
+   * // Check if the 'category' field is either "Electronics" or value of field 'primaryType'
+   * Field.of("category").in("Electronics", Field.of("primaryType"));
+   * }
+ * + * @param other The values or expressions to check against. + * @return A new {@code Expr} representing the 'IN' comparison. + */ + @BetaApi + default In inAny(Object... other) { + return new In(this, toExprList(other)); + } + + /** + * Creates an expression that checks if this expression is not equal to any of the provided values + * or expressions. + * + *

Example: + * + *

{@code
+   * // Check if the 'status' field is neither "pending" nor "cancelled"
+   * Field.of("status").notIn("pending", "cancelled");
+   * }
+ * + * @param other The values or expressions to check against. + * @return A new {@code Expr} representing the 'NOT IN' comparison. + */ + @BetaApi + default Not notInAny(Object... other) { + return new Not(inAny(other)); + } + + // Array Functions + + /** + * Creates an expression that concatenates an array expression with one or more other arrays. + * + *

Example: + * + *

{@code
+   * // Combine the 'items' array with another array field.
+   * Field.of("items").arrayConcat(Field.of("otherItems"));
+   * }
+ * + * @param elements The array expressions to concatenate. + * @return A new {@code Expr} representing the concatenated array. + */ + @BetaApi + default ArrayConcat arrayConcat(Expr... elements) { + return new ArrayConcat(this, Arrays.asList(elements)); + } + + /** + * Creates an expression that concatenates an array expression with one or more other arrays. + * + *

Example: + * + *

{@code
+   * // Combine the 'tags' array with a new array and an array field
+   * Field.of("tags").arrayConcat(Arrays.asList("newTag1", "newTag2"), Field.of("otherTag"));
+   * }
+ * + * @param elements The array expressions or values to concatenate. + * @return A new {@code Expr} representing the concatenated array. + */ + @BetaApi + default ArrayConcat arrayConcat(Object... elements) { + return new ArrayConcat(this, toExprList(elements)); + } + + /** + * Creates an expression that checks if an array contains a specific element. + * + *

Example: + * + *

{@code
+   * // Check if the 'sizes' array contains the value from the 'selectedSize' field
+   * Field.of("sizes").arrayContains(Field.of("selectedSize"));
+   * }
+ * + * @param element The element to search for in the array. + * @return A new {@code Expr} representing the 'array_contains' comparison. + */ + @BetaApi + default ArrayContains arrayContains(Expr element) { + return new ArrayContains(this, element); + } + + /** + * Creates an expression that checks if an array contains a specific value. + * + *

Example: + * + *

{@code
+   * // Check if the 'colors' array contains "red"
+   * Field.of("colors").arrayContains("red");
+   * }
+ * + * @param element The element to search for in the array. + * @return A new {@code Expr} representing the 'array_contains' comparison. + */ + @BetaApi + default ArrayContains arrayContains(Object element) { + return new ArrayContains(this, Constant.of(element)); + } + + /** + * Creates an expression that checks if an array contains all the specified elements. + * + *

Example: + * + *

{@code
+   * // Check if the 'tags' array contains both "news" and "sports"
+   * Field.of("tags").arrayContainsAll(Field.of("tag1"), Field.of("tag2"));
+   * }
+ * + * @param elements The elements to check for in the array. + * @return A new {@code Expr} representing the 'array_contains_all' comparison. + */ + @BetaApi + default ArrayContainsAll arrayContainsAll(Expr... elements) { + return new ArrayContainsAll(this, Arrays.asList(elements)); + } + + /** + * Creates an expression that checks if an array contains all the specified elements. + * + *

Example: + * + *

{@code
+   * // Check if the 'tags' array contains both of the values from field 'tag1' and "tag2"
+   * Field.of("tags").arrayContainsAll(Field.of("tag1"), Field.of("tag2"));
+   * }
+ * + * @param elements The elements to check for in the array. + * @return A new {@code Expr} representing the 'array_contains_all' comparison. + */ + @BetaApi + default ArrayContainsAll arrayContainsAll(Object... elements) { + return new ArrayContainsAll(this, toExprList(elements)); + } + + /** + * Creates an expression that checks if an array contains any of the specified elements. + * + *

Example: + * + *

{@code
+   * // Check if the 'categories' array contains either values from field "cate1" or "cate2"
+   * Field.of("categories").arrayContainsAny(Field.of("cate1"), Field.of("cate2"));
+   * }
+ * + * @param elements The elements to check for in the array. + * @return A new {@code Expr} representing the 'array_contains_any' comparison. + */ + @BetaApi + default ArrayContainsAny arrayContainsAny(Expr... elements) { + return new ArrayContainsAny(this, Arrays.asList(elements)); + } + + /** + * Creates an expression that checks if an array contains any of the specified elements. + * + *

Example: + * + *

{@code
+   * // Check if the 'groups' array contains either the value from the 'userGroup' field
+   * // or the value "guest"
+   * Field.of("groups").arrayContainsAny(Field.of("userGroup"), "guest");
+   * }
+ * + * @param elements The elements to check for in the array. + * @return A new {@code Expr} representing the 'array_contains_any' comparison. + */ + @BetaApi + default ArrayContainsAny arrayContainsAny(Object... elements) { + return new ArrayContainsAny(this, toExprList(elements)); + } + + /** + * Creates an expression that filters elements from an array using the given {@link + * FilterCondition} and returns the filtered elements as a new array. + * + *

Example: + * + *

{@code
+   * // Get items from the 'inventoryPrices' array where the array item is greater than 0
+   * // Note we use {@link Function#arrayElement} to represent array elements to construct a
+   * // filtering condition.
+   * Field.of("inventoryPrices").arrayFilter(arrayElement().gt(0));
+   * }
+ * + * @param filter The {@link FilterCondition} to apply to the array elements. + * @return A new {@code Expr} representing the filtered array. + */ + @BetaApi + default ArrayFilter arrayFilter(FilterCondition filter) { + return new ArrayFilter(this, filter); + } + + /** + * Creates an expression that calculates the length of an array. + * + *

Example: + * + *

{@code
+   * // Get the number of items in the 'cart' array
+   * Field.of("cart").arrayLength();
+   * }
+ * + * @return A new {@code Expr} representing the length of the array. + */ + @BetaApi + default ArrayLength arrayLength() { + return new ArrayLength(this); + } + + /** + * Creates an expression that applies a transformation function to each element in an array and + * returns the new array as the result of the evaluation. + * + *

Example: + * + *

{@code
+   * // Convert all strings in the 'names' array to uppercase
+   * Field.of("names").arrayTransform(arrayElement().toUppercase());
+   * }
+ * + * @param transform The {@link Function} to apply to each array element. + * @return A new {@code Expr} representing the transformed array. + */ + @BetaApi + default ArrayTransform arrayTransform(Function transform) { + return new ArrayTransform(this, transform); + } + + // Other Functions + + /** + * Creates an expression that checks if this expression evaluates to 'NaN' (Not a Number). + * + *

Example: + * + *

{@code
+   * // Check if the result of a calculation is NaN
+   * Field.of("value").divide(0).isNaN();
+   * }
+ * + * @return A new {@code Expr} representing the 'isNaN' check. + */ + @BetaApi + default IsNaN isNaN() { + return new IsNaN(this); + } + + /** + * Creates an expression that checks if a field exists in the document. + * + *

Example: + * + *

{@code
+   * // Check if the document has a field named "phoneNumber"
+   * Field.of("phoneNumber").exists();
+   * }
+ * + * @return A new {@code Expr} representing the 'exists' check. + */ + @BetaApi + default Exists exists() { + return new Exists(this); + } + + /** + * Creates an expression that checks if this expression evaluates to null. + * + *

Example: + * + *

{@code
+   * // Check if the 'optionalField' is null
+   * Field.of("optionalField").isNull();
+   * }
+ * + * @return A new {@code Expr} representing the null check. + */ + @BetaApi + default IsNull isNull() { + return new IsNull(this); + } + + // Aggregate Functions + + /** + * Creates an aggregation that calculates the sum of a numeric field across multiple stage inputs. + * + *

Example: + * + *

{@code
+   * // Calculate the total revenue from a set of orders
+   * Field.of("orderAmount").sum().as("totalRevenue");
+   * }
+ * + * @return A new {@code Accumulator} representing the 'sum' aggregation. + */ + @BetaApi + default Sum sum() { + return new Sum(this, false); + } + + /** + * Creates an aggregation that calculates the average (mean) of a numeric field across multiple + * stage inputs. + * + *

Example: + * + *

{@code
+   * // Calculate the average age of users
+   * Field.of("age").avg().as("averageAge");
+   * }
+ * + * @return A new {@code Accumulator} representing the 'avg' aggregation. + */ + @BetaApi + default Avg avg() { + return new Avg(this, false); + } + + /** + * Creates an aggregation that counts the number of stage inputs with valid evaluations of the + * expression or field. + * + *

Example: + * + *

{@code
+   * // Count the total number of products
+   * Field.of("productId").count().as("totalProducts");
+   * }
+ * + * @return A new {@code Accumulator} representing the 'count' aggregation. + */ + @BetaApi + default Count count() { + return new Count(this, false); + } + + /** + * Creates an aggregation that finds the minimum value of a field across multiple stage inputs. + * + *

Example: + * + *

{@code
+   * // Find the lowest price of all products
+   * Field.of("price").min().as("lowestPrice");
+   * }
+ * + * @return A new {@code Accumulator} representing the 'min' aggregation. + */ + @BetaApi + default Min min() { + return new Min(this, false); + } + + /** + * Creates an aggregation that finds the maximum value of a field across multiple stage inputs. + * + *

Example: + * + *

{@code
+   * // Find the highest score in a leaderboard
+   * Field.of("score").max().as("highestScore");
+   * }
+ * + * @return A new {@code Accumulator} representing the 'max' aggregation. + */ + @BetaApi + default Max max() { + return new Max(this, false); + } + + // String Functions + + /** + * Creates an expression that calculates the length of a string. + * + *

Example: + * + *

{@code
+   * // Get the length of the 'name' field
+   * Field.of("name").length();
+   * }
+ * + * @return A new {@code Expr} representing the length of the string. + */ + @BetaApi + default Length length() { + return new Length(this); + } + + /** + * Creates an expression that performs a case-sensitive string comparison. + * + *

Example: + * + *

{@code
+   * // Check if the 'title' field contains the word "guide" (case-sensitive)
+   * Field.of("title").like("%guide%");
+   * }
+ * + * @param pattern The pattern to search for. You can use "%" as a wildcard character. + * @return A new {@code Expr} representing the 'like' comparison. + */ + @BetaApi + default Like like(String pattern) { + return new Like(this, Constant.of(pattern)); + } + + /** + * Creates an expression that checks if a string contains a specified regular expression as a + * substring. + * + *

Example: + * + *

{@code
+   * // Check if the 'description' field contains "example" (case-insensitive)
+   * Field.of("description").regexContains("(?i)example");
+   * }
+ * + * @param regex The regular expression to use for the search. + * @return A new {@code Expr} representing the 'contains' comparison. + */ + @BetaApi + default RegexContains regexContains(String regex) { + return new RegexContains(this, Constant.of(regex)); + } + + /** + * Creates an expression that checks if a string contains a specified regular expression as a + * substring. + * + *

Example: + * + *

{@code
+   * // Check if the 'description' field contains the regular expression stored in field 'regex'
+   * Field.of("description").regexContains(Field.of("regex"));
+   * }
+ * + * @param regex The regular expression to use for the search. + * @return A new {@code Expr} representing the 'contains' comparison. + */ + @BetaApi + default RegexContains regexContains(Expr regex) { + return new RegexContains(this, regex); + } + + /** + * Creates an expression that checks if a string matches a specified regular expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'email' field matches a valid email pattern
+   * Field.of("email").regexMatches("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}");
+   * }
+ * + * @param regex The regular expression to use for the match. + * @return A new {@code Expr} representing the regular expression match. + */ + @BetaApi + default RegexMatch regexMatches(String regex) { + return new RegexMatch(this, Constant.of(regex)); + } + + /** + * Creates an expression that checks if a string matches a specified regular expression. + * + *

Example: + * + *

{@code
+   * // Check if the 'email' field matches a regular expression stored in field 'regex'
+   * Field.of("email").regexMatches(Field.of("regex"));
+   * }
+ * + * @param regex The regular expression to use for the match. + * @return A new {@code Expr} representing the regular expression match. + */ + @BetaApi + default RegexMatch regexMatches(Expr regex) { + return new RegexMatch(this, regex); + } + + /** + * Creates an expression that checks if a string starts with a given prefix. + * + *

Example: + * + *

{@code
+   * // Check if the 'name' field starts with "Mr."
+   * Field.of("name").startsWith("Mr.");
+   * }
+ * + * @param prefix The prefix to check for. + * @return A new {@code Expr} representing the 'starts with' comparison. + */ + @BetaApi + default StartsWith startsWith(String prefix) { + return new StartsWith(this, Constant.of(prefix)); + } + + /** + * Creates an expression that checks if a string starts with a given prefix (represented as an + * expression). + * + *

Example: + * + *

{@code
+   * // Check if the 'fullName' field starts with the value of the 'firstName' field
+   * Field.of("fullName").startsWith(Field.of("firstName"));
+   * }
+ * + * @param prefix The prefix expression to check for. + * @return A new {@code Expr} representing the 'starts with' comparison. + */ + @BetaApi + default StartsWith startsWith(Expr prefix) { + return new StartsWith(this, prefix); + } + + /** + * Creates an expression that checks if a string ends with a given postfix. + * + *

Example: + * + *

{@code
+   * // Check if the 'filename' field ends with ".txt"
+   * Field.of("filename").endsWith(".txt");
+   * }
+ * + * @param postfix The postfix to check for. + * @return A new {@code Expr} representing the 'ends with' comparison. + */ + @BetaApi + default EndsWith endsWith(String postfix) { + return new EndsWith(this, Constant.of(postfix)); + } + + /** + * Creates an expression that checks if a string ends with a given postfix (represented as an + * expression). + * + *

Example: + * + *

{@code
+   * // Check if the 'url' field ends with the value of the 'extension' field
+   * Field.of("url").endsWith(Field.of("extension"));
+   * }
+ * + * @param postfix The postfix expression to check for. + * @return A new {@code Expr} representing the 'ends with' comparison. + */ + @BetaApi + default EndsWith endsWith(Expr postfix) { + return new EndsWith(this, postfix); + } + + /** + * Creates an expression that concatenates string expressions together. + * + *

Example: + * + *

{@code
+   * // Combine the 'firstName', " ", and 'lastName' fields into a single string
+   * Field.of("firstName").strConcat(Constant.of(" "), Field.of("lastName"));
+   * }
+ * + * @param elements The expressions (typically strings) to concatenate. + * @return A new {@code Expr} representing the concatenated string. + */ + @BetaApi + default StrConcat strConcat(Expr... elements) { + return new StrConcat(this, Arrays.asList(elements)); + } + + /** + * Creates an expression that concatenates string functions, fields or constants together. + * + *

Example: + * + *

{@code
+   * // Combine the 'firstName', " ", and 'lastName' fields into a single string
+   * Field.of("firstName").strConcat(" ", Field.of("lastName"));
+   * }
+ * + * @param elements The expressions (typically strings) to concatenate. + * @return A new {@code Expr} representing the concatenated string. + */ + @BetaApi + default StrConcat strConcat(Object... elements) { + return new StrConcat(this, toExprList(elements)); + } + + /** + * Creates an expression that converts a string to lowercase. + * + *

Example: + * + *

{@code
+   * // Convert the 'name' field to lowercase
+   * Field.of("name").toLowerCase();
+   * }
+ * + * @return A new {@code Expr} representing the lowercase string. + */ + @BetaApi + default ToLowercase toLowercase() { + return new ToLowercase(this); + } + + /** + * Creates an expression that converts a string to uppercase. + * + *

Example: + * + *

{@code
+   * // Convert the 'title' field to uppercase
+   * Field.of("title").toUpperCase();
+   * }
+ * + * @return A new {@code Expr} representing the uppercase string. + */ + @BetaApi + default ToUppercase toUppercase() { + return new ToUppercase(this); + } + + /** + * Creates an expression that removes leading and trailing whitespace from a string. + * + *

Example: + * + *

{@code
+   * // Trim whitespace from the 'userInput' field
+   * Field.of("userInput").trim();
+   * }
+ * + * @return A new {@code Expr} representing the trimmed string. + */ + @BetaApi + default Trim trim() { + return new Trim(this); + } + + /** + * Accesses a value from a map (object) field using the provided key. + * + *

Example: + * + *

{@code
+   * // Get the 'city' value from
+   * // the 'address' map field
+   * Field.of("address").mapGet("city");
+   * }
+ * + * @param key The key to access in the map. + * @return A new {@code Expr} representing the value associated with the given key in the map. + */ + @BetaApi + default MapGet mapGet(String key) { + return new MapGet(this, key); + } + + /** + * Calculates the cosine distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the cosine distance between the 'userVector' field and the 'itemVector' field
+   * Field.of("userVector").cosineDistance(Field.of("itemVector"));
+   * }
+ * + * @param other The other vector (represented as an Expr) to compare against. + * @return A new {@code Expr} representing the cosine distance between the two vectors. + */ + @BetaApi + default CosineDistance cosineDistance(Expr other) { + return new CosineDistance(this, other); + } + + /** + * Calculates the Cosine distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the Cosine distance between the 'location' field and a target location
+   * Field.of("location").cosineDistance(new double[] {37.7749, -122.4194});
+   * }
+ * + * @param other The other vector (as an array of doubles) to compare against. + * @return A new {@code Expr} representing the Cosine distance between the two vectors. + */ + @BetaApi + default CosineDistance cosineDistance(double[] other) { + return new CosineDistance(this, Constant.ofVector(other)); + } + + /** + * Calculates the Euclidean distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the Euclidean distance between the 'location' field and a target location
+   * Field.of("location").euclideanDistance(new double[] {37.7749, -122.4194});
+   * }
+ * + * @param other The other vector (as an array of doubles) to compare against. + * @return A new {@code Expr} representing the Euclidean distance between the two vectors. + */ + @BetaApi + default EuclideanDistance euclideanDistance(double[] other) { + return new EuclideanDistance(this, Constant.ofVector(other)); + } + + /** + * Calculates the Euclidean distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the Euclidean distance between two vector fields: 'pointA' and 'pointB'
+   * Field.of("pointA").euclideanDistance(Field.of("pointB"));
+   * }
+ * + * @param other The other vector (represented as an Expr) to compare against. + * @return A new {@code Expr} representing the Euclidean distance between the two vectors. + */ + @BetaApi + default EuclideanDistance euclideanDistance(Expr other) { + return new EuclideanDistance(this, other); + } + + /** + * Calculates the dot product distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the dot product distance between a feature vector and a target vector
+   * Field.of("features").dotProductDistance(new double[] {0.5, 0.8, 0.2});
+   * }
+ * + * @param other The other vector (as an array of doubles) to compare against. + * @return A new {@code Expr} representing the dot product distance between the two vectors. + */ + @BetaApi + default DotProductDistance dotProductDistance(double[] other) { + return new DotProductDistance(this, Constant.ofVector(other)); + } + + /** + * Calculates the dot product distance between two vectors. + * + *

Example: + * + *

{@code
+   * // Calculate the dot product distance between two document vectors: 'docVector1' and 'docVector2'
+   * Field.of("docVector1").dotProductDistance(Field.of("docVector2"));
+   * }
+ * + * @param other The other vector (represented as an Expr) to compare against. + * @return A new {@code Expr} representing the dot product distance between the two vectors. + */ + @BetaApi + default DotProductDistance dotProductDistance(Expr other) { + return new DotProductDistance(this, other); + } + + // Ordering + + /** + * Creates an {@link Ordering} that sorts documents in ascending order based on this expression. + * + *

Example: + * + *

{@code
+   * // Sort documents by the 'name' field in ascending order
+   * firestore.pipeline().collection("users")
+   *   .sort(Field.of("name").ascending());
+   * }
+ * + * @return A new {@code Ordering} for ascending sorting. + */ + @BetaApi + default Ordering ascending() { + return Ordering.ascending(this); + } + + /** + * Creates an {@link Ordering} that sorts documents in descending order based on this expression. + * + *

Example: + * + *

{@code
+   * // Sort documents by the 'createdAt' field in descending order
+   * firestore.pipeline().collection("users")
+   *   .sort(Field.of("createdAt").descending());
+   * }
+ * + * @return A new {@code Ordering} for descending sorting. + */ + @BetaApi + default Ordering descending() { + return Ordering.descending(this); + } + + // Alias + + /** + * Assigns an alias to this expression. + * + *

Aliases are useful for renaming fields in the output of a stage or for giving meaningful + * names to calculated values. + * + *

Example: + * + *

{@code
+   * // Calculate the total price and assign it the alias "totalPrice" and add it to the output.
+   * firestore.pipeline().collection("items")
+   *   .addFields(Field.of("price").multiply(Field.of("quantity")).as("totalPrice"));
+   * }
+ * + * @param alias The alias to assign to this expression. + * @return A new {@code Selectable} (typically an {@link ExprWithAlias}) that wraps this + * expression and associates it with the provided alias. + */ + @BetaApi + default Selectable as(String alias) { + return new ExprWithAlias(this, alias); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ExprWithAlias.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ExprWithAlias.java new file mode 100644 index 000000000..48802af5a --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ExprWithAlias.java @@ -0,0 +1,26 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.InternalApi; + +@InternalApi +public final class ExprWithAlias implements Selectable { + + private final String alias; + private final T expr; + + @InternalApi + ExprWithAlias(T expr, String alias) { + this.expr = expr; + this.alias = alias; + } + + @InternalApi + public String getAlias() { + return alias; + } + + @InternalApi + public T getExpr() { + return expr; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Field.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Field.java new file mode 100644 index 000000000..90e3b7243 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Field.java @@ -0,0 +1,73 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.FieldPath; +import com.google.cloud.firestore.Pipeline; +import com.google.common.base.Objects; +import com.google.firestore.v1.Value; +import javax.annotation.Nullable; + +@BetaApi +public final class Field implements Expr, Selectable { + public static final String DOCUMENT_ID = "__name__"; + private final FieldPath path; + @Nullable private Pipeline pipeline; // Nullable + + private Field(FieldPath path) { + this.path = path; + } + + private Field(Pipeline pipeline, FieldPath path) { + this.pipeline = pipeline; + this.path = path; + } + + @BetaApi + public static Field of(String path) { + if (path.equals(DOCUMENT_ID)) { + return new Field(FieldPath.of("__path__")); + } + return new Field(FieldPath.fromDotSeparatedString(path)); + } + + @BetaApi + public static Field of(Pipeline pipeline, String path) { + if (path.equals(DOCUMENT_ID)) { + return new Field(pipeline, FieldPath.of("__path__")); + } + return new Field(pipeline, FieldPath.fromDotSeparatedString(path)); + } + + @InternalApi + public Value toProto() { + return Value.newBuilder().setFieldReferenceValue(path.toString()).build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Field field = (Field) o; + return Objects.equal(path, field.path) && Objects.equal(pipeline, field.pipeline); + } + + @Override + public int hashCode() { + return Objects.hashCode(path, pipeline); + } + + @InternalApi + public FieldPath getPath() { + return path; + } + + @InternalApi + public Pipeline getPipeline() { + return pipeline; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Fields.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Fields.java new file mode 100644 index 000000000..862944f36 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Fields.java @@ -0,0 +1,34 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@BetaApi +public final class Fields implements Expr, Selectable { + private final List fields; + + private Fields(List fs) { + this.fields = fs; + } + + @BetaApi + public static Fields of(String f1, String... f) { + List fields = Arrays.stream(f).map(Field::of).collect(Collectors.toList()); + fields.add(0, Field.of(f1)); // Add f1 at the beginning + return new Fields(fields); + } + + @BetaApi + public static Fields ofAll() { + return new Fields(Collections.singletonList(Field.of(""))); + } + + @InternalApi + public List getFields() { + return fields; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FilterCondition.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FilterCondition.java new file mode 100644 index 000000000..00eb128b4 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FilterCondition.java @@ -0,0 +1,6 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; + +@BetaApi +public interface FilterCondition extends Expr {} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Function.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Function.java new file mode 100644 index 000000000..96f0ca0c3 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Function.java @@ -0,0 +1,740 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import static com.google.cloud.firestore.pipeline.expressions.FunctionUtils.toExprList; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.DocumentReference; +import com.google.common.base.Objects; +import com.google.common.collect.Lists; +import com.google.firestore.v1.Value; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +@BetaApi +public class Function implements Expr { + private final String name; + private final List params; + + protected Function(String name, List params) { + this.name = name; + this.params = Collections.unmodifiableList(params); + } + + @InternalApi + Value toProto() { + return Value.newBuilder() + .setFunctionValue( + com.google.firestore.v1.Function.newBuilder() + .setName(this.name) + .addAllArgs( + this.params.stream() + .map(FunctionUtils::exprToValue) + .collect(Collectors.toList()))) + .build(); + } + + @BetaApi + public static CollectionId collectionId(String path) { + return new CollectionId(Constant.of(path)); + } + + @BetaApi + public static CollectionId collectionId(DocumentReference ref) { + return new CollectionId(Constant.of(ref.getPath())); + } + + @BetaApi + public static Parent parent(String path) { + return new Parent(Constant.of(path)); + } + + @BetaApi + public static Parent parent(DocumentReference ref) { + return new Parent(Constant.of(ref.getPath())); + } + + @BetaApi + public static Add add(Expr left, Expr right) { + return new Add(left, right); + } + + @BetaApi + public static Add add(Expr left, Object right) { + return new Add(left, Constant.of(right)); + } + + @BetaApi + public static Add add(String left, Expr right) { + return new Add(Field.of(left), right); + } + + @BetaApi + public static Add add(String left, Object right) { + return new Add(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Subtract subtract(Expr left, Expr right) { + return new Subtract(left, right); + } + + @BetaApi + public static Subtract subtract(Expr left, Object right) { + return new Subtract(left, Constant.of(right)); + } + + @BetaApi + public static Subtract subtract(String left, Expr right) { + return new Subtract(Field.of(left), right); + } + + @BetaApi + public static Subtract subtract(String left, Object right) { + return new Subtract(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Multiply multiply(Expr left, Expr right) { + return new Multiply(left, right); + } + + @BetaApi + public static Multiply multiply(Expr left, Object right) { + return new Multiply(left, Constant.of(right)); + } + + @BetaApi + public static Multiply multiply(String left, Expr right) { + return new Multiply(Field.of(left), right); + } + + @BetaApi + public static Multiply multiply(String left, Object right) { + return new Multiply(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Divide divide(Expr left, Expr right) { + return new Divide(left, right); + } + + @BetaApi + public static Divide divide(Expr left, Object right) { + return new Divide(left, Constant.of(right)); + } + + @BetaApi + public static Divide divide(String left, Expr right) { + return new Divide(Field.of(left), right); + } + + @BetaApi + public static Divide divide(String left, Object right) { + return new Divide(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Eq eq(Expr left, Expr right) { + return new Eq(left, right); + } + + @BetaApi + public static Eq eq(Expr left, Object right) { + return new Eq(left, Constant.of(right)); + } + + @BetaApi + public static Eq eq(String left, Expr right) { + return new Eq(Field.of(left), right); + } + + @BetaApi + public static Eq eq(String left, Object right) { + return new Eq(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Neq neq(Expr left, Expr right) { + return new Neq(left, right); + } + + @BetaApi + public static Neq neq(Expr left, Object right) { + return new Neq(left, Constant.of(right)); + } + + @BetaApi + public static Neq neq(String left, Expr right) { + return new Neq(Field.of(left), right); + } + + @BetaApi + public static Neq neq(String left, Object right) { + return new Neq(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Gt gt(Expr left, Expr right) { + return new Gt(left, right); + } + + @BetaApi + public static Gt gt(Expr left, Object right) { + return new Gt(left, Constant.of(right)); + } + + @BetaApi + public static Gt gt(String left, Expr right) { + return new Gt(Field.of(left), right); + } + + @BetaApi + public static Gt gt(String left, Object right) { + return new Gt(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Gte gte(Expr left, Expr right) { + return new Gte(left, right); + } + + @BetaApi + public static Gte gte(Expr left, Object right) { + return new Gte(left, Constant.of(right)); + } + + @BetaApi + public static Gte gte(String left, Expr right) { + return new Gte(Field.of(left), right); + } + + @BetaApi + public static Gte gte(String left, Object right) { + return new Gte(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Lt lt(Expr left, Expr right) { + return new Lt(left, right); + } + + @BetaApi + public static Lt lt(Expr left, Object right) { + return new Lt(left, Constant.of(right)); + } + + @BetaApi + public static Lt lt(String left, Expr right) { + return new Lt(Field.of(left), right); + } + + @BetaApi + public static Lt lt(String left, Object right) { + return new Lt(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Lte lte(Expr left, Expr right) { + return new Lte(left, right); + } + + @BetaApi + public static Lte lte(Expr left, Object right) { + return new Lte(left, Constant.of(right)); + } + + @BetaApi + public static Lte lte(String left, Expr right) { + return new Lte(Field.of(left), right); + } + + @BetaApi + public static Lte lte(String left, Object right) { + return new Lte(Field.of(left), Constant.of(right)); + } + + @BetaApi + public static Exists exists(String field) { + return new Exists(Field.of(field)); + } + + @BetaApi + public static Exists exists(Expr field) { + return new Exists(field); + } + + @BetaApi + public static In inAny(Expr left, List values) { + List othersAsExpr = + values.stream() + .map(obj -> (obj instanceof Expr) ? (Expr) obj : Constant.of(obj)) + .collect(Collectors.toList()); + return new In(left, othersAsExpr); + } + + @BetaApi + public static In inAny(String left, List values) { + return inAny(Field.of(left), values); + } + + @BetaApi + public static Not notInAny(Expr left, List values) { + return new Not(inAny(left, values)); + } + + @BetaApi + public static Not notInAny(String left, List values) { + return new Not(inAny(Field.of(left), values)); + } + + @BetaApi + public static And and(FilterCondition left, FilterCondition right) { + return new And(Lists.newArrayList(left, right)); + } + + @BetaApi + public static And and(FilterCondition left, FilterCondition... other) { + List conditions = Lists.newArrayList(left); + conditions.addAll(Arrays.asList(other)); + return new And(conditions); + } + + @BetaApi + public static Or or(FilterCondition left, FilterCondition right) { + return new Or(Lists.newArrayList(left, right)); + } + + @BetaApi + public static Or or(FilterCondition left, FilterCondition... other) { + List conditions = Lists.newArrayList(left); + conditions.addAll(Arrays.asList(other)); + return new Or(conditions); + } + + @BetaApi + public static Xor xor(FilterCondition left, FilterCondition right) { + return new Xor(Lists.newArrayList(left, right)); + } + + @BetaApi + public static Xor xor(FilterCondition left, FilterCondition... other) { + List conditions = Lists.newArrayList(left); + conditions.addAll(Arrays.asList(other)); + return new Xor(conditions); + } + + @BetaApi + public static If ifThen(FilterCondition condition, Expr thenExpr) { + return new If(condition, thenExpr, null); + } + + @BetaApi + public static If ifThenElse(FilterCondition condition, Expr thenExpr, Expr elseExpr) { + return new If(condition, thenExpr, elseExpr); + } + + @BetaApi + public static ArrayConcat arrayConcat(Expr expr, Expr... elements) { + return new ArrayConcat(expr, Arrays.asList(elements)); + } + + @BetaApi + public static ArrayConcat arrayConcat(Expr expr, Object... elements) { + return new ArrayConcat(expr, toExprList(elements)); + } + + @BetaApi + public static ArrayConcat arrayConcat(String field, Expr... elements) { + return new ArrayConcat(Field.of(field), Arrays.asList(elements)); + } + + @BetaApi + public static ArrayConcat arrayConcat(String field, Object... elements) { + return new ArrayConcat(Field.of(field), toExprList(elements)); + } + + @BetaApi + public static ArrayContains arrayContains(Expr expr, Expr element) { + return new ArrayContains(expr, element); + } + + @BetaApi + public static ArrayContains arrayContains(String field, Expr element) { + return new ArrayContains(Field.of(field), element); + } + + @BetaApi + public static ArrayContains arrayContains(Expr expr, Object element) { + return new ArrayContains(expr, Constant.of(element)); + } + + @BetaApi + public static ArrayContains arrayContains(String field, Object element) { + return new ArrayContains(Field.of(field), Constant.of(element)); + } + + @BetaApi + public static ArrayContainsAll arrayContainsAll(Expr expr, Expr... elements) { + return new ArrayContainsAll(expr, Arrays.asList(elements)); + } + + @BetaApi + public static ArrayContainsAll arrayContainsAll(Expr expr, Object... elements) { + return new ArrayContainsAll(expr, toExprList(elements)); + } + + @BetaApi + public static ArrayContainsAll arrayContainsAll(String field, Expr... elements) { + return new ArrayContainsAll(Field.of(field), Arrays.asList(elements)); + } + + @BetaApi + public static ArrayContainsAll arrayContainsAll(String field, Object... elements) { + return new ArrayContainsAll(Field.of(field), toExprList(elements)); + } + + @BetaApi + public static ArrayContainsAny arrayContainsAny(Expr expr, Expr... elements) { + return new ArrayContainsAny(expr, Arrays.asList(elements)); + } + + @BetaApi + public static ArrayContainsAny arrayContainsAny(Expr expr, Object... elements) { + return new ArrayContainsAny(expr, toExprList(elements)); + } + + @BetaApi + public static ArrayContainsAny arrayContainsAny(String field, Expr... elements) { + return new ArrayContainsAny(Field.of(field), Arrays.asList(elements)); + } + + @BetaApi + public static ArrayContainsAny arrayContainsAny(String field, Object... elements) { + return new ArrayContainsAny(Field.of(field), toExprList(elements)); + } + + @BetaApi + public static ArrayFilter arrayFilter(Expr expr, FilterCondition filter) { + return new ArrayFilter(expr, filter); + } + + @BetaApi + public static ArrayFilter arrayFilter(String field, FilterCondition filter) { + return new ArrayFilter(Field.of(field), filter); + } + + @BetaApi + public static ArrayLength arrayLength(Expr expr) { + return new ArrayLength(expr); + } + + @BetaApi + public static ArrayLength arrayLength(String field) { + return new ArrayLength(Field.of(field)); + } + + @BetaApi + public static ArrayTransform arrayTransform(Expr expr, Function transform) { + return new ArrayTransform(expr, transform); + } + + @BetaApi + public static ArrayTransform arrayTransform(String field, Function transform) { + return new ArrayTransform(Field.of(field), transform); + } + + @BetaApi + public static Length length(Expr expr) { + return new Length(expr); + } + + @BetaApi + public static Length length(String field) { + return new Length(Field.of(field)); + } + + @BetaApi + public static Like like(Expr expr, String pattern) { + return new Like(expr, Constant.of(pattern)); + } + + @BetaApi + public static Like like(String field, String pattern) { + return new Like(Field.of(field), Constant.of(pattern)); + } + + @BetaApi + public static RegexContains regexContains(Expr expr, String pattern) { + return new RegexContains(expr, Constant.of(pattern)); + } + + @BetaApi + public static RegexContains regexContains(String field, String pattern) { + return new RegexContains(Field.of(field), Constant.of(pattern)); + } + + @BetaApi + public static RegexMatch regexMatch(Expr expr, String pattern) { + return new RegexMatch(expr, Constant.of(pattern)); + } + + @BetaApi + public static RegexMatch regexMatch(String field, String pattern) { + return new RegexMatch(Field.of(field), Constant.of(pattern)); + } + + @BetaApi + public static StartsWith startsWith(String field, String prefix) { + return new StartsWith(Field.of(field), Constant.of(prefix)); + } + + @BetaApi + public static StartsWith startsWith(String field, Expr prefix) { + return new StartsWith(Field.of(field), prefix); + } + + @BetaApi + public static StartsWith startsWith(Expr expr, Expr prefix) { + return new StartsWith(expr, prefix); + } + + @BetaApi + public static EndsWith endsWith(String field, String prefix) { + return new EndsWith(Field.of(field), Constant.of(prefix)); + } + + @BetaApi + public static EndsWith endsWith(String field, Expr prefix) { + return new EndsWith(Field.of(field), prefix); + } + + @BetaApi + public static EndsWith endsWith(Expr expr, Expr prefix) { + return new EndsWith(expr, prefix); + } + + @BetaApi + public static StrConcat strConcat(Expr expr, Expr... elements) { + return new StrConcat(expr, Arrays.asList(elements)); + } + + @BetaApi + public static StrConcat strConcat(Expr expr, Object... elements) { + return new StrConcat(expr, toExprList(elements)); + } + + @BetaApi + public static StrConcat strConcat(String field, Expr... elements) { + return new StrConcat(Field.of(field), Arrays.asList(elements)); + } + + @BetaApi + public static StrConcat strConcat(String field, Object... elements) { + return new StrConcat(Field.of(field), toExprList(elements)); + } + + @BetaApi + public static ToLowercase toLowercase(Expr expr) { + return new ToLowercase(expr); + } + + @BetaApi + public static ToLowercase toLowercase(String field) { + return new ToLowercase(Field.of(field)); + } + + @BetaApi + public static ToUppercase toUppercase(Expr expr) { + return new ToUppercase(expr); + } + + @BetaApi + public static ToUppercase toUppercase(String field) { + return new ToUppercase(Field.of(field)); + } + + @BetaApi + public static Trim trim(Expr expr) { + return new Trim(expr); + } + + @BetaApi + public static Trim trim(String field) { + return new Trim(Field.of(field)); + } + + @BetaApi + public static IsNaN isNaN(Expr expr) { + return new IsNaN(expr); + } + + @BetaApi + public static IsNaN isNaN(String field) { + return new IsNaN(Field.of(field)); + } + + @BetaApi + public static IsNull isNull(Expr expr) { + return new IsNull(expr); + } + + @BetaApi + public static IsNull isNull(String field) { + return new IsNull(Field.of(field)); + } + + @BetaApi + public static Not not(FilterCondition expr) { + return new Not(expr); + } + + @BetaApi + public static Sum sum(Expr expr) { + return new Sum(expr, false); + } + + @BetaApi + public static Sum sum(String field) { + return new Sum(Field.of(field), false); + } + + @BetaApi + public static Avg avg(Expr expr) { + return new Avg(expr, false); + } + + @BetaApi + public static Avg avg(String field) { + return new Avg(Field.of(field), false); + } + + @BetaApi + public static Min min(Expr expr) { + return new Min(expr, false); // Corrected constructor call + } + + @BetaApi + public static Min min(String field) { + return new Min(Field.of(field), false); // Corrected constructor call + } + + @BetaApi + public static Max max(Expr expr) { + return new Max(expr, false); // Corrected constructor call + } + + @BetaApi + public static Max max(String field) { + return new Max(Field.of(field), false); // Corrected constructor call + } + + @BetaApi + public static Count count(Expr expr) { + return new Count(expr, false); + } + + @BetaApi + public static Count count(String field) { + return new Count(Field.of(field), false); + } + + @BetaApi + public static CountIf countIf(FilterCondition condition) { + return new CountIf(condition, false); + } + + @BetaApi + public static Count countAll() { + return new Count(null, false); + } + + @BetaApi + public static CosineDistance cosineDistance(Expr expr, Expr other) { + return new CosineDistance(expr, other); + } + + @BetaApi + public static CosineDistance cosineDistance(Expr expr, double[] other) { + return new CosineDistance(expr, Constant.ofVector(other)); + } + + @BetaApi + public static CosineDistance cosineDistance(String field, Expr other) { + return new CosineDistance(Field.of(field), other); + } + + @BetaApi + public static CosineDistance cosineDistance(String field, double[] other) { + return new CosineDistance(Field.of(field), Constant.ofVector(other)); + } + + @BetaApi + public static DotProductDistance dotProductDistance(Expr expr, Expr other) { + return new DotProductDistance(expr, other); + } + + @BetaApi + public static DotProductDistance dotProductDistance(Expr expr, double[] other) { + return new DotProductDistance(expr, Constant.ofVector(other)); + } + + @BetaApi + public static DotProductDistance dotProductDistance(String field, Expr other) { + return new DotProductDistance(Field.of(field), other); + } + + @BetaApi + public static DotProductDistance dotProductDistance(String field, double[] other) { + return new DotProductDistance(Field.of(field), Constant.ofVector(other)); + } + + @BetaApi + public static EuclideanDistance euclideanDistance(Expr expr, Expr other) { + return new EuclideanDistance(expr, other); + } + + @BetaApi + public static EuclideanDistance euclideanDistance(Expr expr, double[] other) { + return new EuclideanDistance(expr, Constant.ofVector(other)); + } + + @BetaApi + public static EuclideanDistance euclideanDistance(String field, Expr other) { + return new EuclideanDistance(Field.of(field), other); + } + + @BetaApi + public static EuclideanDistance euclideanDistance(String field, double[] other) { + return new EuclideanDistance(Field.of(field), Constant.ofVector(other)); + } + + @BetaApi + public static ArrayElement arrayElement() { + return new ArrayElement(); + } + + @BetaApi + public static Function function(String name, List params) { + return new Function(name, params); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Function function = (Function) o; + return Objects.equal(name, function.name) && Objects.equal(params, function.params); + } + + @Override + public int hashCode() { + return Objects.hashCode(name, params); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FunctionUtils.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FunctionUtils.java new file mode 100644 index 000000000..12b6adcd8 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/FunctionUtils.java @@ -0,0 +1,41 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.InternalApi; +import com.google.firestore.v1.ArrayValue; +import com.google.firestore.v1.Value; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@InternalApi +public final class FunctionUtils { + @InternalApi + public static Value exprToValue(Expr expr) { + if (expr instanceof Constant) { + return ((Constant) expr).toProto(); + } else if (expr instanceof Field) { + return ((Field) expr).toProto(); + } else if (expr instanceof Function) { + return ((Function) expr).toProto(); + } else if (expr instanceof ListOfExprs) { + ListOfExprs listOfExprs = (ListOfExprs) expr; + return Value.newBuilder() + .setArrayValue( + ArrayValue.newBuilder() + .addAllValues( + listOfExprs.getConditions().stream() + .map(FunctionUtils::exprToValue) + .collect(Collectors.toList()))) + .build(); + } else { + throw new IllegalArgumentException("Unsupported expression type: " + expr.getClass()); + } + } + + @InternalApi + static List toExprList(Object[] other) { + return Arrays.stream(other) + .map(obj -> (obj instanceof Expr) ? (Expr) obj : Constant.of(obj)) + .collect(Collectors.toList()); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gt.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gt.java new file mode 100644 index 000000000..94fa72715 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gt.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Gt extends Function implements FilterCondition { + @InternalApi + Gt(Expr left, Expr right) { + super("gt", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gte.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gte.java new file mode 100644 index 000000000..763b376c0 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Gte.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Gte extends Function implements FilterCondition { + @InternalApi + Gte(Expr left, Expr right) { + super("gte", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/If.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/If.java new file mode 100644 index 000000000..ba48a4afe --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/If.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class If extends Function implements FilterCondition { + @InternalApi + If(FilterCondition condition, Expr trueExpr, Expr falseExpr) { + super("if", Lists.newArrayList(condition, trueExpr, falseExpr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/In.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/In.java new file mode 100644 index 000000000..6d5f4559f --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/In.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.List; + +@BetaApi +public final class In extends Function implements FilterCondition { + @InternalApi + In(Expr left, List others) { + super("in", Lists.newArrayList(left, new ListOfExprs(others))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNaN.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNaN.java new file mode 100644 index 000000000..39216b0a2 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNaN.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class IsNaN extends Function implements FilterCondition { + @InternalApi + IsNaN(Expr value) { + super("is_nan", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNull.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNull.java new file mode 100644 index 000000000..a84023223 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/IsNull.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class IsNull extends Function implements FilterCondition { + @InternalApi + IsNull(Expr value) { + super("is_null", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Length.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Length.java new file mode 100644 index 000000000..cf410a558 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Length.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Length extends Function { + @InternalApi + Length(Expr expr) { + super("length", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Like.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Like.java new file mode 100644 index 000000000..8476f9cca --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Like.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Like extends Function implements FilterCondition { + @InternalApi + Like(Expr expr, Expr pattern) { + super("like", Lists.newArrayList(expr, pattern)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ListOfExprs.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ListOfExprs.java new file mode 100644 index 000000000..c52810b98 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ListOfExprs.java @@ -0,0 +1,20 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.InternalApi; +import com.google.common.collect.ImmutableList; +import java.util.List; + +@InternalApi +public final class ListOfExprs implements Expr { + private final ImmutableList conditions; + + @InternalApi + ListOfExprs(List list) { + this.conditions = ImmutableList.copyOf(list); + } + + @InternalApi + public List getConditions() { + return conditions; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lt.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lt.java new file mode 100644 index 000000000..d07078cf9 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lt.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Lt extends Function implements FilterCondition { + @InternalApi + Lt(Expr left, Expr right) { + super("lt", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lte.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lte.java new file mode 100644 index 000000000..4e0416379 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Lte.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Lte extends Function implements FilterCondition { + @InternalApi + Lte(Expr left, Expr right) { + super("lte", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/MapGet.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/MapGet.java new file mode 100644 index 000000000..eab5163e3 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/MapGet.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class MapGet extends Function { + @InternalApi + MapGet(Expr map, String name) { + super("map_get", Lists.newArrayList(map, Constant.of(name))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Max.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Max.java new file mode 100644 index 000000000..e15b6548a --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Max.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Max extends Function implements Accumulator { + @InternalApi + Max(Expr value, boolean distinct) { + super("max", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Min.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Min.java new file mode 100644 index 000000000..fe3443c3a --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Min.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Min extends Function implements Accumulator { + @InternalApi + Min(Expr value, boolean distinct) { + super("min", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Multiply.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Multiply.java new file mode 100644 index 000000000..c353385e8 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Multiply.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Multiply extends Function { + @InternalApi + Multiply(Expr left, Expr right) { + super("multiply", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Neq.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Neq.java new file mode 100644 index 000000000..39e2ca042 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Neq.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Neq extends Function implements FilterCondition { + @InternalApi + Neq(Expr left, Expr right) { + super("neq", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Not.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Not.java new file mode 100644 index 000000000..0d8afb3e6 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Not.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Not extends Function implements FilterCondition { + @InternalApi + Not(Expr condition) { + super("not", Lists.newArrayList(condition)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Or.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Or.java new file mode 100644 index 000000000..e99628a58 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Or.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import java.util.List; + +@BetaApi +public final class Or extends Function implements FilterCondition { + @InternalApi + Or(List conditions) { + super("or", conditions); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Ordering.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Ordering.java new file mode 100644 index 000000000..c5547c2ad --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Ordering.java @@ -0,0 +1,63 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import static com.google.cloud.firestore.PipelineUtils.encodeValue; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.firestore.v1.MapValue; +import com.google.firestore.v1.Value; +import java.util.Locale; + +@BetaApi +public final class Ordering { + + private final Expr expr; + private Ordering.Direction dir = Ordering.Direction.ASCENDING; + + private Ordering(Expr expr, Ordering.Direction dir) { + this.expr = expr; + this.dir = dir; + } + + @BetaApi + public enum Direction { + ASCENDING, + DESCENDING; + + @Override + public String toString() { + return name().toLowerCase(Locale.getDefault()); + } + } + + @InternalApi + public Value toProto() { + return Value.newBuilder() + .setMapValue( + MapValue.newBuilder() + .putFields("direction", encodeValue(dir.toString())) + .putFields("expression", encodeValue(expr)) + .build()) + .build(); + } + + @BetaApi + public static Ordering ascending(Expr expr) { + return new Ordering(expr, Direction.ASCENDING); + } + + @BetaApi + public static Ordering descending(Expr expr) { + return new Ordering(expr, Direction.DESCENDING); + } + + @InternalApi + public Expr getExpr() { + return expr; + } + + @InternalApi + public Ordering.Direction getDir() { + return dir; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Parent.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Parent.java new file mode 100644 index 000000000..3dfa5d752 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Parent.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Parent extends Function { + + @InternalApi + Parent(Expr value) { + super("parent", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexContains.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexContains.java new file mode 100644 index 000000000..a441be091 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexContains.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class RegexContains extends Function implements FilterCondition { + @InternalApi + RegexContains(Expr expr, Expr regex) { + super("regex_contains", Lists.newArrayList(expr, regex)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexMatch.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexMatch.java new file mode 100644 index 000000000..c5221335f --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/RegexMatch.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class RegexMatch extends Function implements FilterCondition { + @InternalApi + RegexMatch(Expr expr, Expr regex) { + super("regex_match", Lists.newArrayList(expr, regex)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Selectable.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Selectable.java new file mode 100644 index 000000000..0afbbd434 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Selectable.java @@ -0,0 +1,6 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; + +@BetaApi +public interface Selectable {} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StartsWith.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StartsWith.java new file mode 100644 index 000000000..b35fbd064 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StartsWith.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class StartsWith extends Function implements FilterCondition { + @InternalApi + StartsWith(Expr expr, Expr prefix) { + super("starts_with", Lists.newArrayList(expr, prefix)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StrConcat.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StrConcat.java new file mode 100644 index 000000000..e3f9ca75a --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/StrConcat.java @@ -0,0 +1,14 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; +import java.util.List; + +@BetaApi +public final class StrConcat extends Function { + @InternalApi + StrConcat(Expr first, List exprs) { + super("str_concat", Lists.asList(first, exprs.toArray(new Expr[] {}))); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Subtract.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Subtract.java new file mode 100644 index 000000000..ceb353bad --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Subtract.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Subtract extends Function { + @InternalApi + Subtract(Expr left, Expr right) { + super("subtract", Lists.newArrayList(left, right)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Sum.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Sum.java new file mode 100644 index 000000000..df016d9f7 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Sum.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Sum extends Function implements Accumulator { + @InternalApi + Sum(Expr value, boolean distinct) { + super("sum", Lists.newArrayList(value)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLower.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLower.java new file mode 100644 index 000000000..6013eeb15 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLower.java @@ -0,0 +1,9 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.common.collect.Lists; + +public final class ToLower extends Function { + ToLower(Expr expr) { + super("to_lower", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLowercase.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLowercase.java new file mode 100644 index 000000000..0e07aa469 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToLowercase.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ToLowercase extends Function { + @InternalApi + ToLowercase(Expr expr) { + super("to_lowercase", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUpper.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUpper.java new file mode 100644 index 000000000..9e0bffee7 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUpper.java @@ -0,0 +1,9 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.common.collect.Lists; + +public final class ToUpper extends Function { + ToUpper(Expr expr) { + super("to_upper", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUppercase.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUppercase.java new file mode 100644 index 000000000..06105f1d2 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/ToUppercase.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class ToUppercase extends Function { + @InternalApi + ToUppercase(Expr expr) { + super("to_uppercase", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Trim.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Trim.java new file mode 100644 index 000000000..fe4d461d1 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Trim.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.common.collect.Lists; + +@BetaApi +public final class Trim extends Function { + @InternalApi + Trim(Expr expr) { + super("trim", Lists.newArrayList(expr)); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Xor.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Xor.java new file mode 100644 index 000000000..5dd5b77bc --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/expressions/Xor.java @@ -0,0 +1,13 @@ +package com.google.cloud.firestore.pipeline.expressions; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import java.util.List; + +@BetaApi +public final class Xor extends Function implements FilterCondition { + @InternalApi + Xor(List conditions) { + super("xor", conditions); + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/AddFields.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/AddFields.java new file mode 100644 index 000000000..01b55c8f1 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/AddFields.java @@ -0,0 +1,27 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import java.util.Map; + +@InternalApi +public final class AddFields implements Stage { + + private static final String name = "add_fields"; + private final Map fields; + + @InternalApi + public AddFields(Map fields) { + this.fields = fields; + } + + @InternalApi + public Map getFields() { + return fields; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Aggregate.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Aggregate.java new file mode 100644 index 000000000..d3e9459ea --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Aggregate.java @@ -0,0 +1,64 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.PipelineUtils; +import com.google.cloud.firestore.pipeline.expressions.Accumulator; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import com.google.cloud.firestore.pipeline.expressions.ExprWithAlias; +import com.google.cloud.firestore.pipeline.expressions.Selectable; +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +@BetaApi +public final class Aggregate implements Stage { + + private static final String name = "aggregate"; + private final Map groups; + private final Map accumulators; + + @BetaApi + public Aggregate withGroups(String... fields) { + return new Aggregate(PipelineUtils.fieldNamesToMap(fields), this.accumulators); + } + + @BetaApi + public Aggregate withGroups(Selectable... selectables) { + return new Aggregate(PipelineUtils.selectablesToMap(selectables), this.accumulators); + } + + @BetaApi + public static Aggregate withAccumulators(ExprWithAlias... accumulators) { + if (accumulators.length == 0) { + throw new IllegalArgumentException( + "Must specify at least one accumulator for aggregate() stage. There is a distinct() stage if only distinct group values are needed."); + } + + return new Aggregate( + Collections.emptyMap(), + Arrays.stream(accumulators) + .collect(Collectors.toMap(ExprWithAlias::getAlias, ExprWithAlias::getExpr))); + } + + private Aggregate(Map groups, Map accumulators) { + this.groups = groups; + this.accumulators = accumulators; + } + + @InternalApi + Map getGroups() { + return groups; + } + + @InternalApi + Map getAccumulators() { + return accumulators; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Collection.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Collection.java new file mode 100644 index 000000000..3f9e2889f --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Collection.java @@ -0,0 +1,30 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import javax.annotation.Nonnull; + +@InternalApi +public final class Collection implements Stage { + + private static final String name = "collection"; + @Nonnull private final String path; + + @InternalApi + public Collection(@Nonnull String path) { + if (!path.startsWith("/")) { + this.path = "/" + path; + } else { + this.path = path; + } + } + + @InternalApi + public String getPath() { + return path; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/CollectionGroup.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/CollectionGroup.java new file mode 100644 index 000000000..c6b2c0b67 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/CollectionGroup.java @@ -0,0 +1,25 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; + +@InternalApi +public final class CollectionGroup implements Stage { + + private static final String name = "collection_group"; + private final String collectionId; + + @InternalApi + public CollectionGroup(String collectionId) { + this.collectionId = collectionId; + } + + @InternalApi + public String getCollectionId() { + return collectionId; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Database.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Database.java new file mode 100644 index 000000000..027077ac1 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Database.java @@ -0,0 +1,16 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; + +@InternalApi +public final class Database implements Stage { + private static final String name = "database"; + + @InternalApi + public Database() {} + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Distinct.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Distinct.java new file mode 100644 index 000000000..d41127b81 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Distinct.java @@ -0,0 +1,28 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import java.util.Map; + +@BetaApi +public final class Distinct implements Stage { + + private static final String name = "distinct"; + private final Map groups; + + @InternalApi + public Distinct(Map groups) { + this.groups = groups; + } + + @InternalApi + Map getGroups() { + return groups; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Documents.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Documents.java new file mode 100644 index 000000000..8c6b24591 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Documents.java @@ -0,0 +1,35 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.DocumentReference; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@InternalApi +public final class Documents implements Stage { + + private static final String name = "documents"; + private List documents; + + @InternalApi + Documents(List documents) { + this.documents = documents; + } + + @InternalApi + public static Documents of(DocumentReference... documents) { + return new Documents( + Arrays.stream(documents).map(doc -> "/" + doc.getPath()).collect(Collectors.toList())); + } + + @InternalApi + public List getDocuments() { + return documents; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/FindNearest.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/FindNearest.java new file mode 100644 index 000000000..ab444c67c --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/FindNearest.java @@ -0,0 +1,155 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import com.google.cloud.firestore.pipeline.expressions.Field; +import javax.annotation.Nullable; + +public final class FindNearest implements Stage { + + private static final String name = "find_nearest"; + private final Expr property; + private final double[] vector; + private final FindNearest.FindNearestOptions options; + + @InternalApi + public FindNearest(Expr property, double[] vector, FindNearest.FindNearestOptions options) { + this.property = property; + this.vector = vector; + this.options = options; + } + + @Override + @InternalApi + public String getName() { + return name; + } + + @InternalApi + public Expr getProperty() { + return property; + } + + @InternalApi + public double[] getVector() { + return vector; + } + + @InternalApi + public FindNearestOptions getOptions() { + return options; + } + + // Nested interfaces and classes + public interface DistanceMeasure { + + enum Type { + EUCLIDEAN, + COSINE, + DOT_PRODUCT + } + + static FindNearest.DistanceMeasure euclidean() { + return new FindNearest.EuclideanDistanceMeasure(); + } + + static FindNearest.DistanceMeasure cosine() { + return new FindNearest.CosineDistanceMeasure(); + } + + static FindNearest.DistanceMeasure dotProduct() { + return new FindNearest.DotProductDistanceMeasure(); + } + + static FindNearest.DistanceMeasure generic(String name) { + return new FindNearest.GenericDistanceMeasure(name); + } + + @InternalApi + String toProtoString(); + } + + static class EuclideanDistanceMeasure implements FindNearest.DistanceMeasure { + + @Override + @InternalApi + public String toProtoString() { + return "euclidean"; + } + } + + static class CosineDistanceMeasure implements FindNearest.DistanceMeasure { + + @Override + @InternalApi + public String toProtoString() { + return "cosine"; + } + } + + static class DotProductDistanceMeasure implements FindNearest.DistanceMeasure { + + @Override + @InternalApi + public String toProtoString() { + return "dot_product"; + } + } + + static class GenericDistanceMeasure implements FindNearest.DistanceMeasure { + + String name; + + public GenericDistanceMeasure(String name) { + this.name = name; + } + + @Override + @InternalApi + public String toProtoString() { + return name; + } + } + + public static class FindNearestOptions { + + private final Long limit; + private final FindNearest.DistanceMeasure distanceMeasure; + + @Nullable private final Field distanceField; + + private FindNearestOptions(Long limit, FindNearest.DistanceMeasure distanceMeasure) { + this.limit = limit; + this.distanceMeasure = distanceMeasure; + this.distanceField = null; + } + + private FindNearestOptions( + Long limit, FindNearest.DistanceMeasure distanceMeasure, Field field) { + this.limit = limit; + this.distanceMeasure = distanceMeasure; + this.distanceField = field; + } + + public static FindNearest.FindNearestOptions withLimitAndMeasure( + long limit, FindNearest.DistanceMeasure distanceMeasure) { + return new FindNearest.FindNearestOptions(limit, distanceMeasure); + } + + public FindNearest.FindNearestOptions withDistanceField(String name) { + return new FindNearest.FindNearestOptions(limit, distanceMeasure, Field.of(name)); + } + + public Long getLimit() { + return limit; + } + + public DistanceMeasure getDistanceMeasure() { + return distanceMeasure; + } + + public Field getDistanceField() { + return distanceField; + } + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/GenericStage.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/GenericStage.java new file mode 100644 index 000000000..6910a87cf --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/GenericStage.java @@ -0,0 +1,28 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import java.util.List; + +@InternalApi +public final class GenericStage implements Stage { + + private final String name; + private List params; + + @InternalApi + public GenericStage(String name, List params) { + this.name = name; + this.params = params; + } + + @Override + @InternalApi + public String getName() { + return name; + } + + @InternalApi + public List getParams() { + return params; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Join.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Join.java new file mode 100644 index 000000000..6d9581ca5 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Join.java @@ -0,0 +1,69 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.Pipeline; +import com.google.cloud.firestore.pipeline.expressions.Field; +import com.google.cloud.firestore.pipeline.expressions.FilterCondition; + +@BetaApi +public class Join implements Stage { + private final Type type; + private final FilterCondition condition; + private final Field alias; + private final Pipeline otherPipeline; + private final Field otherAlias; + + @InternalApi + Join( + Type type, FilterCondition condition, Field alias, Pipeline otherPipeline, Field otherAlias) { + this.type = type; + this.condition = condition; + this.alias = alias; + this.otherPipeline = otherPipeline; + this.otherAlias = otherAlias; + } + + @BetaApi + public static Join with(Pipeline other, Type type) { + return new Join(type, null, null, null, null); + } + + @BetaApi + public Join onCondition(FilterCondition condition) { + return new Join(this.type, condition, this.alias, this.otherPipeline, this.otherAlias); + } + + @BetaApi + public Join onFields(String... fields) { + return new Join(this.type, condition, this.alias, this.otherPipeline, this.otherAlias); + } + + @BetaApi + public Join withThisAlias(String alias) { + return new Join(this.type, condition, this.alias, this.otherPipeline, this.otherAlias); + } + + @BetaApi + public Join withOtherAlias(String alias) { + return new Join(this.type, condition, this.alias, this.otherPipeline, this.otherAlias); + } + + @Override + public String getName() { + return "join"; + } + + @InternalApi + public enum Type { + CROSS, + INNER, + FULL, + LEFT, + RIGHT, + LEFT_SEMI, + RIGHT_SEMI, + LEFT_ANTI_SEMI, + RIGHT_ANTI_SEMI + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Limit.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Limit.java new file mode 100644 index 000000000..b0230ac13 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Limit.java @@ -0,0 +1,26 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; + +@InternalApi +public final class Limit implements Stage { + + private static final String name = "limit"; + private int limit; + + @InternalApi + public Limit(int limit) { + this.limit = limit; + } + + @InternalApi + public int getLimit() { + return limit; + } + + @Override + @InternalApi + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Offset.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Offset.java new file mode 100644 index 000000000..eeaf2a21e --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Offset.java @@ -0,0 +1,26 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; + +@InternalApi +public final class Offset implements Stage { + + private static final String name = "offset"; + private final int offset; + + @InternalApi + public Offset(int offset) { + this.offset = offset; + } + + @InternalApi + public int getOffset() { + return offset; + } + + @Override + @InternalApi + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Select.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Select.java new file mode 100644 index 000000000..1dcf88955 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Select.java @@ -0,0 +1,28 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Expr; +import java.util.Map; + +@InternalApi +public final class Select implements Stage { + + private static final String name = "select"; + private final Map projections; + + @InternalApi + public Select(Map projections) { + this.projections = projections; + } + + @InternalApi + public Map getProjections() { + return projections; + } + + @Override + @InternalApi + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Sort.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Sort.java new file mode 100644 index 000000000..d746e5972 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Sort.java @@ -0,0 +1,67 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Ordering; +import java.util.List; +import java.util.Locale; + +public final class Sort implements Stage { + + private static final String name = "sort"; + private final List orders; + private final Sort.Density density; + private final Sort.Truncation truncation; + + @InternalApi + public Sort(List orders, Sort.Density density, Sort.Truncation truncation) { + this.orders = orders; + this.density = density; + this.truncation = truncation; + } + + @InternalApi + public String getName() { + return name; + } + + @InternalApi + public List getOrders() { + return orders; + } + + @InternalApi + public Sort.Density getDensity() { + if (density != null) { + return density; + } + return Density.UNSPECIFIED; + } + + @InternalApi + public Sort.Truncation getTruncation() { + if (truncation != null) { + return truncation; + } + return Truncation.UNSPECIFIED; + } + + public enum Density { + UNSPECIFIED, + REQUIRED; + + @Override + public String toString() { + return name().toLowerCase(Locale.getDefault()); + } + } + + public enum Truncation { + UNSPECIFIED, + DISABLED; + + @Override + public String toString() { + return name().toLowerCase(Locale.getDefault()); + } + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Stage.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Stage.java new file mode 100644 index 000000000..8acf7f182 --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Stage.java @@ -0,0 +1,5 @@ +package com.google.cloud.firestore.pipeline.stages; + +public interface Stage { + String getName(); +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/StageUtils.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/StageUtils.java new file mode 100644 index 000000000..6d4bd3f9b --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/StageUtils.java @@ -0,0 +1,120 @@ +package com.google.cloud.firestore.pipeline.stages; + +import static com.google.cloud.firestore.PipelineUtils.encodeValue; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.PipelineUtils; +import com.google.cloud.firestore.pipeline.expressions.Ordering; +import com.google.firestore.v1.Value; +import java.util.stream.Collectors; + +@InternalApi +public final class StageUtils { + @InternalApi + public static com.google.firestore.v1.Pipeline.Stage toStageProto(Stage stage) { + + if (stage instanceof Collection) { + Collection collectionStage = (Collection) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(collectionStage.getName()) + .addArgs(Value.newBuilder().setReferenceValue(collectionStage.getPath()).build()) + .build(); + } else if (stage instanceof CollectionGroup) { + CollectionGroup collectionGroupStage = (CollectionGroup) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(collectionGroupStage.getName()) + .addArgs(Value.newBuilder().setReferenceValue("").build()) + .addArgs(encodeValue(collectionGroupStage.getCollectionId())) + .build(); + } else if (stage instanceof Database) { + Database databaseStage = (Database) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(databaseStage.getName()) + .build(); + } else if (stage instanceof Documents) { + Documents documentsStage = (Documents) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(documentsStage.getName()) + .addAllArgs( + documentsStage.getDocuments().stream() + .map(doc -> Value.newBuilder().setReferenceValue(doc).build()) + .collect(Collectors.toList())) + .build(); + } else if (stage instanceof Select) { + Select selectStage = (Select) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(selectStage.getName()) + .addArgs(encodeValue(selectStage.getProjections())) + .build(); + } else if (stage instanceof AddFields) { + AddFields addFieldsStage = (AddFields) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(addFieldsStage.getName()) + .addArgs(encodeValue(addFieldsStage.getFields())) + .build(); + } else if (stage instanceof Where) { + Where whereStage = (Where) stage; // Use wildcard for generic type + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(whereStage.getName()) + .addArgs(encodeValue(whereStage.getCondition())) + .build(); + } else if (stage instanceof Sort) { + Sort sortStage = (Sort) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(sortStage.getName()) + .addAllArgs( + sortStage.getOrders().stream().map(Ordering::toProto).collect(Collectors.toList())) + .putOptions("density", encodeValue(sortStage.getDensity().toString())) + .putOptions("truncation", encodeValue(sortStage.getTruncation().toString())) + .build(); + } else if (stage instanceof Offset) { + Offset offsetStage = (Offset) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(offsetStage.getName()) + .addArgs(encodeValue(offsetStage.getOffset())) + .build(); + } else if (stage instanceof Limit) { + Limit limitStage = (Limit) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(limitStage.getName()) + .addArgs(encodeValue(limitStage.getLimit())) + .build(); + } else if (stage instanceof Aggregate) { + Aggregate aggregateStage = (Aggregate) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(aggregateStage.getName()) + .addArgs(encodeValue(aggregateStage.getAccumulators())) + .addArgs(encodeValue(aggregateStage.getGroups())) + .build(); + } else if (stage instanceof Distinct) { + Distinct distinctStage = (Distinct) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(distinctStage.getName()) + .addArgs(encodeValue(distinctStage.getGroups())) + .build(); + } else if (stage instanceof FindNearest) { + FindNearest findNearestStage = (FindNearest) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(findNearestStage.getName()) + .addArgs(encodeValue(findNearestStage.getProperty())) + .addArgs(encodeValue(findNearestStage.getVector())) + .addArgs(encodeValue(findNearestStage.getOptions().getDistanceMeasure().toProtoString())) + .putOptions("limit", encodeValue(findNearestStage.getOptions().getLimit())) + .putOptions( + "distance_field", encodeValue(findNearestStage.getOptions().getDistanceField())) + .build(); + } else if (stage instanceof GenericStage) { + GenericStage genericStage = (GenericStage) stage; + return com.google.firestore.v1.Pipeline.Stage.newBuilder() + .setName(genericStage.getName()) + .addAllArgs( + genericStage.getParams().stream() + .map(PipelineUtils::encodeValue) + .collect(Collectors.toList())) + .build(); + } else { + // Handle the else case appropriately (e.g., throw an exception) + throw new IllegalArgumentException("Unknown stage type: " + stage.getClass()); + } + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/UnnestArray.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/UnnestArray.java new file mode 100644 index 000000000..6d7526adb --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/UnnestArray.java @@ -0,0 +1,25 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.Field; + +@InternalApi +public final class UnnestArray implements Stage { + + private static final String name = "unnest_array"; + private final Field field; + + @InternalApi + public UnnestArray(Field arrayField) { + this.field = arrayField; + } + + public Field getField() { + return field; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Where.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Where.java new file mode 100644 index 000000000..49451bb3e --- /dev/null +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/Where.java @@ -0,0 +1,26 @@ +package com.google.cloud.firestore.pipeline.stages; + +import com.google.api.core.InternalApi; +import com.google.cloud.firestore.pipeline.expressions.FilterCondition; + +@InternalApi +public final class Where implements Stage { + + private static final String name = "where"; + private final FilterCondition condition; + + @InternalApi + public Where(FilterCondition condition) { + this.condition = condition; + } + + @InternalApi + public FilterCondition getCondition() { + return condition; + } + + @Override + public String getName() { + return name; + } +} diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/FirestoreRpc.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/FirestoreRpc.java index c2172fafb..5c8dd4572 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/FirestoreRpc.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/FirestoreRpc.java @@ -31,6 +31,8 @@ import com.google.firestore.v1.BeginTransactionResponse; import com.google.firestore.v1.CommitRequest; import com.google.firestore.v1.CommitResponse; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListDocumentsRequest; import com.google.firestore.v1.ListenRequest; @@ -62,6 +64,10 @@ public interface FirestoreRpc extends AutoCloseable, ServiceRpc { /** Runs a query. */ ServerStreamingCallable runQueryCallable(); + /** Executes a pipeline. */ + ServerStreamingCallable + executePipelineCallable(); + /** Runs an aggregation query. */ ServerStreamingCallable runAggregationQueryCallable(); diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/GrpcFirestoreRpc.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/GrpcFirestoreRpc.java index c391e9b80..3eee842e6 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/GrpcFirestoreRpc.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/spi/v1/GrpcFirestoreRpc.java @@ -49,6 +49,8 @@ import com.google.firestore.v1.CommitRequest; import com.google.firestore.v1.CommitResponse; import com.google.firestore.v1.DatabaseRootName; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListDocumentsRequest; import com.google.firestore.v1.ListenRequest; @@ -230,6 +232,12 @@ public ServerStreamingCallable runQueryCallab return firestoreStub.runQueryCallable(); } + @Override + public ServerStreamingCallable + executePipelineCallable() { + return firestoreStub.executePipelineCallable(); + } + @Override public ServerStreamingCallable runAggregationQueryCallable() { diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreClient.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreClient.java index 95130776c..0aded0b0a 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreClient.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreClient.java @@ -42,6 +42,8 @@ import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; import com.google.firestore.v1.DocumentMask; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -247,6 +249,16 @@ * * * + *

ExecutePipeline + *

Executes a pipeline query. + * + *

Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.

+ *
    + *
  • executePipelineCallable() + *

+ * + * + * *

RunAggregationQuery *

Runs an aggregation query. *

Rather than producing [Document][google.firestore.v1.Document] results like [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery], this API allows running an aggregation to produce a series of [AggregationResult][google.firestore.v1.AggregationResult] server-side. @@ -1123,6 +1135,34 @@ public final ServerStreamingCallable runQuery return stub.runQueryCallable(); } + // AUTO-GENERATED DOCUMENTATION AND METHOD. + /** + * Executes a pipeline query. + * + *

Sample code: + * + *

{@code
+   * // This snippet has been automatically generated and should be regarded as a code template only.
+   * // It will require modifications to work:
+   * // - It may require correct/in-range values for request initialization.
+   * // - It may require specifying regional endpoints when creating the service client as shown in
+   * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+   * try (FirestoreClient firestoreClient = FirestoreClient.create()) {
+   *   ExecutePipelineRequest request =
+   *       ExecutePipelineRequest.newBuilder().setDatabase("database1789464955").build();
+   *   ServerStream stream =
+   *       firestoreClient.executePipelineCallable().call(request);
+   *   for (ExecutePipelineResponse response : stream) {
+   *     // Do something when a response is received.
+   *   }
+   * }
+   * }
+ */ + public final ServerStreamingCallable + executePipelineCallable() { + return stub.executePipelineCallable(); + } + // AUTO-GENERATED DOCUMENTATION AND METHOD. /** * Runs an aggregation query. diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreSettings.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreSettings.java index cd14ac440..687b81a60 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreSettings.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/FirestoreSettings.java @@ -46,6 +46,8 @@ import com.google.firestore.v1.CreateDocumentRequest; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -155,6 +157,12 @@ public ServerStreamingCallSettings runQuerySe return ((FirestoreStubSettings) getStubSettings()).runQuerySettings(); } + /** Returns the object with the settings used for calls to executePipeline. */ + public ServerStreamingCallSettings + executePipelineSettings() { + return ((FirestoreStubSettings) getStubSettings()).executePipelineSettings(); + } + /** Returns the object with the settings used for calls to runAggregationQuery. */ public ServerStreamingCallSettings runAggregationQuerySettings() { @@ -356,6 +364,12 @@ public UnaryCallSettings.Builder rollbackSettings() { return getStubSettingsBuilder().runQuerySettings(); } + /** Returns the builder for the settings used for calls to executePipeline. */ + public ServerStreamingCallSettings.Builder + executePipelineSettings() { + return getStubSettingsBuilder().executePipelineSettings(); + } + /** Returns the builder for the settings used for calls to runAggregationQuery. */ public ServerStreamingCallSettings.Builder< RunAggregationQueryRequest, RunAggregationQueryResponse> diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/gapic_metadata.json b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/gapic_metadata.json index 05f7e5a5f..44b5ecb1d 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/gapic_metadata.json +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/gapic_metadata.json @@ -28,6 +28,9 @@ "DeleteDocument": { "methods": ["deleteDocument", "deleteDocument", "deleteDocumentCallable"] }, + "ExecutePipeline": { + "methods": ["executePipelineCallable"] + }, "GetDocument": { "methods": ["getDocument", "getDocumentCallable"] }, diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStub.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStub.java index cd1576688..f79ecb994 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStub.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStub.java @@ -35,6 +35,8 @@ import com.google.firestore.v1.CreateDocumentRequest; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -107,6 +109,11 @@ public ServerStreamingCallable runQueryCallab throw new UnsupportedOperationException("Not implemented: runQueryCallable()"); } + public ServerStreamingCallable + executePipelineCallable() { + throw new UnsupportedOperationException("Not implemented: executePipelineCallable()"); + } + public ServerStreamingCallable runAggregationQueryCallable() { throw new UnsupportedOperationException("Not implemented: runAggregationQueryCallable()"); diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStubSettings.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStubSettings.java index 76215deaa..f4b0baacc 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStubSettings.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/FirestoreStubSettings.java @@ -63,6 +63,8 @@ import com.google.firestore.v1.Cursor; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -144,6 +146,8 @@ public class FirestoreStubSettings extends StubSettings { private final UnaryCallSettings commitSettings; private final UnaryCallSettings rollbackSettings; private final ServerStreamingCallSettings runQuerySettings; + private final ServerStreamingCallSettings + executePipelineSettings; private final ServerStreamingCallSettings runAggregationQuerySettings; private final PagedCallSettings< @@ -370,6 +374,12 @@ public ServerStreamingCallSettings runQuerySe return runQuerySettings; } + /** Returns the object with the settings used for calls to executePipeline. */ + public ServerStreamingCallSettings + executePipelineSettings() { + return executePipelineSettings; + } + /** Returns the object with the settings used for calls to runAggregationQuery. */ public ServerStreamingCallSettings runAggregationQuerySettings() { @@ -527,6 +537,7 @@ protected FirestoreStubSettings(Builder settingsBuilder) throws IOException { commitSettings = settingsBuilder.commitSettings().build(); rollbackSettings = settingsBuilder.rollbackSettings().build(); runQuerySettings = settingsBuilder.runQuerySettings().build(); + executePipelineSettings = settingsBuilder.executePipelineSettings().build(); runAggregationQuerySettings = settingsBuilder.runAggregationQuerySettings().build(); partitionQuerySettings = settingsBuilder.partitionQuerySettings().build(); writeSettings = settingsBuilder.writeSettings().build(); @@ -554,6 +565,9 @@ public static class Builder extends StubSettings.Builder rollbackSettings; private final ServerStreamingCallSettings.Builder runQuerySettings; + private final ServerStreamingCallSettings.Builder< + ExecutePipelineRequest, ExecutePipelineResponse> + executePipelineSettings; private final ServerStreamingCallSettings.Builder< RunAggregationQueryRequest, RunAggregationQueryResponse> runAggregationQuerySettings; @@ -595,6 +609,7 @@ public static class Builder extends StubSettings.BuildernewArrayList())); definitions.put( "no_retry_3_codes", ImmutableSet.copyOf(Lists.newArrayList())); definitions.put( @@ -653,6 +668,8 @@ public static class Builder extends StubSettings.Builder rollbackSettings() { return runQuerySettings; } + /** Returns the builder for the settings used for calls to executePipeline. */ + public ServerStreamingCallSettings.Builder + executePipelineSettings() { + return executePipelineSettings; + } + /** Returns the builder for the settings used for calls to runAggregationQuery. */ public ServerStreamingCallSettings.Builder< RunAggregationQueryRequest, RunAggregationQueryResponse> diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/GrpcFirestoreStub.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/GrpcFirestoreStub.java index a92d4a5e5..03808fdb0 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/GrpcFirestoreStub.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/GrpcFirestoreStub.java @@ -40,6 +40,8 @@ import com.google.firestore.v1.CreateDocumentRequest; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -159,6 +161,17 @@ public class GrpcFirestoreStub extends FirestoreStub { .setResponseMarshaller(ProtoUtils.marshaller(RunQueryResponse.getDefaultInstance())) .build(); + private static final MethodDescriptor + executePipelineMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName("google.firestore.v1.Firestore/ExecutePipeline") + .setRequestMarshaller( + ProtoUtils.marshaller(ExecutePipelineRequest.getDefaultInstance())) + .setResponseMarshaller( + ProtoUtils.marshaller(ExecutePipelineResponse.getDefaultInstance())) + .build(); + private static final MethodDescriptor runAggregationQueryMethodDescriptor = MethodDescriptor.newBuilder() @@ -240,6 +253,8 @@ public class GrpcFirestoreStub extends FirestoreStub { private final UnaryCallable commitCallable; private final UnaryCallable rollbackCallable; private final ServerStreamingCallable runQueryCallable; + private final ServerStreamingCallable + executePipelineCallable; private final ServerStreamingCallable runAggregationQueryCallable; private final UnaryCallable partitionQueryCallable; @@ -388,6 +403,17 @@ protected GrpcFirestoreStub( return builder.build(); }) .build(); + GrpcCallSettings + executePipelineTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(executePipelineMethodDescriptor) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add("database", String.valueOf(request.getDatabase())); + return builder.build(); + }) + .build(); GrpcCallSettings runAggregationQueryTransportSettings = GrpcCallSettings.newBuilder() @@ -495,6 +521,9 @@ protected GrpcFirestoreStub( this.runQueryCallable = callableFactory.createServerStreamingCallable( runQueryTransportSettings, settings.runQuerySettings(), clientContext); + this.executePipelineCallable = + callableFactory.createServerStreamingCallable( + executePipelineTransportSettings, settings.executePipelineSettings(), clientContext); this.runAggregationQueryCallable = callableFactory.createServerStreamingCallable( runAggregationQueryTransportSettings, @@ -590,6 +619,12 @@ public ServerStreamingCallable runQueryCallab return runQueryCallable; } + @Override + public ServerStreamingCallable + executePipelineCallable() { + return executePipelineCallable; + } + @Override public ServerStreamingCallable runAggregationQueryCallable() { diff --git a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/HttpJsonFirestoreStub.java b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/HttpJsonFirestoreStub.java index badc0f7e8..9b7ebafe8 100644 --- a/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/HttpJsonFirestoreStub.java +++ b/google-cloud-firestore/src/main/java/com/google/cloud/firestore/v1/stub/HttpJsonFirestoreStub.java @@ -45,6 +45,8 @@ import com.google.firestore.v1.CreateDocumentRequest; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -430,6 +432,43 @@ public class HttpJsonFirestoreStub extends FirestoreStub { .build()) .build(); + private static final ApiMethodDescriptor + executePipelineMethodDescriptor = + ApiMethodDescriptor.newBuilder() + .setFullMethodName("google.firestore.v1.Firestore/ExecutePipeline") + .setHttpMethod("POST") + .setType(ApiMethodDescriptor.MethodType.SERVER_STREAMING) + .setRequestFormatter( + ProtoMessageRequestFormatter.newBuilder() + .setPath( + "/v1beta1/{database=projects/*/databases/*}:executePipeline", + request -> { + Map fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putPathParam(fields, "database", request.getDatabase()); + return fields; + }) + .setQueryParamsExtractor( + request -> { + Map> fields = new HashMap<>(); + ProtoRestSerializer serializer = + ProtoRestSerializer.create(); + serializer.putQueryParam(fields, "$alt", "json;enum-encoding=int"); + return fields; + }) + .setRequestBodyExtractor( + request -> + ProtoRestSerializer.create() + .toBody("*", request.toBuilder().clearDatabase().build(), true)) + .build()) + .setResponseParser( + ProtoMessageResponseParser.newBuilder() + .setDefaultInstance(ExecutePipelineResponse.getDefaultInstance()) + .setDefaultTypeRegistry(typeRegistry) + .build()) + .build(); + private static final ApiMethodDescriptor runAggregationQueryMethodDescriptor = ApiMethodDescriptor.newBuilder() @@ -638,6 +677,8 @@ public class HttpJsonFirestoreStub extends FirestoreStub { private final UnaryCallable commitCallable; private final UnaryCallable rollbackCallable; private final ServerStreamingCallable runQueryCallable; + private final ServerStreamingCallable + executePipelineCallable; private final ServerStreamingCallable runAggregationQueryCallable; private final UnaryCallable partitionQueryCallable; @@ -794,6 +835,18 @@ protected HttpJsonFirestoreStub( return builder.build(); }) .build(); + HttpJsonCallSettings + executePipelineTransportSettings = + HttpJsonCallSettings.newBuilder() + .setMethodDescriptor(executePipelineMethodDescriptor) + .setTypeRegistry(typeRegistry) + .setParamsExtractor( + request -> { + RequestParamsBuilder builder = RequestParamsBuilder.create(); + builder.add("database", String.valueOf(request.getDatabase())); + return builder.build(); + }) + .build(); HttpJsonCallSettings runAggregationQueryTransportSettings = HttpJsonCallSettings @@ -887,6 +940,9 @@ protected HttpJsonFirestoreStub( this.runQueryCallable = callableFactory.createServerStreamingCallable( runQueryTransportSettings, settings.runQuerySettings(), clientContext); + this.executePipelineCallable = + callableFactory.createServerStreamingCallable( + executePipelineTransportSettings, settings.executePipelineSettings(), clientContext); this.runAggregationQueryCallable = callableFactory.createServerStreamingCallable( runAggregationQueryTransportSettings, @@ -931,6 +987,7 @@ public static List getMethodDescriptors() { methodDescriptors.add(commitMethodDescriptor); methodDescriptors.add(rollbackMethodDescriptor); methodDescriptors.add(runQueryMethodDescriptor); + methodDescriptors.add(executePipelineMethodDescriptor); methodDescriptors.add(runAggregationQueryMethodDescriptor); methodDescriptors.add(partitionQueryMethodDescriptor); methodDescriptors.add(listCollectionIdsMethodDescriptor); @@ -992,6 +1049,12 @@ public ServerStreamingCallable runQueryCallab return runQueryCallable; } + @Override + public ServerStreamingCallable + executePipelineCallable() { + return executePipelineCallable; + } + @Override public ServerStreamingCallable runAggregationQueryCallable() { diff --git a/google-cloud-firestore/src/main/resources/META-INF/native-image/com.google.cloud.firestore.v1/reflect-config.json b/google-cloud-firestore/src/main/resources/META-INF/native-image/com.google.cloud.firestore.v1/reflect-config.json index 6d979acf6..d7f0fd007 100644 --- a/google-cloud-firestore/src/main/resources/META-INF/native-image/com.google.cloud.firestore.v1/reflect-config.json +++ b/google-cloud-firestore/src/main/resources/META-INF/native-image/com.google.cloud.firestore.v1/reflect-config.json @@ -854,6 +854,42 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.firestore.v1.ExecutePipelineRequest", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.ExecutePipelineRequest$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.ExecutePipelineResponse", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.ExecutePipelineResponse$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.firestore.v1.ExecutionStats", "queryAllDeclaredConstructors": true, @@ -926,6 +962,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.firestore.v1.Function", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.Function$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.firestore.v1.GetDocumentRequest", "queryAllDeclaredConstructors": true, @@ -1106,6 +1160,42 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.firestore.v1.Pipeline", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.Pipeline$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.Pipeline$Stage", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.Pipeline$Stage$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.firestore.v1.PlanSummary", "queryAllDeclaredConstructors": true, @@ -1322,6 +1412,24 @@ "allDeclaredClasses": true, "allPublicClasses": true }, + { + "name": "com.google.firestore.v1.StructuredPipeline", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "com.google.firestore.v1.StructuredPipeline$Builder", + "queryAllDeclaredConstructors": true, + "queryAllPublicConstructors": true, + "queryAllDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, { "name": "com.google.firestore.v1.StructuredQuery", "queryAllDeclaredConstructors": true, diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TestUtil.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TestUtil.java new file mode 100644 index 000000000..92a53ce8f --- /dev/null +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/TestUtil.java @@ -0,0 +1,24 @@ +package com.google.cloud.firestore; + +import com.google.firestore.v1.Value; +import java.util.HashMap; +import java.util.Map; + +public final class TestUtil { + public static Map getAggregateSnapshotData(AggregateQuerySnapshot snapshot) { + Map result = new HashMap<>(); + for (Map.Entry entry : snapshot.getData().entrySet()) { + if (entry.getValue().hasIntegerValue()) { + result.put(entry.getKey(), entry.getValue().getIntegerValue()); + } else if (entry.getValue().hasDoubleValue()) { + result.put(entry.getKey(), entry.getValue().getDoubleValue()); + } else if (entry.getValue().hasNullValue()) { + result.put(entry.getKey(), null); + } else { + throw new IllegalArgumentException("AggregateSnapshot has unrecognized value type"); + } + } + + return result; + } +} diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITPipelineTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITPipelineTest.java new file mode 100644 index 000000000..4e6dfa2b8 --- /dev/null +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITPipelineTest.java @@ -0,0 +1,865 @@ +/* + * Copyright 2024 Google LLC + * + * 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.cloud.firestore.it; + +import static com.google.cloud.firestore.it.ITQueryTest.map; +import static com.google.cloud.firestore.pipeline.expressions.Function.add; +import static com.google.cloud.firestore.pipeline.expressions.Function.and; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayContains; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayContainsAll; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayContainsAny; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayElement; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayFilter; +import static com.google.cloud.firestore.pipeline.expressions.Function.arrayTransform; +import static com.google.cloud.firestore.pipeline.expressions.Function.avg; +import static com.google.cloud.firestore.pipeline.expressions.Function.collectionId; +import static com.google.cloud.firestore.pipeline.expressions.Function.cosineDistance; +import static com.google.cloud.firestore.pipeline.expressions.Function.countAll; +import static com.google.cloud.firestore.pipeline.expressions.Function.dotProductDistance; +import static com.google.cloud.firestore.pipeline.expressions.Function.endsWith; +import static com.google.cloud.firestore.pipeline.expressions.Function.eq; +import static com.google.cloud.firestore.pipeline.expressions.Function.euclideanDistance; +import static com.google.cloud.firestore.pipeline.expressions.Function.gt; +import static com.google.cloud.firestore.pipeline.expressions.Function.isNull; +import static com.google.cloud.firestore.pipeline.expressions.Function.lt; +import static com.google.cloud.firestore.pipeline.expressions.Function.neq; +import static com.google.cloud.firestore.pipeline.expressions.Function.not; +import static com.google.cloud.firestore.pipeline.expressions.Function.or; +import static com.google.cloud.firestore.pipeline.expressions.Function.parent; +import static com.google.cloud.firestore.pipeline.expressions.Function.startsWith; +import static com.google.cloud.firestore.pipeline.expressions.Function.strConcat; +import static com.google.cloud.firestore.pipeline.expressions.Function.subtract; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.cloud.firestore.CollectionReference; +import com.google.cloud.firestore.LocalFirestoreHelper; +import com.google.cloud.firestore.PipelineResult; +import com.google.cloud.firestore.pipeline.expressions.Constant; +import com.google.cloud.firestore.pipeline.expressions.Field; +import com.google.cloud.firestore.pipeline.expressions.Function; +import com.google.cloud.firestore.pipeline.stages.Aggregate; +import com.google.common.collect.Lists; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ITPipelineTest extends ITBaseTest { + private CollectionReference collection; + + public CollectionReference testCollectionWithDocs(Map> docs) + throws ExecutionException, InterruptedException, TimeoutException { + CollectionReference collection = firestore.collection(LocalFirestoreHelper.autoId()); + for (Map.Entry> doc : docs.entrySet()) { + collection.document(doc.getKey()).set(doc.getValue()).get(5, TimeUnit.SECONDS); + } + return collection; + } + + List> data(List results) { + return results.stream().map(PipelineResult::getData).collect(Collectors.toList()); + } + + @Before + public void setup() throws Exception { + if (collection != null) { + return; + } + + Map> bookDocs = + map( + "book1", + map( + "title", + "The Hitchhiker's Guide to the Galaxy", + "author", + "Douglas Adams", + "genre", + "Science Fiction", + "published", + 1979, + "rating", + 4.2, + "tags", + Lists.newArrayList("comedy", "space", "adventure"), + "awards", + map("hugo", true, "nebula", false)), + "book2", + map( + "title", + "Pride and Prejudice", + "author", + "Jane Austen", + "genre", + "Romance", + "published", + 1813, + "rating", + 4.5, + "tags", + Lists.newArrayList("classic", "social commentary", "love"), + "awards", + map("none", true)), + "book3", + map( + "title", + "One Hundred Years of Solitude", + "author", + "Gabriel García Márquez", + "genre", + "Magical Realism", + "published", + 1967, + "rating", + 4.3, + "tags", + Lists.newArrayList("family", "history", "fantasy"), + "awards", + map("nobel", true, "nebula", false)), + "book4", + map( + "title", + "The Lord of the Rings", + "author", + "J.R.R. Tolkien", + "genre", + "Fantasy", + "published", + 1954, + "rating", + 4.7, + "tags", + Lists.newArrayList("adventure", "magic", "epic"), + "awards", + map("hugo", false, "nebula", false)), + "book5", + map( + "title", + "The Handmaid's Tale", + "author", + "Margaret Atwood", + "genre", + "Dystopian", + "published", + 1985, + "rating", + 4.1, + "tags", + Lists.newArrayList("feminism", "totalitarianism", "resistance"), + "awards", + map("arthur c. clarke", true, "booker prize", false)), + "book6", + map( + "title", + "Crime and Punishment", + "author", + "Fyodor Dostoevsky", + "genre", + "Psychological Thriller", + "published", + 1866, + "rating", + 4.3, + "tags", + Lists.newArrayList("philosophy", "crime", "redemption"), + "awards", + map("none", true)), + "book7", + map( + "title", + "To Kill a Mockingbird", + "author", + "Harper Lee", + "genre", + "Southern Gothic", + "published", + 1960, + "rating", + 4.2, + "tags", + Lists.newArrayList("racism", "injustice", "coming-of-age"), + "awards", + map("pulitzer", true)), + "book8", + map( + "title", + "1984", + "author", + "George Orwell", + "genre", + "Dystopian", + "published", + 1949, + "rating", + 4.2, + "tags", + Lists.newArrayList("surveillance", "totalitarianism", "propaganda"), + "awards", + map("prometheus", true)), + "book9", + map( + "title", + "The Great Gatsby", + "author", + "F. Scott Fitzgerald", + "genre", + "Modernist", + "published", + 1925, + "rating", + 4.0, + "tags", + Lists.newArrayList("wealth", "american dream", "love"), + "awards", + map("none", true)), + "book10", + map( + "title", + "Dune", + "author", + "Frank Herbert", + "genre", + "Science Fiction", + "published", + 1965, + "rating", + 4.6, + "tags", + Lists.newArrayList("politics", "desert", "ecology"), + "awards", + map("hugo", true, "nebula", true))); + collection = testCollectionWithDocs(bookDocs); + } + + @Test + public void testAggregates() throws Exception { + List results = + firestore + .pipeline() + .collection(collection.getPath()) + .aggregate(countAll().as("count")) + .execute() + .get(); + assertThat(data(results)).isEqualTo(Lists.newArrayList(map("count", 10L))); + + results = + collection + .pipeline() + .where(eq("genre", "Science Fiction")) + .aggregate( + countAll().as("count"), + avg("rating").as("avg_rating"), + Field.of("rating").max().as("max_rating")) + .execute() + .get(); + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("count", 2L, "avg_rating", 4.4, "max_rating", 4.6))); + } + + @Test + public void testGroupBysWithoutAccumulators() throws Exception { + assertThrows( + IllegalArgumentException.class, + () -> { + collection + .pipeline() + .where(lt("published", 1900)) + .aggregate(Aggregate.withAccumulators().withGroups("genre")); + }); + } + + @Test + public void testDistinct() throws Exception { + List results = + collection + .pipeline() + .where(lt("published", 1900)) + .distinct(Field.of("genre").toLowercase().as("lower_genre")) + .execute() + .get(); + assertThat(data(results)) + .containsExactly( + map("lower_genre", "romance"), map("lower_genre", "psychological thriller")); + } + + @Test + public void testGroupBysAndAggregate() throws Exception { + List results = + collection + .pipeline() + .where(lt("published", 1984)) + .aggregate( + Aggregate.withAccumulators(avg("rating").as("avg_rating")).withGroups("genre")) + .where(gt("avg_rating", 4.3)) + .execute() + .get(); + assertThat(data(results)) + .containsExactly( + map("avg_rating", 4.7, "genre", "Fantasy"), + map("avg_rating", 4.5, "genre", "Romance"), + map("avg_rating", 4.4, "genre", "Science Fiction")); + } + + @Test + public void testMinMax() throws Exception { + List results = + collection + .pipeline() + .aggregate( + countAll().as("count"), + Field.of("rating").max().as("max_rating"), + Field.of("published").min().as("min_published")) + .execute() + .get(); + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "count", 10L, + "max_rating", 4.7, + "min_published", 1813L))); + } + + @Test + public void selectSpecificFields() throws Exception { + List results = + collection + .pipeline() + .select("title", "author") + .sort(Field.of("author").ascending()) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "The Hitchhiker's Guide to the Galaxy", "author", "Douglas Adams"), + map("title", "The Great Gatsby", "author", "F. Scott Fitzgerald"), + map("title", "Dune", "author", "Frank Herbert"), + map("title", "Crime and Punishment", "author", "Fyodor Dostoevsky"), + map("title", "One Hundred Years of Solitude", "author", "Gabriel García Márquez"), + map("title", "1984", "author", "George Orwell"), + map("title", "To Kill a Mockingbird", "author", "Harper Lee"), + map("title", "The Lord of the Rings", "author", "J.R.R. Tolkien"), + map("title", "Pride and Prejudice", "author", "Jane Austen"), + map("title", "The Handmaid's Tale", "author", "Margaret Atwood"))); + } + + @Test + public void whereByMultipleConditions() throws Exception { + List results = + collection + .pipeline() + .where(and(gt("rating", 4.5), eq("genre", "Science Fiction"))) + .execute() + .get(); + + // It's Dune + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(collection.document("book10").get().get().getData())); + assertThat(results.get(0).getReference()).isEqualTo(collection.document("book10")); + } + + @Test + public void whereByOrCondition() throws Exception { + List results = + collection + .pipeline() + .where(or(eq("genre", "Romance"), eq("genre", "Dystopian"))) + .select("title") + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "Pride and Prejudice"), + map("title", "The Handmaid's Tale"), + map("title", "1984"))); + } + + @Test + public void testPipelineWithOffsetAndLimit() throws Exception { + List results = + collection + .pipeline() + .sort(Field.of("author").ascending()) + .offset(5) + .limit(3) + .select("title", "author") + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "1984", "author", "George Orwell"), + map("title", "To Kill a Mockingbird", "author", "Harper Lee"), + map("title", "The Lord of the Rings", "author", "J.R.R. Tolkien"))); + } + + @Test + public void testArrayContains() throws Exception { + List results = + collection.pipeline().where(arrayContains("tags", "comedy")).execute().get(); + assertThat(data(results)) + // The Hitchhiker's Guide to the Galaxy + .isEqualTo(Lists.newArrayList(collection.document("book1").get().get().getData())); + } + + @Test + public void testArrayContainsAny() throws Exception { + List results = + collection + .pipeline() + .where(arrayContainsAny("tags", "comedy", "classic")) + .select("title") + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "The Hitchhiker's Guide to the Galaxy"), + map("title", "Pride and Prejudice"))); + } + + @Test + public void testArrayContainsAll() throws Exception { + List results = + collection + .pipeline() + .where(arrayContainsAll("tags", "adventure", "magic")) + .select("title") + .execute() + .get(); + + assertThat(data(results)).isEqualTo(Lists.newArrayList(map("title", "The Lord of the Rings"))); + } + + @Test + public void testArrayLength() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("tags").arrayLength().as("tagsCount")) + .where(eq("tagsCount", 3)) + .execute() + .get(); + + // All documents have 3 tags in the test dataset + assertThat(data(results)).hasSize(10); + } + + @Test + public void testArrayConcat() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("tags").arrayConcat("newTag1", "newTag2").as("modifiedTags")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "modifiedTags", + Lists.newArrayList("comedy", "space", "adventure", "newTag1", "newTag2")))); + } + + @Test + public void testArrayFilter() throws Exception { + List results = + collection + .pipeline() + .select( + arrayFilter(Field.of("tags"), Function.eq(arrayElement(), "comedy")) + .as("filteredTags")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("filteredTags", Lists.newArrayList("comedy")))); + } + + @Test + public void testArrayTransform() throws Exception { + List results = + collection + .pipeline() + .select( + arrayTransform(Field.of("tags"), strConcat(arrayElement(), "transformed")) + .as("transformedTags")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "transformedTags", + Lists.newArrayList( + "comedytransformed", "spacetransformed", "adventuretransformed")))); + } + + @Test + public void testStrConcat() throws Exception { + List results = + collection + .pipeline() + .select(strConcat(Field.of("author"), " - ", Field.of("title")).as("bookInfo")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("bookInfo", "Douglas Adams - The Hitchhiker's Guide to the Galaxy"))); + } + + @Test + public void testStartsWith() throws Exception { + List results = + collection + .pipeline() + .where(startsWith("title", "The")) + .select("title") + .sort(Field.of("title").ascending()) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "The Great Gatsby"), + map("title", "The Handmaid's Tale"), + map("title", "The Hitchhiker's Guide to the Galaxy"), + map("title", "The Lord of the Rings"))); + } + + @Test + public void testEndsWith() throws Exception { + List results = + collection + .pipeline() + .where(endsWith(Field.of("title"), Constant.of("y"))) + .select("title") + .sort(Field.of("title").descending()) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "The Hitchhiker's Guide to the Galaxy"), + map("title", "The Great Gatsby"))); + } + + @Test + public void testLength() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("title").length().as("titleLength"), Field.of("title")) + .where(gt("titleLength", 20)) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("titleLength", 32L), map("titleLength", 27L))); + } + + @Test + public void testToLowercase() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("title").toLowercase().as("lowercaseTitle")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList(map("lowercaseTitle", "the hitchhiker's guide to the galaxy"))); + } + + @Test + public void testToUppercase() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("author").toUppercase().as("uppercaseAuthor")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("uppercaseAuthor", "DOUGLAS ADAMS"))); + } + + @Test + public void testTrim() throws Exception { + List results = + collection + .pipeline() + .addFields( + strConcat(Constant.of(" "), Field.of("title"), Constant.of(" ")).as("spacedTitle")) + .select(Field.of("spacedTitle").trim().as("trimmedTitle"), Field.of("spacedTitle")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "spacedTitle", " The Hitchhiker's Guide to the Galaxy ", + "trimmedTitle", "The Hitchhiker's Guide to the Galaxy"))); + } + + @Test + public void testLike() throws Exception { + List results = + collection + .pipeline() + .where(Field.of("title").like("%Guide%")) + .select("title") + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("title", "The Hitchhiker's Guide to the Galaxy"))); + } + + @Test + public void testRegexContains() throws Exception { + // Find titles that contain either "the" or "of" (case-insensitive) + List results = + collection + .pipeline() + .where(Field.of("title").regexContains("(?i)(the|of)")) + .execute() + .get(); + + assertThat(data(results)).hasSize(5); + } + + @Test + public void testRegexMatches() throws Exception { + // Find titles that contain either "the" or "of" (case-insensitive) + List results = + collection + .pipeline() + .where(Function.regexMatch("title", ".*(?i)(the|of).*")) + .execute() + .get(); + + assertThat(data(results)).hasSize(5); + } + + @Test + public void testArithmeticOperations() throws Exception { + List results = + collection + .pipeline() + .select( + add(Field.of("rating"), 1).as("ratingPlusOne"), + subtract(Field.of("published"), 1900).as("yearsSince1900"), + Field.of("rating").multiply(10).as("ratingTimesTen"), + Field.of("rating").divide(2).as("ratingDividedByTwo")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "ratingPlusOne", + 5.2, + "yearsSince1900", + 79L, + "ratingTimesTen", + 42.0, + "ratingDividedByTwo", + 2.1))); + } + + @Test + public void testComparisonOperators() throws Exception { + List results = + collection + .pipeline() + .where( + and( + gt("rating", 4.2), + Field.of("rating").lte(4.5), + neq("genre", "Science Fiction"))) + .select("rating", "title") + .sort(Field.of("title").ascending()) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("rating", 4.3, "title", "Crime and Punishment"), + map("rating", 4.3, "title", "One Hundred Years of Solitude"), + map("rating", 4.5, "title", "Pride and Prejudice"))); + } + + @Test + public void testLogicalOperators() throws Exception { + List results = + collection + .pipeline() + .where( + or(and(gt("rating", 4.5), eq("genre", "Science Fiction")), lt("published", 1900))) + .select("title") + .sort(Field.of("title").ascending()) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "Crime and Punishment"), + map("title", "Dune"), + map("title", "Pride and Prejudice"))); + } + + @Test + public void testChecks() throws Exception { + List results = + collection + .pipeline() + .where(not(Field.of("rating").isNaN())) // Filter out any documents with NaN rating + .select( + isNull("rating").as("ratingIsNull"), + not(Field.of("rating").isNaN()).as("ratingIsNotNaN")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo(Lists.newArrayList(map("ratingIsNull", false, "ratingIsNotNaN", true))); + } + + @Test + public void testMapGet() throws Exception { + List results = + collection + .pipeline() + .select(Field.of("awards").mapGet("hugo").as("hugoAward"), Field.of("title")) + .where(eq("hugoAward", true)) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("hugoAward", true, "title", "The Hitchhiker's Guide to the Galaxy"), + map("hugoAward", true, "title", "Dune"))); + } + + @Test + public void testParent() throws Exception { + List results = + collection + .pipeline() + .select( + parent(collection.document("chile").collection("subCollection").getPath()) + .as("parent")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList(map("parent", "projects/projectId/databases/(default)/documents"))); + } + + @Test + public void testCollectionId() throws Exception { + List results = + collection + .pipeline() + .select(collectionId(collection.document("chile")).as("collectionId")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)).isEqualTo(Lists.newArrayList(map("collectionId", "books"))); + } + + @Test + public void testDistanceFunctions() throws Exception { + double[] sourceVector = {0.1, 0.1}; + double[] targetVector = {0.5, 0.8}; + List results = + collection + .pipeline() + .select( + cosineDistance(Constant.ofVector(sourceVector), targetVector).as("cosineDistance"), + dotProductDistance(Constant.ofVector(sourceVector), targetVector) + .as("dotProductDistance"), + euclideanDistance(Constant.ofVector(sourceVector), targetVector) + .as("euclideanDistance")) + .limit(1) + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map( + "cosineDistance", 0.02560880430538015, + "dotProductDistance", 0.13, + "euclideanDistance", 0.806225774829855))); + } + + @Test + public void testNestedFields() throws Exception { + List results = + collection + .pipeline() + .where(eq("awards.hugo", true)) + .select("title", "awards.hugo") + .execute() + .get(); + + assertThat(data(results)) + .isEqualTo( + Lists.newArrayList( + map("title", "The Hitchhiker's Guide to the Galaxy", "awards.hugo", true), + map("title", "Dune", "awards.hugo", true))); + } +} diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryAggregationsTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryAggregationsTest.java index 7659d4656..259ba585f 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryAggregationsTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryAggregationsTest.java @@ -30,6 +30,7 @@ import com.google.api.core.ApiFuture; import com.google.cloud.firestore.*; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import org.junit.Ignore; @@ -56,6 +57,18 @@ private CollectionReference testCollectionWithDocs(Map pipelineResults = query.pipeline().execute().get(); + assertThat(pipelineResults).hasSize(1); + assertThat(pipelineResults.get(0).getData()) + .isEqualTo(TestUtil.getAggregateSnapshotData(snapshot)); + + return snapshot; + } + public static void writeAllDocs( CollectionReference collection, Map> docs) throws InterruptedException { @@ -74,7 +87,8 @@ public static void writeAllDocs( @Test public void canRunCountUsingAggregationMethod() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); - AggregateQuerySnapshot snapshot = collection.aggregate(AggregateField.count()).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(AggregateField.count())); assertThat(snapshot.getCount()).isEqualTo(2); } @@ -92,10 +106,10 @@ public void allowsAliasesForLongestFieldNames() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection.aggregate(AggregateField.sum(longestField)).get().get(); + verifyPipelineReturnsSameResult(collection.aggregate(AggregateField.sum(longestField))); assertThat(snapshot.get(AggregateField.sum(longestField))).isEqualTo(6); AggregateQuerySnapshot snapshot2 = - collection.aggregate(AggregateField.average(longestField)).get().get(); + verifyPipelineReturnsSameResult(collection.aggregate(AggregateField.average(longestField))); assertThat(snapshot2.get(AggregateField.average(longestField))).isEqualTo(3.0); } @@ -134,14 +148,16 @@ public void aggregateErrorMessageIfIndexIsMissing() throws Exception { @Test public void canRunSumQuery() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("pages")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("pages"))); assertThat(snapshot.get(sum("pages"))).isEqualTo(150); } @Test public void canRunAverageQuery() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); - AggregateQuerySnapshot snapshot = collection.aggregate(average("pages")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("pages"))); assertThat(snapshot.get(average("pages"))).isEqualTo(75.0); } @@ -149,7 +165,8 @@ public void canRunAverageQuery() throws Exception { public void canGetMultipleAggregationsInTheSameQuery() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); AggregateQuerySnapshot snapshot = - collection.aggregate(sum("pages"), average("pages"), AggregateField.count()).get().get(); + verifyPipelineReturnsSameResult( + collection.aggregate(sum("pages"), average("pages"), AggregateField.count())); assertThat(snapshot.get(sum("pages"))).isEqualTo(150); assertThat(snapshot.get(average("pages"))).isEqualTo(75.0); assertThat(snapshot.get(AggregateField.count())).isEqualTo(2); @@ -159,7 +176,8 @@ public void canGetMultipleAggregationsInTheSameQuery() throws Exception { public void getCorrectTypeForSumLong() throws Exception { Map> testDocs = map("a", map("foo", 100), "b", map("foo", 100)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("foo")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("foo"))); Object sum = snapshot.get(sum("foo")); assertThat(sum instanceof Long).isTrue(); } @@ -168,7 +186,8 @@ public void getCorrectTypeForSumLong() throws Exception { public void getCorrectTypeForSumDouble() throws Exception { Map> testDocs = map("a", map("foo", 100.5), "b", map("foo", 100)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("foo")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("foo"))); Object sum = snapshot.get(sum("foo")); assertThat(sum instanceof Double).isTrue(); } @@ -178,7 +197,8 @@ public void getCorrectTypeForSumNaN() throws Exception { Map> testDocs = map("a", map("foo", 100.5), "b", map("foo", Double.NaN)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("foo")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("foo"))); Object sum = snapshot.get(sum("foo")); assertThat(sum instanceof Double).isTrue(); assertThat(sum.equals(Double.NaN)); @@ -187,7 +207,8 @@ public void getCorrectTypeForSumNaN() throws Exception { @Test public void getCorrectTypeForAverageDouble() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); - AggregateQuerySnapshot snapshot = collection.aggregate(average("pages")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("pages"))); Object average = snapshot.get((AggregateField) average("pages")); assertThat(average instanceof Double).isTrue(); } @@ -197,7 +218,8 @@ public void getCorrectTypeForAverageNaN() throws Exception { Map> testDocs = map("a", map("foo", 100.5), "b", map("foo", Double.NaN)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("foo")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("foo"))); Object sum = snapshot.get(average("foo")); assertThat(sum instanceof Double).isTrue(); assertThat(sum.equals(Double.NaN)); @@ -206,7 +228,8 @@ public void getCorrectTypeForAverageNaN() throws Exception { @Test public void getCorrectTypeForAverageNull() throws Exception { CollectionReference collection = testCollection(); - AggregateQuerySnapshot snapshot = collection.aggregate(average("bar")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("bar"))); Object sum = snapshot.get(average("bar")); assertThat(sum == null).isTrue(); } @@ -222,7 +245,8 @@ public void canPerformMaxAggregations() throws Exception { AggregateField f3 = AggregateField.count(); AggregateField f4 = sum("foo"); AggregateField f5 = sum("bar"); - AggregateQuerySnapshot snapshot = collection.aggregate(f1, f2, f3, f4, f5).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(f1, f2, f3, f4, f5)); assertThat(snapshot.get(f1)).isEqualTo(150); assertThat(snapshot.get(f2)).isEqualTo(75.0); assertThat(snapshot.get(f3)).isEqualTo(2); @@ -289,7 +313,8 @@ public void aggregateQueriesSupportCollectionGroups() throws Exception { .set(data)); CollectionGroup collectionGroup = firestore.collectionGroup(collectionGroupId); AggregateQuerySnapshot snapshot = - collectionGroup.aggregate(AggregateField.count(), sum("x"), average("x")).get().get(); + verifyPipelineReturnsSameResult( + collectionGroup.aggregate(AggregateField.count(), sum("x"), average("x"))); assertThat(snapshot.get(AggregateField.count())).isEqualTo(2); assertThat(snapshot.get(sum("x"))).isEqualTo(4); assertThat(snapshot.get(average("x"))).isEqualTo(2); @@ -312,10 +337,9 @@ public void performsAggregationsOnDocumentsWithAllAggregatedFields() throws Exce map("author", "authorD", "title", "titleD", "pages", 50)); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection - .aggregate(sum("pages"), average("pages"), average("year"), AggregateField.count()) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection.aggregate( + sum("pages"), average("pages"), average("year"), AggregateField.count())); assertThat(snapshot.get(sum("pages"))).isEqualTo(300); assertThat(snapshot.get(average("pages"))).isEqualTo(100); assertThat(snapshot.get(average("year"))).isEqualTo(2007); @@ -353,7 +377,8 @@ public void performsAggregationsWhenNaNExistsForSomeFieldValues() throws Excepti 0)); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection.aggregate(sum("rating"), sum("pages"), average("year")).get().get(); + verifyPipelineReturnsSameResult( + collection.aggregate(sum("rating"), sum("pages"), average("year"))); assertThat(snapshot.get(sum("rating"))).isEqualTo(Double.NaN); assertThat(snapshot.get(sum("pages"))).isEqualTo(300); assertThat(snapshot.get(average("year"))).isEqualTo(2000); @@ -362,7 +387,8 @@ public void performsAggregationsWhenNaNExistsForSomeFieldValues() throws Excepti @Test public void throwsAnErrorWhenGettingTheResultOfAnUnrequestedAggregation() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("pages")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("pages"))); Exception exception = null; try { snapshot.get(average("pages")); @@ -406,16 +432,15 @@ public void performsAggregationWhenUsingInOperator() throws Exception { 0)); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection - .whereIn("rating", asList(5, 3)) - .aggregate( - sum("rating"), - average("rating"), - sum("pages"), - average("pages"), - AggregateField.count()) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .whereIn("rating", asList(5, 3)) + .aggregate( + sum("rating"), + average("rating"), + sum("pages"), + average("pages"), + AggregateField.count())); assertThat(snapshot.get(sum("rating"))).isEqualTo(8); assertThat(snapshot.get(average("rating"))).isEqualTo(4); assertThat(snapshot.get(sum("pages"))).isEqualTo(200); @@ -464,16 +489,15 @@ public void performsAggregationWhenUsingArrayContainsAnyOperator() throws Except asList(0))); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection - .whereArrayContainsAny("rating", asList(5, 3)) - .aggregate( - sum("rating"), - average("rating"), - sum("pages"), - average("pages"), - AggregateField.count()) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .whereArrayContainsAny("rating", asList(5, 3)) + .aggregate( + sum("rating"), + average("rating"), + sum("pages"), + average("pages"), + AggregateField.count())); assertThat(snapshot.get(sum("rating"))).isEqualTo(0); assertThat(snapshot.get(average("rating"))).isEqualTo(null); assertThat(snapshot.get(sum("pages"))).isEqualTo(200); @@ -503,10 +527,9 @@ public void performsAggregationsOnNestedMapValues() throws Exception { map("pages", 50, "rating", map("critic", 4, "user", 4)))); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection - .aggregate(sum("metadata.pages"), average("metadata.pages"), AggregateField.count()) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection.aggregate( + sum("metadata.pages"), average("metadata.pages"), AggregateField.count())); assertThat(snapshot.get(sum("metadata.pages"))).isEqualTo(150); assertThat(snapshot.get(average("metadata.pages"))).isEqualTo(75); assertThat(snapshot.get(AggregateField.count())).isEqualTo(2); @@ -520,7 +543,8 @@ public void performsSumThatResultsInFloat() throws Exception { "b", map("author", "authorB", "title", "titleB", "rating", 4.5), "c", map("author", "authorC", "title", "titleC", "rating", 3)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); Object sum = snapshot.get(sum("rating")); assertThat(sum instanceof Double).isTrue(); assertThat(sum).isEqualTo(12.5); @@ -534,7 +558,8 @@ public void performsSumOfIntsAndFloatsThatResultsInInt() throws Exception { "b", map("author", "authorB", "title", "titleB", "rating", 4.5), "c", map("author", "authorC", "title", "titleC", "rating", 3.5)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); Object sum = snapshot.get(sum("rating")); assertThat(sum instanceof Double).isTrue(); assertThat(sum).isEqualTo(13.0); @@ -576,7 +601,8 @@ public void performsSumThatIsNegative() throws Exception { "c", map("author", "authorC", "title", "titleC", "rating", -101), "d", map("author", "authorD", "title", "titleD", "rating", -10000)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); assertThat(snapshot.get(sum("rating"))).isEqualTo(-10101); } @@ -587,7 +613,8 @@ public void performsSumThatIsPositiveInfinity() throws Exception { "a", map("author", "authorA", "title", "titleA", "rating", Double.MAX_VALUE), "b", map("author", "authorB", "title", "titleB", "rating", Double.MAX_VALUE)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); Object sum = snapshot.get(sum("rating")); assertThat(sum instanceof Double).isTrue(); assertThat(sum).isEqualTo(Double.POSITIVE_INFINITY); @@ -602,7 +629,8 @@ public void performsSumThatIsNegativeInfinity() throws Exception { "a", map("author", "authorA", "title", "titleA", "rating", -Double.MAX_VALUE), "b", map("author", "authorB", "title", "titleB", "rating", -Double.MAX_VALUE)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); Object sum = snapshot.get(sum("rating")); assertThat(sum instanceof Double).isTrue(); assertThat(sum).isEqualTo(Double.NEGATIVE_INFINITY); @@ -638,7 +666,8 @@ public void performsSumThatIncludesNaN() throws Exception { "c", map("author", "authorC", "title", "titleC", "rating", Double.NaN), "d", map("author", "authorD", "title", "titleD", "rating", 0)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); assertThat(snapshot.get(sum("rating"))).isEqualTo(Double.NaN); } @@ -646,7 +675,8 @@ public void performsSumThatIncludesNaN() throws Exception { public void performsSumOverResultSetOfZeroDocuments() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); AggregateQuerySnapshot snapshot = - collection.whereGreaterThan("pages", 200).aggregate(sum("pages")).get().get(); + verifyPipelineReturnsSameResult( + collection.whereGreaterThan("pages", 200).aggregate(sum("pages"))); assertThat(snapshot.get(sum("pages"))).isEqualTo(0); } @@ -660,7 +690,8 @@ public void performsSumOnlyOnNumericFields() throws Exception { "d", map("author", "authorD", "title", "titleD", "rating", 1)); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection.aggregate(sum("rating"), AggregateField.count()).get().get(); + verifyPipelineReturnsSameResult( + collection.aggregate(sum("rating"), AggregateField.count())); assertThat(snapshot.get(sum("rating"))).isEqualTo(10); assertThat(snapshot.get(AggregateField.count())).isEqualTo(4); } @@ -670,7 +701,8 @@ public void performsSumOfMinIEEE754() throws Exception { Map> testDocs = map("a", map("author", "authorA", "title", "titleA", "rating", Double.MIN_VALUE)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(sum("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(sum("rating"))); assertThat(snapshot.get(sum("rating"))).isEqualTo(Double.MIN_VALUE); } @@ -682,7 +714,8 @@ public void performsAverageOfIntsThatResultsInAnInt() throws Exception { "b", map("author", "authorB", "title", "titleB", "rating", 5), "c", map("author", "authorC", "title", "titleC", "rating", 0)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(5); assertThat(snapshot.getLong(average("rating"))).isEqualTo(5L); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(5.0); @@ -695,7 +728,8 @@ public void performsAverageOfFloatsThatResultsInAnInt() throws Exception { "a", map("author", "authorA", "title", "titleA", "rating", 10.5), "b", map("author", "authorB", "title", "titleB", "rating", 9.5)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating")) instanceof Double).isTrue(); assertThat(snapshot.get(average("rating"))).isEqualTo(10); assertThat(snapshot.getLong(average("rating"))).isEqualTo(10L); @@ -710,7 +744,8 @@ public void performsAverageOfFloatsAndIntsThatResultsInAnInt() throws Exception "b", map("author", "authorB", "title", "titleB", "rating", 9.5), "c", map("author", "authorC", "title", "titleC", "rating", 10.5)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(10); assertThat(snapshot.getLong(average("rating"))).isEqualTo(10L); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(10.0); @@ -724,7 +759,8 @@ public void performsAverageOfFloatsThatResultsInAFloat() throws Exception { "b", map("author", "authorB", "title", "titleB", "rating", 4.5), "c", map("author", "authorC", "title", "titleC", "rating", 3.5)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(4.5); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(4.5); assertThat(snapshot.getLong(average("rating"))).isEqualTo(4L); @@ -738,7 +774,8 @@ public void performsAverageOfFloatsAndIntsThatResultsInAFloat() throws Exception "b", map("author", "authorB", "title", "titleB", "rating", 9), "c", map("author", "authorC", "title", "titleC", "rating", 10)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(27.6 / 3); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(27.6 / 3); assertThat(snapshot.getLong(average("rating"))).isEqualTo(9L); @@ -751,7 +788,8 @@ public void performsAverageOfIntsThatResultsInAFloat() throws Exception { "a", map("author", "authorA", "title", "titleA", "rating", 10), "b", map("author", "authorB", "title", "titleB", "rating", 9)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(9.5); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(9.5d); assertThat(snapshot.getLong(average("rating"))).isEqualTo(9L); @@ -764,7 +802,8 @@ public void performsAverageCausingUnderflow() throws Exception { "a", map("author", "authorA", "title", "titleA", "rating", Double.MIN_VALUE), "b", map("author", "authorB", "title", "titleB", "rating", 0)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(0); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(0.0d); assertThat(snapshot.getLong(average("rating"))).isEqualTo(0L); @@ -775,7 +814,8 @@ public void performsAverageOfMinIEEE754() throws Exception { Map> testDocs = map("a", map("author", "authorA", "title", "titleA", "rating", Double.MIN_VALUE)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(Double.MIN_VALUE); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(Double.MIN_VALUE); assertThat(snapshot.getLong(average("rating"))).isEqualTo(0); @@ -790,7 +830,8 @@ public void performsAverageThatCouldOverflowIEEE754DuringAccumulation() throws E "b", map("author", "authorB", "title", "titleB", "rating", Double.MAX_VALUE)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(Double.POSITIVE_INFINITY); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(Double.POSITIVE_INFINITY); assertThat(snapshot.getLong(average("rating"))).isEqualTo(Long.MAX_VALUE); @@ -809,7 +850,8 @@ public void performsAverageThatIncludesNaN() throws Exception { "d", map("author", "authorD", "title", "titleD", "rating", 0)); CollectionReference collection = testCollectionWithDocs(testDocs); - AggregateQuerySnapshot snapshot = collection.aggregate(average("rating")).get().get(); + AggregateQuerySnapshot snapshot = + verifyPipelineReturnsSameResult(collection.aggregate(average("rating"))); assertThat(snapshot.get(average("rating"))).isEqualTo(Double.NaN); assertThat(snapshot.getDouble(average("rating"))).isEqualTo(Double.NaN); assertThat(snapshot.getLong(average("rating"))).isEqualTo(0L); @@ -819,7 +861,8 @@ public void performsAverageThatIncludesNaN() throws Exception { public void performsAverageOverResultSetOfZeroDocuments() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs1); AggregateQuerySnapshot snapshot = - collection.whereGreaterThan("pages", 200).aggregate(average("pages")).get().get(); + verifyPipelineReturnsSameResult( + collection.whereGreaterThan("pages", 200).aggregate(average("pages"))); assertThat(snapshot.get(average("pages"))).isEqualTo(null); assertThat(snapshot.getDouble(average("pages"))).isEqualTo(null); assertThat(snapshot.getLong(average("pages"))).isEqualTo(null); @@ -835,7 +878,8 @@ public void performsAverageOnlyOnNumericFields() throws Exception { "d", map("author", "authorD", "title", "titleD", "rating", 6)); CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection.aggregate(average("rating"), AggregateField.count()).get().get(); + verifyPipelineReturnsSameResult( + collection.aggregate(average("rating"), AggregateField.count())); assertThat(snapshot.get(average("rating"))).isEqualTo(5); assertThat(snapshot.get(AggregateField.count())).isEqualTo(4); } @@ -854,39 +898,35 @@ public void aggregatesWithDocumentReferenceCursors() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs); AggregateQuerySnapshot snapshot = - collection - .orderBy(FieldPath.documentId()) - .startAfter(collection.document("c")) - .aggregate(sum("num")) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .orderBy(FieldPath.documentId()) + .startAfter(collection.document("c")) + .aggregate(sum("num"))); assertThat(snapshot.get(sum("num"))).isEqualTo(9); snapshot = - collection - .orderBy(FieldPath.documentId()) - .startAt(collection.document("c")) - .aggregate(sum("num")) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .orderBy(FieldPath.documentId()) + .startAt(collection.document("c")) + .aggregate(sum("num"))); assertThat(snapshot.get(sum("num"))).isEqualTo(12); snapshot = - collection - .orderBy(FieldPath.documentId()) - .endBefore(collection.document("c")) - .aggregate(sum("num")) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .orderBy(FieldPath.documentId()) + .endBefore(collection.document("c")) + .aggregate(sum("num"))); assertThat(snapshot.get(sum("num"))).isEqualTo(3); snapshot = - collection - .orderBy(FieldPath.documentId()) - .endAt(collection.document("c")) - .aggregate(sum("num")) - .get() - .get(); + verifyPipelineReturnsSameResult( + collection + .orderBy(FieldPath.documentId()) + .endAt(collection.document("c")) + .aggregate(sum("num"))); assertThat(snapshot.get(sum("num"))).isEqualTo(6); } @@ -902,7 +942,7 @@ CollectionReference addTwoDocsForCursorTesting() throws InterruptedException { public void aggregateWithNoFilterNoOrderByNoCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(12); } @@ -910,7 +950,7 @@ public void aggregateWithNoFilterNoOrderByNoCursor() throws Exception { public void aggregateWithEqualityFilterNoOrderByNoCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereEqualTo("num", 5).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(5); } @@ -918,7 +958,7 @@ public void aggregateWithEqualityFilterNoOrderByNoCursor() throws Exception { public void aggregateWithInequalityFilterNoOrderByNoCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereGreaterThan("num", 5).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -926,7 +966,7 @@ public void aggregateWithInequalityFilterNoOrderByNoCursor() throws Exception { public void aggregateWithNoFilterExplicitOrderByNoCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.orderBy("num").aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(12); } @@ -934,7 +974,7 @@ public void aggregateWithNoFilterExplicitOrderByNoCursor() throws Exception { public void aggregateWithEqualityFilterExplicitOrderByNoCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereEqualTo("num", 5).orderBy("num").aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(5); } @@ -943,7 +983,7 @@ public void aggregateWithInequalityFilterExplicitOrderByNoCursor() throws Except CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereGreaterThan("num", 5).orderBy("num").aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -951,7 +991,7 @@ public void aggregateWithInequalityFilterExplicitOrderByNoCursor() throws Except public void aggregateNoFilterExplicitOrderByFieldValueCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.orderBy("num").startAfter(5).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -965,7 +1005,7 @@ public void aggregateNoFilterExplicitOrderByDocumentReferenceCursor() throws Exc .orderBy(FieldPath.documentId()) .startAfter(collection.document("a")) .aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -975,7 +1015,7 @@ public void aggregateNoFilterExplicitOrderByDocumentReferenceCursor() throws Exc public void aggregateNoFilterNoOrderByDocumentReferenceCursor() throws Exception { CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.startAfter(collection.document("a")).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -986,7 +1026,7 @@ public void aggregateNoFilterExplicitOrderByDocumentSnapshotCursor() throws Exce CollectionReference collection = addTwoDocsForCursorTesting(); DocumentSnapshot docSnapshot = collection.document("a").get().get(); AggregateQuery query = collection.orderBy("foo").startAfter(docSnapshot).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -996,7 +1036,7 @@ public void aggregateNoFilterExplicitOrderByDocumentSnapshotCursor2() throws Exc CollectionReference collection = addTwoDocsForCursorTesting(); DocumentSnapshot docSnapshot = collection.document("a").get().get(); AggregateQuery query = collection.orderBy("num").startAfter(docSnapshot).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1005,7 +1045,7 @@ public void aggregateEqualityFilterExplicitOrderByFieldValueCursor() throws Exce CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereEqualTo("num", 5).orderBy("num").startAt(5).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(5); } @@ -1014,7 +1054,7 @@ public void aggregateInequalityFilterExplicitOrderByFieldValueCursor() throws Ex CollectionReference collection = addTwoDocsForCursorTesting(); AggregateQuery query = collection.whereGreaterThan("num", 5).orderBy("num").startAt(6).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1029,7 +1069,7 @@ public void aggregateEqualityFilterExplicitOrderByDocumentReferenceCursor() thro .orderBy(FieldPath.documentId()) .startAfter(collection.document("a")) .aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1044,7 +1084,7 @@ public void aggregateInequalityFilterExplicitOrderByDocumentReferenceCursor() th .orderBy(FieldPath.documentId()) .startAfter(5, collection.document("a")) .aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1056,7 +1096,7 @@ public void aggregateEqualityFilterNoOrderByDocumentSnapshotReference() throws E DocumentSnapshot docSnapshot = collection.document("a").get().get(); AggregateQuery query = collection.whereEqualTo("num", 7).startAfter(docSnapshot).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1067,7 +1107,7 @@ public void aggregateInequalityFilterNoOrderByDocumentSnapshotReference() throws DocumentSnapshot docSnapshot = collection.document("a").get().get(); AggregateQuery query = collection.whereGreaterThan("num", 0).startAfter(docSnapshot).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } @@ -1079,7 +1119,7 @@ public void aggregateInequalityFilterNoOrderByDocumentSnapshotReference2() throw DocumentSnapshot docSnapshot = collection.document("a").get().get(); AggregateQuery query = collection.whereGreaterThan("foo", 0).startAfter(docSnapshot).aggregate(sum("num")); - AggregateQuerySnapshot snapshot = query.get().get(); + AggregateQuerySnapshot snapshot = verifyPipelineReturnsSameResult(query); assertThat(snapshot.get(sum("num"))).isEqualTo(7); } diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryTest.java index 6125d24f4..164b7c8d4 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryTest.java @@ -19,26 +19,21 @@ import static com.google.cloud.firestore.it.TestHelper.isRunningAgainstFirestoreEmulator; import static com.google.common.primitives.Ints.asList; import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; -import com.google.api.core.ApiFuture; -import com.google.api.gax.rpc.ApiStreamObserver; import com.google.cloud.firestore.*; import com.google.cloud.firestore.Query.Direction; -import java.time.Duration; +import com.google.common.collect.Sets; import java.util.Arrays; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; @@ -73,16 +68,50 @@ public CollectionReference testCollectionWithDocs(Map result = + snapshot.getDocuments().stream() + .map(queryDocumentSnapshot -> queryDocumentSnapshot.getReference().getId()) + .collect(Collectors.toList()); + assertThat(result).isEqualTo(Arrays.asList(docs)); + } + + List pipelineResults = query.pipeline().execute().get(); List result = - snapshot.getDocuments().stream() - .map(queryDocumentSnapshot -> queryDocumentSnapshot.getReference().getId()) + pipelineResults.stream() + .map(pipelineResult -> Objects.requireNonNull(pipelineResult.getReference()).getId()) .collect(Collectors.toList()); assertThat(result).isEqualTo(Arrays.asList(docs)); } + public static void checkResultContainsDocuments(Query query, boolean pipelineOnly, String... docs) + throws ExecutionException, InterruptedException { + if (!pipelineOnly) { + QuerySnapshot snapshot = query.get().get(); + Set result = + snapshot.getDocuments().stream() + .map(queryDocumentSnapshot -> queryDocumentSnapshot.getReference().getId()) + .collect(Collectors.toSet()); + assertThat(result).isEqualTo(Sets.newHashSet(docs)); + } + + List pipelineResults = query.pipeline().execute().get(); + Set result = + pipelineResults.stream() + .map(pipelineResult -> Objects.requireNonNull(pipelineResult.getReference()).getId()) + .collect(Collectors.toSet()); + assertThat(result).isEqualTo(Sets.newHashSet(docs)); + } + @Test public void orQueries() throws Exception { Map> testDocs = @@ -96,7 +125,7 @@ public void orQueries() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs); // Two equalities: a==1 || b==1. - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 1), Filter.equalTo("b", 1))), "doc1", "doc2", @@ -104,7 +133,7 @@ public void orQueries() throws Exception { "doc5"); // (a==1 && b==0) || (a==3 && b==2) - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where( Filter.or( Filter.and(Filter.equalTo("a", 1), Filter.equalTo("b", 0)), @@ -113,7 +142,7 @@ public void orQueries() throws Exception { "doc3"); // a==1 && (b==0 || b==3). - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where( Filter.and( Filter.equalTo("a", 1), Filter.or(Filter.equalTo("b", 0), Filter.equalTo("b", 3)))), @@ -121,7 +150,7 @@ public void orQueries() throws Exception { "doc4"); // (a==2 || b==2) && (a==3 || b==3) - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where( Filter.and( Filter.or(Filter.equalTo("a", 2), Filter.equalTo("b", 2)), @@ -129,16 +158,13 @@ public void orQueries() throws Exception { "doc3"); // Test with limits without orderBy (the __name__ ordering is the tiebreaker). - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 2), Filter.equalTo("b", 1))).limit(1), "doc2"); } @Test public void orQueriesWithCompositeIndexes() throws Exception { - assumeTrue( - "Skip this test when running against production because these queries require a composite index.", - isRunningAgainstFirestoreEmulator(firestore)); Map> testDocs = map( "doc1", map("a", 1, "b", 0), @@ -150,50 +176,56 @@ public void orQueriesWithCompositeIndexes() throws Exception { CollectionReference collection = testCollectionWithDocs(testDocs); // with one inequality: a>2 || b==1. - checkQuerySnapshotContainsDocuments( + checkResultContainsDocuments( collection.where(Filter.or(Filter.greaterThan("a", 2), Filter.equalTo("b", 1))), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc5", "doc2", "doc3"); // Test with limits (implicit order by ASC): (a==1) || (b > 0) LIMIT 2 - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 1), Filter.greaterThan("b", 0))).limit(2), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc1", "doc2"); // Test with limits (explicit order by): (a==1) || (b > 0) LIMIT_TO_LAST 2 // Note: The public query API does not allow implicit ordering when limitToLast is used. - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection .where(Filter.or(Filter.equalTo("a", 1), Filter.greaterThan("b", 0))) .limitToLast(2) .orderBy("b"), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc3", "doc4"); // Test with limits (explicit order by ASC): (a==2) || (b == 1) ORDER BY a LIMIT 1 - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection .where(Filter.or(Filter.equalTo("a", 2), Filter.equalTo("b", 1))) .limit(1) .orderBy("a"), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc5"); // Test with limits (explicit order by DESC): (a==2) || (b == 1) ORDER BY a LIMIT_TO_LAST 1 - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection .where(Filter.or(Filter.equalTo("a", 2), Filter.equalTo("b", 1))) .limitToLast(1) .orderBy("a"), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc2"); // Test with limits (explicit order by DESC): (a==2) || (b == 1) ORDER BY a DESC LIMIT 1 - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection .where(Filter.or(Filter.equalTo("a", 2), Filter.equalTo("b", 1))) .limit(1) .orderBy("a", Direction.DESCENDING), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc2"); } @@ -214,14 +246,11 @@ public void orQueryDoesNotIncludeDocumentsWithMissingFields() throws Exception { // There's no explicit nor implicit orderBy. Documents with missing 'a' or missing 'b' should be // allowed if the document matches at least one disjunction term. Query query = collection.where(Filter.or(Filter.equalTo("a", 1), Filter.equalTo("b", 1))); - checkQuerySnapshotContainsDocuments(query, "doc1", "doc2", "doc4", "doc5"); + checkResultContainsDocumentsInOrder(query, "doc1", "doc2", "doc4", "doc5"); } @Test public void orQueryDoesNotIncludeDocumentsWithMissingFields2() throws Exception { - assumeTrue( - "Skip this test when running against production because these queries require a composite index.", - isRunningAgainstFirestoreEmulator(firestore)); Map> testDocs = map( "doc1", map("a", 1, "b", 0), @@ -237,19 +266,30 @@ public void orQueryDoesNotIncludeDocumentsWithMissingFields2() throws Exception // doc2 should not be included because it's missing the field 'a', and we have "orderBy a". Query query1 = collection.where(Filter.or(Filter.equalTo("a", 1), Filter.equalTo("b", 1))).orderBy("a"); - checkQuerySnapshotContainsDocuments(query1, "doc1", "doc4", "doc5"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc4", + "doc5"); // Query: a==1 || b==1 order by b. // doc5 should not be included because it's missing the field 'b', and we have "orderBy b". Query query2 = collection.where(Filter.or(Filter.equalTo("a", 1), Filter.equalTo("b", 1))).orderBy("b"); - checkQuerySnapshotContainsDocuments(query2, "doc1", "doc2", "doc4"); + checkResultContainsDocumentsInOrder( + query2, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc2", + "doc4"); // Query: a>2 || b==1. // This query has an implicit 'order by a'. // doc2 should not be included because it's missing the field 'a'. Query query3 = collection.where(Filter.or(Filter.greaterThan("a", 2), Filter.equalTo("b", 1))); - checkQuerySnapshotContainsDocuments(query3, "doc3"); + checkResultContainsDocumentsInOrder( + query3, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc3"); // Query: a>1 || b==1 order by a order by b. // doc6 should not be included because it's missing the field 'b'. @@ -259,7 +299,8 @@ public void orQueryDoesNotIncludeDocumentsWithMissingFields2() throws Exception .where(Filter.or(Filter.greaterThan("a", 1), Filter.equalTo("b", 1))) .orderBy("a") .orderBy("b"); - checkQuerySnapshotContainsDocuments(query4, "doc3"); + checkResultContainsDocumentsInOrder( + query4, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc3"); } @Test @@ -275,7 +316,7 @@ public void orQueriesWithIn() throws ExecutionException, InterruptedException, T CollectionReference collection = testCollectionWithDocs(testDocs); // a==2 || b in [2,3] - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 2), Filter.inArray("b", asList(2, 3)))), "doc3", "doc4", @@ -285,9 +326,6 @@ public void orQueriesWithIn() throws ExecutionException, InterruptedException, T @Test public void orQueriesWithNotIn() throws ExecutionException, InterruptedException, TimeoutException { - assumeTrue( - "Skip this test when running against production because it is currently not supported.", - isRunningAgainstFirestoreEmulator(firestore)); Map> testDocs = map( "doc1", map("a", 1, "b", 0), @@ -300,8 +338,9 @@ public void orQueriesWithNotIn() // a==2 || b not-in [2,3] // Has implicit orderBy b. - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 2), Filter.notInArray("b", asList(2, 3)))), + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc1", "doc2"); } @@ -320,14 +359,14 @@ public void orQueriesWithArrayMembership() CollectionReference collection = testCollectionWithDocs(testDocs); // a==2 || b array-contains 7 - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where(Filter.or(Filter.equalTo("a", 2), Filter.arrayContains("b", 7))), "doc3", "doc4", "doc6"); // a==2 || b array-contains-any [0, 3] - checkQuerySnapshotContainsDocuments( + checkResultContainsDocumentsInOrder( collection.where( Filter.or(Filter.equalTo("a", 2), Filter.arrayContainsAny("b", asList(0, 3)))), "doc1", @@ -351,35 +390,31 @@ public void testUsingInWithArrayContains() Query query1 = collection.where( Filter.or(Filter.inArray("a", asList(2, 3)), Filter.arrayContains("b", 3))); - checkQuerySnapshotContainsDocuments(query1, "doc3", "doc4", "doc6"); + checkResultContainsDocumentsInOrder(query1, "doc3", "doc4", "doc6"); Query query2 = collection.where( Filter.and(Filter.inArray("a", asList(2, 3)), Filter.arrayContains("b", 7))); - checkQuerySnapshotContainsDocuments(query2, "doc3"); + checkResultContainsDocumentsInOrder(query2, "doc3"); Query query3 = collection.where( Filter.or( Filter.inArray("a", asList(2, 3)), Filter.and(Filter.arrayContains("b", 3), Filter.equalTo("a", 1)))); - checkQuerySnapshotContainsDocuments(query3, "doc3", "doc4", "doc6"); + checkResultContainsDocumentsInOrder(query3, "doc3", "doc4", "doc6"); Query query4 = collection.where( Filter.and( Filter.inArray("a", asList(2, 3)), Filter.or(Filter.arrayContains("b", 7), Filter.equalTo("a", 1)))); - checkQuerySnapshotContainsDocuments(query4, "doc3"); + checkResultContainsDocumentsInOrder(query4, "doc3"); } @Test public void testOrderByEquality() throws ExecutionException, InterruptedException, TimeoutException { - assumeTrue( - "Skip this test if running against production because order-by-equality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); Map> testDocs = map( "doc1", map("a", 1, "b", asList(0)), @@ -391,21 +426,21 @@ public void testOrderByEquality() CollectionReference collection = testCollectionWithDocs(testDocs); Query query1 = collection.where(Filter.equalTo("a", 1)).orderBy("a"); - checkQuerySnapshotContainsDocuments(query1, "doc1", "doc4", "doc5"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc4", + "doc5"); Query query2 = collection.where(Filter.inArray("a", asList(2, 3))).orderBy("a"); - checkQuerySnapshotContainsDocuments(query2, "doc6", "doc3"); + checkResultContainsDocumentsInOrder( + query2, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc6", "doc3"); } /** Multiple Inequality */ @Test public void multipleInequalityOnDifferentFields() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -419,7 +454,8 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereNotEqualTo("key", "a") .whereLessThanOrEqualTo("sort", 2) .whereGreaterThan("v", 2); - checkQuerySnapshotContainsDocuments(query1, "doc3"); + checkResultContainsDocumentsInOrder( + query1, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc3"); // Duplicate inequality fields Query query2 = @@ -427,7 +463,8 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereNotEqualTo("key", "a") .whereLessThanOrEqualTo("sort", 2) .whereGreaterThan("sort", 1); - checkQuerySnapshotContainsDocuments(query2, "doc4"); + checkResultContainsDocumentsInOrder( + query2, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc4"); // With multiple IN Query query3 = @@ -436,7 +473,8 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereLessThanOrEqualTo("sort", 2) .whereIn("v", asList(2, 3, 4)) .whereIn("sort", asList(2, 3)); - checkQuerySnapshotContainsDocuments(query3, "doc4"); + checkResultContainsDocumentsInOrder( + query3, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc4"); // With NOT-IN Query query4 = @@ -444,7 +482,8 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereGreaterThanOrEqualTo("key", "a") .whereLessThanOrEqualTo("sort", 2) .whereNotIn("v", asList(2, 4, 5)); - checkQuerySnapshotContainsDocuments(query4, "doc1", "doc3"); + checkResultContainsDocumentsInOrder( + query4, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc1", "doc3"); // With orderby Query query5 = @@ -452,7 +491,12 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereGreaterThanOrEqualTo("key", "a") .whereLessThanOrEqualTo("sort", 2) .orderBy("v", Direction.DESCENDING); - checkQuerySnapshotContainsDocuments(query5, "doc3", "doc4", "doc1"); + checkResultContainsDocumentsInOrder( + query5, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc3", + "doc4", + "doc1"); // With limit Query query6 = @@ -461,7 +505,8 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereLessThanOrEqualTo("sort", 2) .orderBy("v", Direction.DESCENDING) .limit(2); - checkQuerySnapshotContainsDocuments(query6, "doc3", "doc4"); + checkResultContainsDocumentsInOrder( + query6, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc3", "doc4"); // With limitToLast Query query7 = @@ -470,17 +515,12 @@ public void multipleInequalityOnDifferentFields() throws Exception { .whereLessThanOrEqualTo("sort", 2) .orderBy("v", Direction.DESCENDING) .limitToLast(2); - checkQuerySnapshotContainsDocuments(query7, "doc4", "doc1"); + checkResultContainsDocumentsInOrder( + query7, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc4", "doc1"); } @Test public void multipleInequalityOnSpecialValues() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -492,24 +532,20 @@ public void multipleInequalityOnSpecialValues() throws Exception { "doc6", map("key", "f", "sort", 1, "v", 1))); Query query1 = collection.whereNotEqualTo("key", "a").whereLessThanOrEqualTo("sort", 2); - checkQuerySnapshotContainsDocuments(query1, "doc5", "doc6"); + checkResultContainsDocumentsInOrder( + query1, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc5", "doc6"); Query query2 = collection .whereNotEqualTo("key", "a") .whereLessThanOrEqualTo("sort", 2) .whereLessThanOrEqualTo("v", 1); - checkQuerySnapshotContainsDocuments(query2, "doc6"); + checkResultContainsDocumentsInOrder( + query2, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc6"); } @Test public void multipleInequalityWithArrayMembership() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -533,14 +569,16 @@ public void multipleInequalityWithArrayMembership() throws Exception { .whereNotEqualTo("key", "a") .whereGreaterThanOrEqualTo("sort", 1) .whereArrayContains("v", 0); - checkQuerySnapshotContainsDocuments(query1, "doc2"); + checkResultContainsDocumentsInOrder( + query1, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc2"); Query query2 = collection .whereNotEqualTo("key", "a") .whereGreaterThanOrEqualTo("sort", 1) .whereArrayContainsAny("v", asList(0, 1)); - checkQuerySnapshotContainsDocuments(query2, "doc2", "doc4"); + checkResultContainsDocumentsInOrder( + query2, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc2", "doc4"); } private static Map nestedObject(int number) { @@ -561,12 +599,6 @@ private static Map nestedObject(int number) { // result with the query fields normalized in the server. @Test public void multipleInequalityWithNestedField() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -584,8 +616,13 @@ public void multipleInequalityWithNestedField() throws Exception { .orderBy("name"); DocumentSnapshot docSnap = collection.document("doc4").get().get(); Query query1WithCursor = query1.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query1, "doc4", "doc1"); - checkQuerySnapshotContainsDocuments(query1WithCursor, "doc4", "doc1"); + checkResultContainsDocumentsInOrder( + query1, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc4", "doc1"); + checkResultContainsDocumentsInOrder( + query1WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc4", + "doc1"); // ordered by: name desc, field desc, field.dot desc, field\\slash desc, __name__ desc Query query2 = @@ -596,18 +633,13 @@ public void multipleInequalityWithNestedField() throws Exception { .orderBy("name", Direction.DESCENDING); docSnap = collection.document("doc2").get().get(); Query query2WithCursor = query2.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query2, "doc2", "doc3"); - checkQuerySnapshotContainsDocuments(query2WithCursor, "doc2", "doc3"); + checkResultContainsDocumentsInOrder( + query2, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc2", "doc3"); + checkResultContainsDocumentsInOrder(query2WithCursor, "doc2", "doc3"); } @Test public void multipleInequalityWithCompositeFilters() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -632,8 +664,20 @@ public void multipleInequalityWithCompositeFilters() throws Exception { Filter.and(Filter.notEqualTo("key", "b"), Filter.greaterThan("v", 4)))); DocumentSnapshot docSnap = collection.document("doc1").get().get(); Query query1WithCursor = query1.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query1, "doc1", "doc6", "doc5", "doc4"); - checkQuerySnapshotContainsDocuments(query1WithCursor, "doc1", "doc6", "doc5", "doc4"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc6", + "doc5", + "doc4"); + checkResultContainsDocumentsInOrder( + query1WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc6", + "doc5", + "doc4"); // Ordered by: 'sort' desc, 'key' asc, 'v' asc, __name__ asc Query query2 = @@ -646,8 +690,20 @@ public void multipleInequalityWithCompositeFilters() throws Exception { .orderBy("key"); docSnap = collection.document("doc5").get().get(); Query query2WithCursor = query2.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query2, "doc5", "doc4", "doc1", "doc6"); - checkQuerySnapshotContainsDocuments(query2WithCursor, "doc5", "doc4", "doc1", "doc6"); + checkResultContainsDocumentsInOrder( + query2, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc4", + "doc1", + "doc6"); + checkResultContainsDocumentsInOrder( + query2WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc4", + "doc1", + "doc6"); // Implicitly ordered by: 'key' asc, 'sort' asc, 'v' asc, __name__ asc Query query3 = @@ -662,19 +718,18 @@ public void multipleInequalityWithCompositeFilters() throws Exception { Filter.and(Filter.lessThan("key", "b"), Filter.greaterThan("v", 0))))); docSnap = collection.document("doc1").get().get(); Query query3WithCursor = query3.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query3, "doc1", "doc2"); - checkQuerySnapshotContainsDocuments(query3WithCursor, "doc1", "doc2"); + checkResultContainsDocumentsInOrder( + query3, /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), "doc1", "doc2"); + checkResultContainsDocumentsInOrder( + query3WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc1", + "doc2"); } @Test public void multipleInequalityFieldsWillBeImplicitlyOrderedLexicographicallyByServer() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -700,8 +755,20 @@ public void multipleInequalityFieldsWillBeImplicitlyOrderedLexicographicallyBySe .whereGreaterThan("sort", 1) .whereIn("v", asList(1, 2, 3, 4)); Query query1WithCursor = query1.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query1, "doc2", "doc4", "doc5", "doc3"); - checkQuerySnapshotContainsDocuments(query1WithCursor, "doc2", "doc4", "doc5", "doc3"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc5", + "doc3"); + checkResultContainsDocumentsInOrder( + query1WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc5", + "doc3"); // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc Query query2 = @@ -710,18 +777,24 @@ public void multipleInequalityFieldsWillBeImplicitlyOrderedLexicographicallyBySe .whereNotEqualTo("key", "a") .whereIn("v", asList(1, 2, 3, 4)); Query query2WithCursor = query2.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query2, "doc2", "doc4", "doc5", "doc3"); - checkQuerySnapshotContainsDocuments(query2WithCursor, "doc2", "doc4", "doc5", "doc3"); + checkResultContainsDocumentsInOrder( + query2, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc5", + "doc3"); + checkResultContainsDocumentsInOrder( + query2WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc5", + "doc3"); } @Test public void multipleInequalityWithMultipleExplicitOrderBy() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -744,8 +817,20 @@ public void multipleInequalityWithMultipleExplicitOrderBy() throws Exception { Query query1 = collection.whereGreaterThan("key", "a").whereGreaterThanOrEqualTo("sort", 1).orderBy("v"); Query query1WithCursor = query1.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query1, "doc2", "doc4", "doc3", "doc5"); - checkQuerySnapshotContainsDocuments(query1WithCursor, "doc2", "doc4", "doc3", "doc5"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3", + "doc5"); + checkResultContainsDocumentsInOrder( + query1WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3", + "doc5"); // Ordered by: 'v asc, 'sort' asc, 'key' asc, __name__ asc Query query2 = @@ -755,8 +840,20 @@ public void multipleInequalityWithMultipleExplicitOrderBy() throws Exception { .orderBy("v") .orderBy("sort"); Query query2WithCursor = query2.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query2, "doc2", "doc5", "doc4", "doc3"); - checkQuerySnapshotContainsDocuments(query2WithCursor, "doc2", "doc5", "doc4", "doc3"); + checkResultContainsDocumentsInOrder( + query2, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc5", + "doc4", + "doc3"); + checkResultContainsDocumentsInOrder( + query2WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc5", + "doc4", + "doc3"); docSnap = collection.document("doc5").get().get(); @@ -768,8 +865,20 @@ public void multipleInequalityWithMultipleExplicitOrderBy() throws Exception { .whereGreaterThanOrEqualTo("sort", 1) .orderBy("v", Direction.DESCENDING); Query query3WithCursor = query3.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query3, "doc5", "doc3", "doc4", "doc2"); - checkQuerySnapshotContainsDocuments(query3WithCursor, "doc5", "doc3", "doc4", "doc2"); + checkResultContainsDocumentsInOrder( + query3, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc3", + "doc4", + "doc2"); + checkResultContainsDocumentsInOrder( + query3WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc3", + "doc4", + "doc2"); // Ordered by: 'v desc, 'sort' asc, 'key' asc, __name__ asc Query query4 = @@ -779,18 +888,24 @@ public void multipleInequalityWithMultipleExplicitOrderBy() throws Exception { .orderBy("v", Direction.DESCENDING) .orderBy("sort"); Query query4WithCursor = query4.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query4, "doc5", "doc4", "doc3", "doc2"); - checkQuerySnapshotContainsDocuments(query4WithCursor, "doc5", "doc4", "doc3", "doc2"); + checkResultContainsDocumentsInOrder( + query4, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc4", + "doc3", + "doc2"); + checkResultContainsDocumentsInOrder( + query4WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc5", + "doc4", + "doc3", + "doc2"); } @Test public void multipleInequalityFieldsInAggregateQuery() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -811,18 +926,15 @@ public void multipleInequalityFieldsInAggregateQuery() throws Exception { .whereGreaterThanOrEqualTo("sort", 1) .orderBy("v") .count(); - assertThat(query.get().get().getCount()).isEqualTo(4); + if (isRunningAgainstFirestoreEmulator(firestore)) { + assertThat(query.get().get().getCount()).isEqualTo(4); + } + assertThat(query.pipeline().execute().get()).isNotEmpty(); // TODO(MIEQ): Add sum and average when they are public. } @Test public void multipleInequalityFieldsWithDocumentKey() throws Exception { - // TODO(MIEQ): Enable this test against production when possible. - assumeTrue( - "Skip this test if running against production because multiple inequality is " - + "not supported yet.", - isRunningAgainstFirestoreEmulator(firestore)); - CollectionReference collection = testCollectionWithDocs( map( @@ -847,8 +959,18 @@ public void multipleInequalityFieldsWithDocumentKey() throws Exception { .whereNotEqualTo("key", "a") .whereLessThan(FieldPath.documentId(), "doc5"); Query query1WithCursor = query1.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query1, "doc2", "doc4", "doc3"); - checkQuerySnapshotContainsDocuments(query1WithCursor, "doc2", "doc4", "doc3"); + checkResultContainsDocumentsInOrder( + query1, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3"); + checkResultContainsDocumentsInOrder( + query1WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3"); // Changing filters order will not affect implicit order. // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc @@ -858,8 +980,18 @@ public void multipleInequalityFieldsWithDocumentKey() throws Exception { .whereGreaterThan("sort", 1) .whereNotEqualTo("key", "a"); Query query2WithCursor = query2.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query2, "doc2", "doc4", "doc3"); - checkQuerySnapshotContainsDocuments(query2WithCursor, "doc2", "doc4", "doc3"); + checkResultContainsDocumentsInOrder( + query2, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3"); + checkResultContainsDocumentsInOrder( + query2WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc4", + "doc3"); // Ordered by: 'sort' desc, 'key' desc, __name__ desc Query query3 = @@ -869,248 +1001,17 @@ public void multipleInequalityFieldsWithDocumentKey() throws Exception { .whereNotEqualTo("key", "a") .orderBy("sort", Direction.DESCENDING); Query query3WithCursor = query3.startAt(docSnap); - checkQuerySnapshotContainsDocuments(query3, "doc2", "doc3", "doc4"); - checkQuerySnapshotContainsDocuments(query3WithCursor, "doc2", "doc3", "doc4"); - } - - @Test - public void testQueryPlan() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - Query query = collection.where(Filter.equalTo("a", 1)).orderBy("a"); - ExplainResults explainResults = - query.explain(ExplainOptions.builder().setAnalyze(false).build()).get(); - - @Nullable QuerySnapshot snapshot = explainResults.getSnapshot(); - assertThat(snapshot).isNull(); - - ExplainMetrics metrics = explainResults.getMetrics(); - assertThat(metrics).isNotNull(); - - PlanSummary planSummary = metrics.getPlanSummary(); - assertThat(planSummary).isNotNull(); - assertThat(planSummary.getIndexesUsed()).isNotEmpty(); - - ExecutionStats stats = metrics.getExecutionStats(); - assertThat(stats).isNull(); - } - - @Test - public void testQueryProfile() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - Query query = collection.where(Filter.equalTo("a", 1)).orderBy("a"); - ExplainResults explainResults = - query.explain(ExplainOptions.builder().setAnalyze(true).build()).get(); - - @Nullable QuerySnapshot snapshot = explainResults.getSnapshot(); - assertThat(snapshot).isNotNull(); - assertThat(snapshot.size()).isEqualTo(3); - - ExplainMetrics metrics = explainResults.getMetrics(); - assertThat(metrics).isNotNull(); - - PlanSummary planSummary = metrics.getPlanSummary(); - assertThat(planSummary).isNotNull(); - assertThat(planSummary.getIndexesUsed()).isNotEmpty(); - - ExecutionStats stats = metrics.getExecutionStats(); - assertThat(stats).isNotNull(); - assertThat(stats.getDebugStats()).isNotEmpty(); - assertThat(stats.getReadOperations()).isEqualTo(3); - assertThat(stats.getResultsReturned()).isEqualTo(3); - assertThat(stats.getExecutionDuration()).isGreaterThan(Duration.ZERO); - } - - @Test - public void testQueryProfileForQueryWithNoResultSet() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - Query query = collection.where(Filter.equalTo("a", 100)).orderBy("a"); - - // Regular query execution (get). - QuerySnapshot getSnapshot = query.get().get(); - assertThat(getSnapshot.size()).isEqualTo(0); - - // Explain. - ExplainResults explainResults = - query.explain(ExplainOptions.builder().setAnalyze(true).build()).get(); - - @Nullable QuerySnapshot snapshot = explainResults.getSnapshot(); - assertThat(snapshot).isNotNull(); - assertThat(snapshot.size()).isEqualTo(0); - - ExplainMetrics metrics = explainResults.getMetrics(); - assertThat(metrics).isNotNull(); - - PlanSummary planSummary = metrics.getPlanSummary(); - assertThat(planSummary).isNotNull(); - assertThat(planSummary.getIndexesUsed()).isNotEmpty(); - - ExecutionStats stats = metrics.getExecutionStats(); - assertThat(stats).isNotNull(); - assertThat(stats.getDebugStats()).isNotEmpty(); - assertThat(stats.getReadOperations()).isGreaterThan(0); - assertThat(stats.getResultsReturned()).isEqualTo(0); - assertThat(stats.getExecutionDuration()).isGreaterThan(Duration.ZERO); - } - - @Test - public void testExplainStreamWithoutAnalyze() throws Exception { - CollectionReference collection = testCollectionWithDocs(Collections.emptyMap()); - Query query = collection.where(Filter.equalTo("a", 1)).orderBy("a"); - - ApiFuture metricsFuture = - query.explainStream( - ExplainOptions.builder().setAnalyze(false).build(), - new ApiStreamObserver() { - @Override - public void onNext(DocumentSnapshot documentSnapshot) { - fail("No DocumentSnapshot should be received because analyze option was disabled."); - } - - @Override - public void onError(Throwable throwable) { - fail(throwable.getMessage()); - } - - @Override - public void onCompleted() {} - }); - - ExplainMetrics metrics = metricsFuture.get(); - assertThat(metrics.getPlanSummary().getIndexesUsed().size()).isGreaterThan(0); - assertThat(metrics.getExecutionStats()).isNull(); - } - - @Test - public void testExplainStreamWithAnalyze() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - Query query = collection.where(Filter.equalTo("a", 1)).orderBy("a"); - - final Iterator iterator = Arrays.asList("doc1", "doc4", "doc5").iterator(); - - ApiFuture metricsFuture = - query.explainStream( - ExplainOptions.builder().setAnalyze(true).build(), - new ApiStreamObserver() { - @Override - public void onNext(DocumentSnapshot documentSnapshot) { - assertEquals(iterator.next(), documentSnapshot.getId()); - } - - @Override - public void onError(Throwable throwable) { - fail(throwable.getMessage()); - } - - @Override - public void onCompleted() {} - }); - - ExplainMetrics metrics = metricsFuture.get(); - assertThat(metrics.getPlanSummary().getIndexesUsed().size()).isGreaterThan(0); - assertThat(metrics.getExecutionStats()).isNotNull(); - assertThat(metrics.getExecutionStats().getResultsReturned()).isEqualTo(3); - } - - @Test - public void testAggregateQueryPlan() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - AggregateQuery query = collection.where(Filter.equalTo("a", 1)).orderBy("a").count(); - - ExplainResults explainResults = - query.explain(ExplainOptions.builder().setAnalyze(false).build()).get(); - - @Nullable AggregateQuerySnapshot snapshot = explainResults.getSnapshot(); - assertThat(snapshot).isNull(); - - ExplainMetrics metrics = explainResults.getMetrics(); - assertThat(metrics).isNotNull(); - - PlanSummary planSummary = metrics.getPlanSummary(); - assertThat(planSummary).isNotNull(); - assertThat(planSummary.getIndexesUsed()).isNotEmpty(); - - ExecutionStats stats = metrics.getExecutionStats(); - assertThat(stats).isNull(); - } - - @Test - public void testAggregateQueryProfile() throws Exception { - Map> testDocs = - map( - "doc1", map("a", 1, "b", asList(0)), - "doc2", map("b", asList(1)), - "doc3", map("a", 3, "b", asList(2, 7), "c", 10), - "doc4", map("a", 1, "b", asList(3, 7)), - "doc5", map("a", 1), - "doc6", map("a", 2, "c", 20)); - CollectionReference collection = testCollectionWithDocs(testDocs); - - AggregateQuery query = collection.where(Filter.equalTo("a", 1)).orderBy("a").count(); - - ExplainResults explainResults = - query.explain(ExplainOptions.builder().setAnalyze(true).build()).get(); - - @Nullable AggregateQuerySnapshot snapshot = explainResults.getSnapshot(); - assertThat(snapshot).isNotNull(); - assertThat(snapshot.getCount()).isEqualTo(3); - - ExplainMetrics metrics = explainResults.getMetrics(); - assertThat(metrics).isNotNull(); - - PlanSummary planSummary = metrics.getPlanSummary(); - assertThat(planSummary).isNotNull(); - assertThat(planSummary.getIndexesUsed()).isNotEmpty(); - - ExecutionStats stats = metrics.getExecutionStats(); - assertThat(stats).isNotNull(); - assertThat(stats.getDebugStats()).isNotEmpty(); - assertThat(stats.getReadOperations()).isEqualTo(1); - assertThat(stats.getResultsReturned()).isEqualTo(1); - assertThat(stats.getExecutionDuration()).isGreaterThan(Duration.ZERO); + checkResultContainsDocumentsInOrder( + query3, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc3", + "doc4"); + checkResultContainsDocumentsInOrder( + query3WithCursor, + /*pipelineOnly*/ !isRunningAgainstFirestoreEmulator(firestore), + "doc2", + "doc3", + "doc4"); } } diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientHttpJsonTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientHttpJsonTest.java index 86e0c966a..605cf0663 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientHttpJsonTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientHttpJsonTest.java @@ -483,6 +483,17 @@ public void runQueryExceptionTest() throws Exception { mockService.addException(exception); } + @Test + public void executePipelineTest() throws Exception {} + + @Test + public void executePipelineExceptionTest() throws Exception { + ApiException exception = + ApiExceptionFactory.createException( + new Exception(), FakeStatusCode.of(StatusCode.Code.INVALID_ARGUMENT), false); + mockService.addException(exception); + } + @Test public void runAggregationQueryTest() throws Exception {} diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientTest.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientTest.java index 885ebc7b9..97400f5ad 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientTest.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/FirestoreClientTest.java @@ -47,8 +47,8 @@ import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; import com.google.firestore.v1.DocumentMask; -import com.google.firestore.v1.ExplainMetrics; -import com.google.firestore.v1.ExplainOptions; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; import com.google.firestore.v1.ListCollectionIdsResponse; @@ -507,14 +507,9 @@ public void runQueryTest() throws Exception { .setDocument(Document.newBuilder().build()) .setReadTime(Timestamp.newBuilder().build()) .setSkippedResults(880286183) - .setExplainMetrics(ExplainMetrics.newBuilder().build()) .build(); mockFirestore.addResponse(expectedResponse); - RunQueryRequest request = - RunQueryRequest.newBuilder() - .setParent("parent-995424086") - .setExplainOptions(ExplainOptions.newBuilder().build()) - .build(); + RunQueryRequest request = RunQueryRequest.newBuilder().setParent("parent-995424086").build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); @@ -530,11 +525,7 @@ public void runQueryTest() throws Exception { public void runQueryExceptionTest() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockFirestore.addException(exception); - RunQueryRequest request = - RunQueryRequest.newBuilder() - .setParent("parent-995424086") - .setExplainOptions(ExplainOptions.newBuilder().build()) - .build(); + RunQueryRequest request = RunQueryRequest.newBuilder().setParent("parent-995424086").build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); @@ -551,6 +542,52 @@ public void runQueryExceptionTest() throws Exception { } } + @Test + public void executePipelineTest() throws Exception { + ExecutePipelineResponse expectedResponse = + ExecutePipelineResponse.newBuilder() + .setTransaction(ByteString.EMPTY) + .addAllResults(new ArrayList()) + .setExecutionTime(Timestamp.newBuilder().build()) + .build(); + mockFirestore.addResponse(expectedResponse); + ExecutePipelineRequest request = + ExecutePipelineRequest.newBuilder().setDatabase("database1789464955").build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.executePipelineCallable(); + callable.serverStreamingCall(request, responseObserver); + + List actualResponses = responseObserver.future().get(); + Assert.assertEquals(1, actualResponses.size()); + Assert.assertEquals(expectedResponse, actualResponses.get(0)); + } + + @Test + public void executePipelineExceptionTest() throws Exception { + StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); + mockFirestore.addException(exception); + ExecutePipelineRequest request = + ExecutePipelineRequest.newBuilder().setDatabase("database1789464955").build(); + + MockStreamObserver responseObserver = new MockStreamObserver<>(); + + ServerStreamingCallable callable = + client.executePipelineCallable(); + callable.serverStreamingCall(request, responseObserver); + + try { + List actualResponses = responseObserver.future().get(); + Assert.fail("No exception thrown"); + } catch (ExecutionException e) { + Assert.assertTrue(e.getCause() instanceof InvalidArgumentException); + InvalidArgumentException apiException = ((InvalidArgumentException) e.getCause()); + Assert.assertEquals(StatusCode.Code.INVALID_ARGUMENT, apiException.getStatusCode().getCode()); + } + } + @Test public void runAggregationQueryTest() throws Exception { RunAggregationQueryResponse expectedResponse = @@ -558,14 +595,10 @@ public void runAggregationQueryTest() throws Exception { .setResult(AggregationResult.newBuilder().build()) .setTransaction(ByteString.EMPTY) .setReadTime(Timestamp.newBuilder().build()) - .setExplainMetrics(ExplainMetrics.newBuilder().build()) .build(); mockFirestore.addResponse(expectedResponse); RunAggregationQueryRequest request = - RunAggregationQueryRequest.newBuilder() - .setParent("parent-995424086") - .setExplainOptions(ExplainOptions.newBuilder().build()) - .build(); + RunAggregationQueryRequest.newBuilder().setParent("parent-995424086").build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); @@ -583,10 +616,7 @@ public void runAggregationQueryExceptionTest() throws Exception { StatusRuntimeException exception = new StatusRuntimeException(io.grpc.Status.INVALID_ARGUMENT); mockFirestore.addException(exception); RunAggregationQueryRequest request = - RunAggregationQueryRequest.newBuilder() - .setParent("parent-995424086") - .setExplainOptions(ExplainOptions.newBuilder().build()) - .build(); + RunAggregationQueryRequest.newBuilder().setParent("parent-995424086").build(); MockStreamObserver responseObserver = new MockStreamObserver<>(); diff --git a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/MockFirestoreImpl.java b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/MockFirestoreImpl.java index 7de1495d4..31eba7263 100644 --- a/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/MockFirestoreImpl.java +++ b/google-cloud-firestore/src/test/java/com/google/cloud/firestore/v1/MockFirestoreImpl.java @@ -28,6 +28,8 @@ import com.google.firestore.v1.CreateDocumentRequest; import com.google.firestore.v1.DeleteDocumentRequest; import com.google.firestore.v1.Document; +import com.google.firestore.v1.ExecutePipelineRequest; +import com.google.firestore.v1.ExecutePipelineResponse; import com.google.firestore.v1.FirestoreGrpc.FirestoreImplBase; import com.google.firestore.v1.GetDocumentRequest; import com.google.firestore.v1.ListCollectionIdsRequest; @@ -273,6 +275,27 @@ public void runQuery(RunQueryRequest request, StreamObserver r } } + @Override + public void executePipeline( + ExecutePipelineRequest request, StreamObserver responseObserver) { + Object response = responses.poll(); + if (response instanceof ExecutePipelineResponse) { + requests.add(request); + responseObserver.onNext(((ExecutePipelineResponse) response)); + responseObserver.onCompleted(); + } else if (response instanceof Exception) { + responseObserver.onError(((Exception) response)); + } else { + responseObserver.onError( + new IllegalArgumentException( + String.format( + "Unrecognized response type %s for method ExecutePipeline, expected %s or %s", + response == null ? "null" : response.getClass().getName(), + ExecutePipelineResponse.class.getName(), + Exception.class.getName()))); + } + } + @Override public void runAggregationQuery( RunAggregationQueryRequest request, diff --git a/grpc-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreGrpc.java b/grpc-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreGrpc.java index 24bd52f05..ecdbe1c13 100644 --- a/grpc-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreGrpc.java +++ b/grpc-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreGrpc.java @@ -421,6 +421,50 @@ private FirestoreGrpc() {} return getRunQueryMethod; } + private static volatile io.grpc.MethodDescriptor< + com.google.firestore.v1.ExecutePipelineRequest, + com.google.firestore.v1.ExecutePipelineResponse> + getExecutePipelineMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "ExecutePipeline", + requestType = com.google.firestore.v1.ExecutePipelineRequest.class, + responseType = com.google.firestore.v1.ExecutePipelineResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor< + com.google.firestore.v1.ExecutePipelineRequest, + com.google.firestore.v1.ExecutePipelineResponse> + getExecutePipelineMethod() { + io.grpc.MethodDescriptor< + com.google.firestore.v1.ExecutePipelineRequest, + com.google.firestore.v1.ExecutePipelineResponse> + getExecutePipelineMethod; + if ((getExecutePipelineMethod = FirestoreGrpc.getExecutePipelineMethod) == null) { + synchronized (FirestoreGrpc.class) { + if ((getExecutePipelineMethod = FirestoreGrpc.getExecutePipelineMethod) == null) { + FirestoreGrpc.getExecutePipelineMethod = + getExecutePipelineMethod = + io.grpc.MethodDescriptor + . + newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ExecutePipeline")) + .setSampledToLocalTracing(true) + .setRequestMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.firestore.v1.ExecutePipelineRequest.getDefaultInstance())) + .setResponseMarshaller( + io.grpc.protobuf.ProtoUtils.marshaller( + com.google.firestore.v1.ExecutePipelineResponse.getDefaultInstance())) + .setSchemaDescriptor(new FirestoreMethodDescriptorSupplier("ExecutePipeline")) + .build(); + } + } + } + return getExecutePipelineMethod; + } + private static volatile io.grpc.MethodDescriptor< com.google.firestore.v1.RunAggregationQueryRequest, com.google.firestore.v1.RunAggregationQueryResponse> @@ -906,6 +950,21 @@ default void runQuery( io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRunQueryMethod(), responseObserver); } + /** + * + * + *
+     * Executes a pipeline query.
+     * 
+ */ + default void executePipeline( + com.google.firestore.v1.ExecutePipelineRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall( + getExecutePipelineMethod(), responseObserver); + } + /** * * @@ -1212,6 +1271,23 @@ public void runQuery( getChannel().newCall(getRunQueryMethod(), getCallOptions()), request, responseObserver); } + /** + * + * + *
+     * Executes a pipeline query.
+     * 
+ */ + public void executePipeline( + com.google.firestore.v1.ExecutePipelineRequest request, + io.grpc.stub.StreamObserver + responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getExecutePipelineMethod(), getCallOptions()), + request, + responseObserver); + } + /** * * @@ -1483,6 +1559,19 @@ public java.util.Iterator runQuery( getChannel(), getRunQueryMethod(), getCallOptions(), request); } + /** + * + * + *
+     * Executes a pipeline query.
+     * 
+ */ + public java.util.Iterator executePipeline( + com.google.firestore.v1.ExecutePipelineRequest request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getExecutePipelineMethod(), getCallOptions(), request); + } + /** * * @@ -1759,13 +1848,14 @@ public com.google.common.util.concurrent.ListenableFuture implements io.grpc.stub.ServerCalls.UnaryMethod, @@ -1834,6 +1924,12 @@ public void invoke(Req request, io.grpc.stub.StreamObserver responseObserv (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_EXECUTE_PIPELINE: + serviceImpl.executePipeline( + (com.google.firestore.v1.ExecutePipelineRequest) request, + (io.grpc.stub.StreamObserver) + responseObserver); + break; case METHODID_RUN_AGGREGATION_QUERY: serviceImpl.runAggregationQuery( (com.google.firestore.v1.RunAggregationQueryRequest) request, @@ -1948,6 +2044,13 @@ public static final io.grpc.ServerServiceDefinition bindService(AsyncService ser new MethodHandlers< com.google.firestore.v1.RunQueryRequest, com.google.firestore.v1.RunQueryResponse>(service, METHODID_RUN_QUERY))) + .addMethod( + getExecutePipelineMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + com.google.firestore.v1.ExecutePipelineRequest, + com.google.firestore.v1.ExecutePipelineResponse>( + service, METHODID_EXECUTE_PIPELINE))) .addMethod( getRunAggregationQueryMethod(), io.grpc.stub.ServerCalls.asyncServerStreamingCall( @@ -2053,6 +2156,7 @@ public static io.grpc.ServiceDescriptor getServiceDescriptor() { .addMethod(getCommitMethod()) .addMethod(getRollbackMethod()) .addMethod(getRunQueryMethod()) + .addMethod(getExecutePipelineMethod()) .addMethod(getRunAggregationQueryMethod()) .addMethod(getPartitionQueryMethod()) .addMethod(getWriteMethod()) diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/Backup.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/Backup.java index aa61d5aa3..25a0b809b 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/Backup.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/Backup.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/backup.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupOrBuilder.java index dd9af1b2c..8da642d41 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/backup.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface BackupOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupProto.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupProto.java index 6f0a802ae..deab8154c 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupProto.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupProto.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/backup.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public final class BackupProto { diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupSchedule.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupSchedule.java index cb1074ec2..7c549cea5 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupSchedule.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupSchedule.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupScheduleOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupScheduleOrBuilder.java index 723400cee..d31b3c5c2 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupScheduleOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/BackupScheduleOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface BackupScheduleOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequest.java index b30470fa7..63dbeb830 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequestOrBuilder.java index 53131c507..d5402d0e4 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/CreateBackupScheduleRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface CreateBackupScheduleRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrence.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrence.java index 353b9464e..8b21cbc67 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrence.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrence.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrenceOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrenceOrBuilder.java index 6ee832b1f..750956a9b 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrenceOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DailyRecurrenceOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface DailyRecurrenceOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequest.java index 112572a0d..e4643bb90 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequestOrBuilder.java index 790ba2bb2..40dcbef62 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface DeleteBackupRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequest.java index 5fc48b2a0..b17dc9415 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequestOrBuilder.java index 4bff0493b..3844da9fd 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/DeleteBackupScheduleRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface DeleteBackupScheduleRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequest.java index e9be92d06..bc3a04431 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequestOrBuilder.java index a475a5173..541b353aa 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface GetBackupRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequest.java index 18a4ad0ee..466569f11 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequestOrBuilder.java index 6c33e1e67..d75c69e10 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/GetBackupScheduleRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface GetBackupScheduleRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequest.java index 441f55ac8..c8f38c04c 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequestOrBuilder.java index 2c4bba0b5..c2d083160 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface ListBackupSchedulesRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponse.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponse.java index 07fbfebda..ea2ac8418 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponse.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponse.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponseOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponseOrBuilder.java index b2b4cc77c..eea1e95de 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponseOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupSchedulesResponseOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface ListBackupSchedulesResponseOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequest.java index fd2bc58c4..63727c091 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequestOrBuilder.java index ab2541756..2945d5c15 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface ListBackupsRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponse.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponse.java index 444e6d34d..728d020c9 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponse.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponse.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponseOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponseOrBuilder.java index 6d36e5016..9cbfc18a4 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponseOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ListBackupsResponseOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface ListBackupsResponseOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadata.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadata.java index d34f928c7..00716f960 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadata.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadata.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/operation.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadataOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadataOrBuilder.java index 607e33338..10131af08 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadataOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseMetadataOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/operation.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface RestoreDatabaseMetadataOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequest.java index 4afad3b7e..1f88b08d7 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequestOrBuilder.java index a1b317b9f..33d7b0110 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/RestoreDatabaseRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface RestoreDatabaseRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ScheduleProto.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ScheduleProto.java index 8bcd70222..ddec765b9 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ScheduleProto.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/ScheduleProto.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public final class ScheduleProto { diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequest.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequest.java index 50704d968..e0ef6097a 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequest.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequest.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequestOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequestOrBuilder.java index 347c89d92..07e4d0cb7 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequestOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/UpdateBackupScheduleRequestOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/firestore_admin.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface UpdateBackupScheduleRequestOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrence.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrence.java index 256e57f0c..58dcabbaf 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrence.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrence.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; /** diff --git a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrenceOrBuilder.java b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrenceOrBuilder.java index 6c265b99d..668210ab6 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrenceOrBuilder.java +++ b/proto-google-cloud-firestore-admin-v1/src/main/java/com/google/firestore/admin/v1/WeeklyRecurrenceOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/admin/v1/schedule.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.admin.v1; public interface WeeklyRecurrenceOrBuilder diff --git a/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/backup.proto b/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/backup.proto index 45f3adc8e..e01f81ff8 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/backup.proto +++ b/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/backup.proto @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/schedule.proto b/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/schedule.proto index 52200e8e5..7a45238f0 100644 --- a/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/schedule.proto +++ b/proto-google-cloud-firestore-admin-v1/src/main/proto/google/firestore/admin/v1/schedule.proto @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/DocumentProto.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/DocumentProto.java index 350f1f50b..49ed13f86 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/DocumentProto.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/DocumentProto.java @@ -52,6 +52,26 @@ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry r internal_static_google_firestore_v1_MapValue_FieldsEntry_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_google_firestore_v1_MapValue_FieldsEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_Function_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_Function_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_Function_OptionsEntry_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_Function_OptionsEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_Pipeline_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_Pipeline_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_Pipeline_Stage_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_Pipeline_Stage_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { return descriptor; @@ -71,7 +91,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "p\022/\n\013update_time\030\004 \001(\0132\032.google.protobuf" + ".Timestamp\032I\n\013FieldsEntry\022\013\n\003key\030\001 \001(\t\022)" + "\n\005value\030\002 \001(\0132\032.google.firestore.v1.Valu" - + "e:\0028\001\"\256\003\n\005Value\0220\n\nnull_value\030\013 \001(\0162\032.go" + + "e:\0028\001\"\301\004\n\005Value\0220\n\nnull_value\030\013 \001(\0162\032.go" + "ogle.protobuf.NullValueH\000\022\027\n\rboolean_val" + "ue\030\001 \001(\010H\000\022\027\n\rinteger_value\030\002 \001(\003H\000\022\026\n\014d" + "ouble_value\030\003 \001(\001H\000\0225\n\017timestamp_value\030\n" @@ -81,18 +101,33 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "t_value\030\010 \001(\0132\023.google.type.LatLngH\000\0226\n\013" + "array_value\030\t \001(\0132\037.google.firestore.v1." + "ArrayValueH\000\0222\n\tmap_value\030\006 \001(\0132\035.google" - + ".firestore.v1.MapValueH\000B\014\n\nvalue_type\"8" - + "\n\nArrayValue\022*\n\006values\030\001 \003(\0132\032.google.fi" - + "restore.v1.Value\"\220\001\n\010MapValue\0229\n\006fields\030" - + "\001 \003(\0132).google.firestore.v1.MapValue.Fie" - + "ldsEntry\032I\n\013FieldsEntry\022\013\n\003key\030\001 \001(\t\022)\n\005" - + "value\030\002 \001(\0132\032.google.firestore.v1.Value:" - + "\0028\001B\305\001\n\027com.google.firestore.v1B\rDocumen" - + "tProtoP\001Z;cloud.google.com/go/firestore/" - + "apiv1/firestorepb;firestorepb\242\002\004GCFS\252\002\031G" - + "oogle.Cloud.Firestore.V1\312\002\031Google\\Cloud\\" - + "Firestore\\V1\352\002\034Google::Cloud::Firestore:" - + ":V1b\006proto3" + + ".firestore.v1.MapValueH\000\022\037\n\025field_refere" + + "nce_value\030\023 \001(\tH\000\0227\n\016function_value\030\024 \001(" + + "\0132\035.google.firestore.v1.FunctionH\000\0227\n\016pi" + + "peline_value\030\025 \001(\0132\035.google.firestore.v1" + + ".PipelineH\000B\014\n\nvalue_type\"8\n\nArrayValue\022" + + "*\n\006values\030\001 \003(\0132\032.google.firestore.v1.Va" + + "lue\"\220\001\n\010MapValue\0229\n\006fields\030\001 \003(\0132).googl" + + "e.firestore.v1.MapValue.FieldsEntry\032I\n\013F" + + "ieldsEntry\022\013\n\003key\030\001 \001(\t\022)\n\005value\030\002 \001(\0132\032" + + ".google.firestore.v1.Value:\0028\001\"\313\001\n\010Funct" + + "ion\022\014\n\004name\030\001 \001(\t\022(\n\004args\030\002 \003(\0132\032.google" + + ".firestore.v1.Value\022;\n\007options\030\003 \003(\0132*.g" + + "oogle.firestore.v1.Function.OptionsEntry" + + "\032J\n\014OptionsEntry\022\013\n\003key\030\001 \001(\t\022)\n\005value\030\002" + + " \001(\0132\032.google.firestore.v1.Value:\0028\001\"\220\002\n" + + "\010Pipeline\0223\n\006stages\030\001 \003(\0132#.google.fires" + + "tore.v1.Pipeline.Stage\032\316\001\n\005Stage\022\014\n\004name" + + "\030\001 \001(\t\022(\n\004args\030\002 \003(\0132\032.google.firestore." + + "v1.Value\022A\n\007options\030\003 \003(\01320.google.fires" + + "tore.v1.Pipeline.Stage.OptionsEntry\032J\n\014O" + + "ptionsEntry\022\013\n\003key\030\001 \001(\t\022)\n\005value\030\002 \001(\0132" + + "\032.google.firestore.v1.Value:\0028\001B\305\001\n\027com." + + "google.firestore.v1B\rDocumentProtoP\001Z;cl" + + "oud.google.com/go/firestore/apiv1/firest" + + "orepb;firestorepb\242\002\004GCFS\252\002\031Google.Cloud." + + "Firestore.V1\312\002\031Google\\Cloud\\Firestore\\V1" + + "\352\002\034Google::Cloud::Firestore::V1b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( @@ -134,6 +169,9 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { "GeoPointValue", "ArrayValue", "MapValue", + "FieldReferenceValue", + "FunctionValue", + "PipelineValue", "ValueType", }); internal_static_google_firestore_v1_ArrayValue_descriptor = @@ -160,6 +198,46 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { new java.lang.String[] { "Key", "Value", }); + internal_static_google_firestore_v1_Function_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_google_firestore_v1_Function_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_Function_descriptor, + new java.lang.String[] { + "Name", "Args", "Options", + }); + internal_static_google_firestore_v1_Function_OptionsEntry_descriptor = + internal_static_google_firestore_v1_Function_descriptor.getNestedTypes().get(0); + internal_static_google_firestore_v1_Function_OptionsEntry_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_Function_OptionsEntry_descriptor, + new java.lang.String[] { + "Key", "Value", + }); + internal_static_google_firestore_v1_Pipeline_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_google_firestore_v1_Pipeline_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_Pipeline_descriptor, + new java.lang.String[] { + "Stages", + }); + internal_static_google_firestore_v1_Pipeline_Stage_descriptor = + internal_static_google_firestore_v1_Pipeline_descriptor.getNestedTypes().get(0); + internal_static_google_firestore_v1_Pipeline_Stage_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_Pipeline_Stage_descriptor, + new java.lang.String[] { + "Name", "Args", "Options", + }); + internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_descriptor = + internal_static_google_firestore_v1_Pipeline_Stage_descriptor.getNestedTypes().get(0); + internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_descriptor, + new java.lang.String[] { + "Key", "Value", + }); com.google.protobuf.StructProto.getDescriptor(); com.google.protobuf.TimestampProto.getDescriptor(); com.google.type.LatLngProto.getDescriptor(); diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequest.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequest.java new file mode 100644 index 000000000..544c520ff --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequest.java @@ -0,0 +1,1898 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +/** + * + * + *
+ * The request for [Firestore.ExecutePipeline][].
+ * 
+ * + * Protobuf type {@code google.firestore.v1.ExecutePipelineRequest} + */ +public final class ExecutePipelineRequest extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.ExecutePipelineRequest) + ExecutePipelineRequestOrBuilder { + private static final long serialVersionUID = 0L; + // Use ExecutePipelineRequest.newBuilder() to construct. + private ExecutePipelineRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private ExecutePipelineRequest() { + database_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new ExecutePipelineRequest(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.ExecutePipelineRequest.class, + com.google.firestore.v1.ExecutePipelineRequest.Builder.class); + } + + private int pipelineTypeCase_ = 0; + + @SuppressWarnings("serial") + private java.lang.Object pipelineType_; + + public enum PipelineTypeCase + implements + com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + STRUCTURED_PIPELINE(2), + PIPELINETYPE_NOT_SET(0); + private final int value; + + private PipelineTypeCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static PipelineTypeCase valueOf(int value) { + return forNumber(value); + } + + public static PipelineTypeCase forNumber(int value) { + switch (value) { + case 2: + return STRUCTURED_PIPELINE; + case 0: + return PIPELINETYPE_NOT_SET; + default: + return null; + } + } + + public int getNumber() { + return this.value; + } + }; + + public PipelineTypeCase getPipelineTypeCase() { + return PipelineTypeCase.forNumber(pipelineTypeCase_); + } + + private int consistencySelectorCase_ = 0; + + @SuppressWarnings("serial") + private java.lang.Object consistencySelector_; + + public enum ConsistencySelectorCase + implements + com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + TRANSACTION(5), + NEW_TRANSACTION(6), + READ_TIME(7), + CONSISTENCYSELECTOR_NOT_SET(0); + private final int value; + + private ConsistencySelectorCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static ConsistencySelectorCase valueOf(int value) { + return forNumber(value); + } + + public static ConsistencySelectorCase forNumber(int value) { + switch (value) { + case 5: + return TRANSACTION; + case 6: + return NEW_TRANSACTION; + case 7: + return READ_TIME; + case 0: + return CONSISTENCYSELECTOR_NOT_SET; + default: + return null; + } + } + + public int getNumber() { + return this.value; + } + }; + + public ConsistencySelectorCase getConsistencySelectorCase() { + return ConsistencySelectorCase.forNumber(consistencySelectorCase_); + } + + public static final int DATABASE_FIELD_NUMBER = 1; + + @SuppressWarnings("serial") + private volatile java.lang.Object database_ = ""; + /** + * + * + *
+   * Database identifier, in the form `projects/{project}/databases/{database}`.
+   * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The database. + */ + @java.lang.Override + public java.lang.String getDatabase() { + java.lang.Object ref = database_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + database_ = s; + return s; + } + } + /** + * + * + *
+   * Database identifier, in the form `projects/{project}/databases/{database}`.
+   * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The bytes for database. + */ + @java.lang.Override + public com.google.protobuf.ByteString getDatabaseBytes() { + java.lang.Object ref = database_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + database_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int STRUCTURED_PIPELINE_FIELD_NUMBER = 2; + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return Whether the structuredPipeline field is set. + */ + @java.lang.Override + public boolean hasStructuredPipeline() { + return pipelineTypeCase_ == 2; + } + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return The structuredPipeline. + */ + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline getStructuredPipeline() { + if (pipelineTypeCase_ == 2) { + return (com.google.firestore.v1.StructuredPipeline) pipelineType_; + } + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + @java.lang.Override + public com.google.firestore.v1.StructuredPipelineOrBuilder getStructuredPipelineOrBuilder() { + if (pipelineTypeCase_ == 2) { + return (com.google.firestore.v1.StructuredPipeline) pipelineType_; + } + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + + public static final int TRANSACTION_FIELD_NUMBER = 5; + /** + * + * + *
+   * Run the query within an already active transaction.
+   *
+   * The value here is the opaque transaction ID to execute the query in.
+   * 
+ * + * bytes transaction = 5; + * + * @return Whether the transaction field is set. + */ + @java.lang.Override + public boolean hasTransaction() { + return consistencySelectorCase_ == 5; + } + /** + * + * + *
+   * Run the query within an already active transaction.
+   *
+   * The value here is the opaque transaction ID to execute the query in.
+   * 
+ * + * bytes transaction = 5; + * + * @return The transaction. + */ + @java.lang.Override + public com.google.protobuf.ByteString getTransaction() { + if (consistencySelectorCase_ == 5) { + return (com.google.protobuf.ByteString) consistencySelector_; + } + return com.google.protobuf.ByteString.EMPTY; + } + + public static final int NEW_TRANSACTION_FIELD_NUMBER = 6; + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return Whether the newTransaction field is set. + */ + @java.lang.Override + public boolean hasNewTransaction() { + return consistencySelectorCase_ == 6; + } + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return The newTransaction. + */ + @java.lang.Override + public com.google.firestore.v1.TransactionOptions getNewTransaction() { + if (consistencySelectorCase_ == 6) { + return (com.google.firestore.v1.TransactionOptions) consistencySelector_; + } + return com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + @java.lang.Override + public com.google.firestore.v1.TransactionOptionsOrBuilder getNewTransactionOrBuilder() { + if (consistencySelectorCase_ == 6) { + return (com.google.firestore.v1.TransactionOptions) consistencySelector_; + } + return com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } + + public static final int READ_TIME_FIELD_NUMBER = 7; + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return Whether the readTime field is set. + */ + @java.lang.Override + public boolean hasReadTime() { + return consistencySelectorCase_ == 7; + } + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return The readTime. + */ + @java.lang.Override + public com.google.protobuf.Timestamp getReadTime() { + if (consistencySelectorCase_ == 7) { + return (com.google.protobuf.Timestamp) consistencySelector_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + @java.lang.Override + public com.google.protobuf.TimestampOrBuilder getReadTimeOrBuilder() { + if (consistencySelectorCase_ == 7) { + return (com.google.protobuf.Timestamp) consistencySelector_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(database_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, database_); + } + if (pipelineTypeCase_ == 2) { + output.writeMessage(2, (com.google.firestore.v1.StructuredPipeline) pipelineType_); + } + if (consistencySelectorCase_ == 5) { + output.writeBytes(5, (com.google.protobuf.ByteString) consistencySelector_); + } + if (consistencySelectorCase_ == 6) { + output.writeMessage(6, (com.google.firestore.v1.TransactionOptions) consistencySelector_); + } + if (consistencySelectorCase_ == 7) { + output.writeMessage(7, (com.google.protobuf.Timestamp) consistencySelector_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(database_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, database_); + } + if (pipelineTypeCase_ == 2) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 2, (com.google.firestore.v1.StructuredPipeline) pipelineType_); + } + if (consistencySelectorCase_ == 5) { + size += + com.google.protobuf.CodedOutputStream.computeBytesSize( + 5, (com.google.protobuf.ByteString) consistencySelector_); + } + if (consistencySelectorCase_ == 6) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 6, (com.google.firestore.v1.TransactionOptions) consistencySelector_); + } + if (consistencySelectorCase_ == 7) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 7, (com.google.protobuf.Timestamp) consistencySelector_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.ExecutePipelineRequest)) { + return super.equals(obj); + } + com.google.firestore.v1.ExecutePipelineRequest other = + (com.google.firestore.v1.ExecutePipelineRequest) obj; + + if (!getDatabase().equals(other.getDatabase())) return false; + if (!getPipelineTypeCase().equals(other.getPipelineTypeCase())) return false; + switch (pipelineTypeCase_) { + case 2: + if (!getStructuredPipeline().equals(other.getStructuredPipeline())) return false; + break; + case 0: + default: + } + if (!getConsistencySelectorCase().equals(other.getConsistencySelectorCase())) return false; + switch (consistencySelectorCase_) { + case 5: + if (!getTransaction().equals(other.getTransaction())) return false; + break; + case 6: + if (!getNewTransaction().equals(other.getNewTransaction())) return false; + break; + case 7: + if (!getReadTime().equals(other.getReadTime())) return false; + break; + case 0: + default: + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + DATABASE_FIELD_NUMBER; + hash = (53 * hash) + getDatabase().hashCode(); + switch (pipelineTypeCase_) { + case 2: + hash = (37 * hash) + STRUCTURED_PIPELINE_FIELD_NUMBER; + hash = (53 * hash) + getStructuredPipeline().hashCode(); + break; + case 0: + default: + } + switch (consistencySelectorCase_) { + case 5: + hash = (37 * hash) + TRANSACTION_FIELD_NUMBER; + hash = (53 * hash) + getTransaction().hashCode(); + break; + case 6: + hash = (37 * hash) + NEW_TRANSACTION_FIELD_NUMBER; + hash = (53 * hash) + getNewTransaction().hashCode(); + break; + case 7: + hash = (37 * hash) + READ_TIME_FIELD_NUMBER; + hash = (53 * hash) + getReadTime().hashCode(); + break; + case 0: + default: + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.ExecutePipelineRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * The request for [Firestore.ExecutePipeline][].
+   * 
+ * + * Protobuf type {@code google.firestore.v1.ExecutePipelineRequest} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.ExecutePipelineRequest) + com.google.firestore.v1.ExecutePipelineRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.ExecutePipelineRequest.class, + com.google.firestore.v1.ExecutePipelineRequest.Builder.class); + } + + // Construct using com.google.firestore.v1.ExecutePipelineRequest.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + database_ = ""; + if (structuredPipelineBuilder_ != null) { + structuredPipelineBuilder_.clear(); + } + if (newTransactionBuilder_ != null) { + newTransactionBuilder_.clear(); + } + if (readTimeBuilder_ != null) { + readTimeBuilder_.clear(); + } + pipelineTypeCase_ = 0; + pipelineType_ = null; + consistencySelectorCase_ = 0; + consistencySelector_ = null; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineRequest_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineRequest getDefaultInstanceForType() { + return com.google.firestore.v1.ExecutePipelineRequest.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineRequest build() { + com.google.firestore.v1.ExecutePipelineRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineRequest buildPartial() { + com.google.firestore.v1.ExecutePipelineRequest result = + new com.google.firestore.v1.ExecutePipelineRequest(this); + if (bitField0_ != 0) { + buildPartial0(result); + } + buildPartialOneofs(result); + onBuilt(); + return result; + } + + private void buildPartial0(com.google.firestore.v1.ExecutePipelineRequest result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.database_ = database_; + } + } + + private void buildPartialOneofs(com.google.firestore.v1.ExecutePipelineRequest result) { + result.pipelineTypeCase_ = pipelineTypeCase_; + result.pipelineType_ = this.pipelineType_; + if (pipelineTypeCase_ == 2 && structuredPipelineBuilder_ != null) { + result.pipelineType_ = structuredPipelineBuilder_.build(); + } + result.consistencySelectorCase_ = consistencySelectorCase_; + result.consistencySelector_ = this.consistencySelector_; + if (consistencySelectorCase_ == 6 && newTransactionBuilder_ != null) { + result.consistencySelector_ = newTransactionBuilder_.build(); + } + if (consistencySelectorCase_ == 7 && readTimeBuilder_ != null) { + result.consistencySelector_ = readTimeBuilder_.build(); + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.ExecutePipelineRequest) { + return mergeFrom((com.google.firestore.v1.ExecutePipelineRequest) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.ExecutePipelineRequest other) { + if (other == com.google.firestore.v1.ExecutePipelineRequest.getDefaultInstance()) return this; + if (!other.getDatabase().isEmpty()) { + database_ = other.database_; + bitField0_ |= 0x00000001; + onChanged(); + } + switch (other.getPipelineTypeCase()) { + case STRUCTURED_PIPELINE: + { + mergeStructuredPipeline(other.getStructuredPipeline()); + break; + } + case PIPELINETYPE_NOT_SET: + { + break; + } + } + switch (other.getConsistencySelectorCase()) { + case TRANSACTION: + { + setTransaction(other.getTransaction()); + break; + } + case NEW_TRANSACTION: + { + mergeNewTransaction(other.getNewTransaction()); + break; + } + case READ_TIME: + { + mergeReadTime(other.getReadTime()); + break; + } + case CONSISTENCYSELECTOR_NOT_SET: + { + break; + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + database_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: + { + input.readMessage( + getStructuredPipelineFieldBuilder().getBuilder(), extensionRegistry); + pipelineTypeCase_ = 2; + break; + } // case 18 + case 42: + { + consistencySelector_ = input.readBytes(); + consistencySelectorCase_ = 5; + break; + } // case 42 + case 50: + { + input.readMessage(getNewTransactionFieldBuilder().getBuilder(), extensionRegistry); + consistencySelectorCase_ = 6; + break; + } // case 50 + case 58: + { + input.readMessage(getReadTimeFieldBuilder().getBuilder(), extensionRegistry); + consistencySelectorCase_ = 7; + break; + } // case 58 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int pipelineTypeCase_ = 0; + private java.lang.Object pipelineType_; + + public PipelineTypeCase getPipelineTypeCase() { + return PipelineTypeCase.forNumber(pipelineTypeCase_); + } + + public Builder clearPipelineType() { + pipelineTypeCase_ = 0; + pipelineType_ = null; + onChanged(); + return this; + } + + private int consistencySelectorCase_ = 0; + private java.lang.Object consistencySelector_; + + public ConsistencySelectorCase getConsistencySelectorCase() { + return ConsistencySelectorCase.forNumber(consistencySelectorCase_); + } + + public Builder clearConsistencySelector() { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + onChanged(); + return this; + } + + private int bitField0_; + + private java.lang.Object database_ = ""; + /** + * + * + *
+     * Database identifier, in the form `projects/{project}/databases/{database}`.
+     * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The database. + */ + public java.lang.String getDatabase() { + java.lang.Object ref = database_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + database_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * Database identifier, in the form `projects/{project}/databases/{database}`.
+     * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The bytes for database. + */ + public com.google.protobuf.ByteString getDatabaseBytes() { + java.lang.Object ref = database_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + database_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * Database identifier, in the form `projects/{project}/databases/{database}`.
+     * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @param value The database to set. + * @return This builder for chaining. + */ + public Builder setDatabase(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + database_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * Database identifier, in the form `projects/{project}/databases/{database}`.
+     * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return This builder for chaining. + */ + public Builder clearDatabase() { + database_ = getDefaultInstance().getDatabase(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * + * + *
+     * Database identifier, in the form `projects/{project}/databases/{database}`.
+     * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @param value The bytes for database to set. + * @return This builder for chaining. + */ + public Builder setDatabaseBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + database_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.StructuredPipeline, + com.google.firestore.v1.StructuredPipeline.Builder, + com.google.firestore.v1.StructuredPipelineOrBuilder> + structuredPipelineBuilder_; + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return Whether the structuredPipeline field is set. + */ + @java.lang.Override + public boolean hasStructuredPipeline() { + return pipelineTypeCase_ == 2; + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return The structuredPipeline. + */ + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline getStructuredPipeline() { + if (structuredPipelineBuilder_ == null) { + if (pipelineTypeCase_ == 2) { + return (com.google.firestore.v1.StructuredPipeline) pipelineType_; + } + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } else { + if (pipelineTypeCase_ == 2) { + return structuredPipelineBuilder_.getMessage(); + } + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + public Builder setStructuredPipeline(com.google.firestore.v1.StructuredPipeline value) { + if (structuredPipelineBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + pipelineType_ = value; + onChanged(); + } else { + structuredPipelineBuilder_.setMessage(value); + } + pipelineTypeCase_ = 2; + return this; + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + public Builder setStructuredPipeline( + com.google.firestore.v1.StructuredPipeline.Builder builderForValue) { + if (structuredPipelineBuilder_ == null) { + pipelineType_ = builderForValue.build(); + onChanged(); + } else { + structuredPipelineBuilder_.setMessage(builderForValue.build()); + } + pipelineTypeCase_ = 2; + return this; + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + public Builder mergeStructuredPipeline(com.google.firestore.v1.StructuredPipeline value) { + if (structuredPipelineBuilder_ == null) { + if (pipelineTypeCase_ == 2 + && pipelineType_ != com.google.firestore.v1.StructuredPipeline.getDefaultInstance()) { + pipelineType_ = + com.google.firestore.v1.StructuredPipeline.newBuilder( + (com.google.firestore.v1.StructuredPipeline) pipelineType_) + .mergeFrom(value) + .buildPartial(); + } else { + pipelineType_ = value; + } + onChanged(); + } else { + if (pipelineTypeCase_ == 2) { + structuredPipelineBuilder_.mergeFrom(value); + } else { + structuredPipelineBuilder_.setMessage(value); + } + } + pipelineTypeCase_ = 2; + return this; + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + public Builder clearStructuredPipeline() { + if (structuredPipelineBuilder_ == null) { + if (pipelineTypeCase_ == 2) { + pipelineTypeCase_ = 0; + pipelineType_ = null; + onChanged(); + } + } else { + if (pipelineTypeCase_ == 2) { + pipelineTypeCase_ = 0; + pipelineType_ = null; + } + structuredPipelineBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + public com.google.firestore.v1.StructuredPipeline.Builder getStructuredPipelineBuilder() { + return getStructuredPipelineFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + @java.lang.Override + public com.google.firestore.v1.StructuredPipelineOrBuilder getStructuredPipelineOrBuilder() { + if ((pipelineTypeCase_ == 2) && (structuredPipelineBuilder_ != null)) { + return structuredPipelineBuilder_.getMessageOrBuilder(); + } else { + if (pipelineTypeCase_ == 2) { + return (com.google.firestore.v1.StructuredPipeline) pipelineType_; + } + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + } + /** + * + * + *
+     * A pipelined operation.
+     * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.StructuredPipeline, + com.google.firestore.v1.StructuredPipeline.Builder, + com.google.firestore.v1.StructuredPipelineOrBuilder> + getStructuredPipelineFieldBuilder() { + if (structuredPipelineBuilder_ == null) { + if (!(pipelineTypeCase_ == 2)) { + pipelineType_ = com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + structuredPipelineBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.StructuredPipeline, + com.google.firestore.v1.StructuredPipeline.Builder, + com.google.firestore.v1.StructuredPipelineOrBuilder>( + (com.google.firestore.v1.StructuredPipeline) pipelineType_, + getParentForChildren(), + isClean()); + pipelineType_ = null; + } + pipelineTypeCase_ = 2; + onChanged(); + return structuredPipelineBuilder_; + } + + /** + * + * + *
+     * Run the query within an already active transaction.
+     *
+     * The value here is the opaque transaction ID to execute the query in.
+     * 
+ * + * bytes transaction = 5; + * + * @return Whether the transaction field is set. + */ + public boolean hasTransaction() { + return consistencySelectorCase_ == 5; + } + /** + * + * + *
+     * Run the query within an already active transaction.
+     *
+     * The value here is the opaque transaction ID to execute the query in.
+     * 
+ * + * bytes transaction = 5; + * + * @return The transaction. + */ + public com.google.protobuf.ByteString getTransaction() { + if (consistencySelectorCase_ == 5) { + return (com.google.protobuf.ByteString) consistencySelector_; + } + return com.google.protobuf.ByteString.EMPTY; + } + /** + * + * + *
+     * Run the query within an already active transaction.
+     *
+     * The value here is the opaque transaction ID to execute the query in.
+     * 
+ * + * bytes transaction = 5; + * + * @param value The transaction to set. + * @return This builder for chaining. + */ + public Builder setTransaction(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + consistencySelectorCase_ = 5; + consistencySelector_ = value; + onChanged(); + return this; + } + /** + * + * + *
+     * Run the query within an already active transaction.
+     *
+     * The value here is the opaque transaction ID to execute the query in.
+     * 
+ * + * bytes transaction = 5; + * + * @return This builder for chaining. + */ + public Builder clearTransaction() { + if (consistencySelectorCase_ == 5) { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + onChanged(); + } + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.TransactionOptions, + com.google.firestore.v1.TransactionOptions.Builder, + com.google.firestore.v1.TransactionOptionsOrBuilder> + newTransactionBuilder_; + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return Whether the newTransaction field is set. + */ + @java.lang.Override + public boolean hasNewTransaction() { + return consistencySelectorCase_ == 6; + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return The newTransaction. + */ + @java.lang.Override + public com.google.firestore.v1.TransactionOptions getNewTransaction() { + if (newTransactionBuilder_ == null) { + if (consistencySelectorCase_ == 6) { + return (com.google.firestore.v1.TransactionOptions) consistencySelector_; + } + return com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } else { + if (consistencySelectorCase_ == 6) { + return newTransactionBuilder_.getMessage(); + } + return com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + public Builder setNewTransaction(com.google.firestore.v1.TransactionOptions value) { + if (newTransactionBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + consistencySelector_ = value; + onChanged(); + } else { + newTransactionBuilder_.setMessage(value); + } + consistencySelectorCase_ = 6; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + public Builder setNewTransaction( + com.google.firestore.v1.TransactionOptions.Builder builderForValue) { + if (newTransactionBuilder_ == null) { + consistencySelector_ = builderForValue.build(); + onChanged(); + } else { + newTransactionBuilder_.setMessage(builderForValue.build()); + } + consistencySelectorCase_ = 6; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + public Builder mergeNewTransaction(com.google.firestore.v1.TransactionOptions value) { + if (newTransactionBuilder_ == null) { + if (consistencySelectorCase_ == 6 + && consistencySelector_ + != com.google.firestore.v1.TransactionOptions.getDefaultInstance()) { + consistencySelector_ = + com.google.firestore.v1.TransactionOptions.newBuilder( + (com.google.firestore.v1.TransactionOptions) consistencySelector_) + .mergeFrom(value) + .buildPartial(); + } else { + consistencySelector_ = value; + } + onChanged(); + } else { + if (consistencySelectorCase_ == 6) { + newTransactionBuilder_.mergeFrom(value); + } else { + newTransactionBuilder_.setMessage(value); + } + } + consistencySelectorCase_ = 6; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + public Builder clearNewTransaction() { + if (newTransactionBuilder_ == null) { + if (consistencySelectorCase_ == 6) { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + onChanged(); + } + } else { + if (consistencySelectorCase_ == 6) { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + } + newTransactionBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + public com.google.firestore.v1.TransactionOptions.Builder getNewTransactionBuilder() { + return getNewTransactionFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + @java.lang.Override + public com.google.firestore.v1.TransactionOptionsOrBuilder getNewTransactionOrBuilder() { + if ((consistencySelectorCase_ == 6) && (newTransactionBuilder_ != null)) { + return newTransactionBuilder_.getMessageOrBuilder(); + } else { + if (consistencySelectorCase_ == 6) { + return (com.google.firestore.v1.TransactionOptions) consistencySelector_; + } + return com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } + } + /** + * + * + *
+     * Execute the pipeline in a new transaction.
+     *
+     * The identifier of the newly created transaction will be returned in the
+     * first response on the stream. This defaults to a read-only transaction.
+     * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.TransactionOptions, + com.google.firestore.v1.TransactionOptions.Builder, + com.google.firestore.v1.TransactionOptionsOrBuilder> + getNewTransactionFieldBuilder() { + if (newTransactionBuilder_ == null) { + if (!(consistencySelectorCase_ == 6)) { + consistencySelector_ = com.google.firestore.v1.TransactionOptions.getDefaultInstance(); + } + newTransactionBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.TransactionOptions, + com.google.firestore.v1.TransactionOptions.Builder, + com.google.firestore.v1.TransactionOptionsOrBuilder>( + (com.google.firestore.v1.TransactionOptions) consistencySelector_, + getParentForChildren(), + isClean()); + consistencySelector_ = null; + } + consistencySelectorCase_ = 6; + onChanged(); + return newTransactionBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + readTimeBuilder_; + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return Whether the readTime field is set. + */ + @java.lang.Override + public boolean hasReadTime() { + return consistencySelectorCase_ == 7; + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return The readTime. + */ + @java.lang.Override + public com.google.protobuf.Timestamp getReadTime() { + if (readTimeBuilder_ == null) { + if (consistencySelectorCase_ == 7) { + return (com.google.protobuf.Timestamp) consistencySelector_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } else { + if (consistencySelectorCase_ == 7) { + return readTimeBuilder_.getMessage(); + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + public Builder setReadTime(com.google.protobuf.Timestamp value) { + if (readTimeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + consistencySelector_ = value; + onChanged(); + } else { + readTimeBuilder_.setMessage(value); + } + consistencySelectorCase_ = 7; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + public Builder setReadTime(com.google.protobuf.Timestamp.Builder builderForValue) { + if (readTimeBuilder_ == null) { + consistencySelector_ = builderForValue.build(); + onChanged(); + } else { + readTimeBuilder_.setMessage(builderForValue.build()); + } + consistencySelectorCase_ = 7; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + public Builder mergeReadTime(com.google.protobuf.Timestamp value) { + if (readTimeBuilder_ == null) { + if (consistencySelectorCase_ == 7 + && consistencySelector_ != com.google.protobuf.Timestamp.getDefaultInstance()) { + consistencySelector_ = + com.google.protobuf.Timestamp.newBuilder( + (com.google.protobuf.Timestamp) consistencySelector_) + .mergeFrom(value) + .buildPartial(); + } else { + consistencySelector_ = value; + } + onChanged(); + } else { + if (consistencySelectorCase_ == 7) { + readTimeBuilder_.mergeFrom(value); + } else { + readTimeBuilder_.setMessage(value); + } + } + consistencySelectorCase_ = 7; + return this; + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + public Builder clearReadTime() { + if (readTimeBuilder_ == null) { + if (consistencySelectorCase_ == 7) { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + onChanged(); + } + } else { + if (consistencySelectorCase_ == 7) { + consistencySelectorCase_ = 0; + consistencySelector_ = null; + } + readTimeBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + public com.google.protobuf.Timestamp.Builder getReadTimeBuilder() { + return getReadTimeFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + @java.lang.Override + public com.google.protobuf.TimestampOrBuilder getReadTimeOrBuilder() { + if ((consistencySelectorCase_ == 7) && (readTimeBuilder_ != null)) { + return readTimeBuilder_.getMessageOrBuilder(); + } else { + if (consistencySelectorCase_ == 7) { + return (com.google.protobuf.Timestamp) consistencySelector_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + } + /** + * + * + *
+     * Execute the pipeline in a snapshot transaction at the given time.
+     *
+     * This must be a microsecond precision timestamp within the past one hour,
+     * or if Point-in-Time Recovery is enabled, can additionally be a whole
+     * minute timestamp within the past 7 days.
+     * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + getReadTimeFieldBuilder() { + if (readTimeBuilder_ == null) { + if (!(consistencySelectorCase_ == 7)) { + consistencySelector_ = com.google.protobuf.Timestamp.getDefaultInstance(); + } + readTimeBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder>( + (com.google.protobuf.Timestamp) consistencySelector_, + getParentForChildren(), + isClean()); + consistencySelector_ = null; + } + consistencySelectorCase_ = 7; + onChanged(); + return readTimeBuilder_; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.ExecutePipelineRequest) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.ExecutePipelineRequest) + private static final com.google.firestore.v1.ExecutePipelineRequest DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.ExecutePipelineRequest(); + } + + public static com.google.firestore.v1.ExecutePipelineRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ExecutePipelineRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequestOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequestOrBuilder.java new file mode 100644 index 000000000..95a65826b --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineRequestOrBuilder.java @@ -0,0 +1,211 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public interface ExecutePipelineRequestOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.ExecutePipelineRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * Database identifier, in the form `projects/{project}/databases/{database}`.
+   * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The database. + */ + java.lang.String getDatabase(); + /** + * + * + *
+   * Database identifier, in the form `projects/{project}/databases/{database}`.
+   * 
+ * + * string database = 1 [(.google.api.field_behavior) = REQUIRED]; + * + * @return The bytes for database. + */ + com.google.protobuf.ByteString getDatabaseBytes(); + + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return Whether the structuredPipeline field is set. + */ + boolean hasStructuredPipeline(); + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + * + * @return The structuredPipeline. + */ + com.google.firestore.v1.StructuredPipeline getStructuredPipeline(); + /** + * + * + *
+   * A pipelined operation.
+   * 
+ * + * .google.firestore.v1.StructuredPipeline structured_pipeline = 2; + */ + com.google.firestore.v1.StructuredPipelineOrBuilder getStructuredPipelineOrBuilder(); + + /** + * + * + *
+   * Run the query within an already active transaction.
+   *
+   * The value here is the opaque transaction ID to execute the query in.
+   * 
+ * + * bytes transaction = 5; + * + * @return Whether the transaction field is set. + */ + boolean hasTransaction(); + /** + * + * + *
+   * Run the query within an already active transaction.
+   *
+   * The value here is the opaque transaction ID to execute the query in.
+   * 
+ * + * bytes transaction = 5; + * + * @return The transaction. + */ + com.google.protobuf.ByteString getTransaction(); + + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return Whether the newTransaction field is set. + */ + boolean hasNewTransaction(); + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + * + * @return The newTransaction. + */ + com.google.firestore.v1.TransactionOptions getNewTransaction(); + /** + * + * + *
+   * Execute the pipeline in a new transaction.
+   *
+   * The identifier of the newly created transaction will be returned in the
+   * first response on the stream. This defaults to a read-only transaction.
+   * 
+ * + * .google.firestore.v1.TransactionOptions new_transaction = 6; + */ + com.google.firestore.v1.TransactionOptionsOrBuilder getNewTransactionOrBuilder(); + + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return Whether the readTime field is set. + */ + boolean hasReadTime(); + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + * + * @return The readTime. + */ + com.google.protobuf.Timestamp getReadTime(); + /** + * + * + *
+   * Execute the pipeline in a snapshot transaction at the given time.
+   *
+   * This must be a microsecond precision timestamp within the past one hour,
+   * or if Point-in-Time Recovery is enabled, can additionally be a whole
+   * minute timestamp within the past 7 days.
+   * 
+ * + * .google.protobuf.Timestamp read_time = 7; + */ + com.google.protobuf.TimestampOrBuilder getReadTimeOrBuilder(); + + com.google.firestore.v1.ExecutePipelineRequest.PipelineTypeCase getPipelineTypeCase(); + + com.google.firestore.v1.ExecutePipelineRequest.ConsistencySelectorCase + getConsistencySelectorCase(); +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponse.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponse.java new file mode 100644 index 000000000..a8408e14e --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponse.java @@ -0,0 +1,1647 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +/** + * + * + *
+ * The response for [Firestore.Execute][].
+ * 
+ * + * Protobuf type {@code google.firestore.v1.ExecutePipelineResponse} + */ +public final class ExecutePipelineResponse extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.ExecutePipelineResponse) + ExecutePipelineResponseOrBuilder { + private static final long serialVersionUID = 0L; + // Use ExecutePipelineResponse.newBuilder() to construct. + private ExecutePipelineResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private ExecutePipelineResponse() { + transaction_ = com.google.protobuf.ByteString.EMPTY; + results_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new ExecutePipelineResponse(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.ExecutePipelineResponse.class, + com.google.firestore.v1.ExecutePipelineResponse.Builder.class); + } + + private int bitField0_; + public static final int TRANSACTION_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString transaction_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+   * Newly created transaction identifier.
+   *
+   * This field is only specified on the first response from the server when
+   * the request specified [ExecuteRequest.new_transaction][].
+   * 
+ * + * bytes transaction = 1; + * + * @return The transaction. + */ + @java.lang.Override + public com.google.protobuf.ByteString getTransaction() { + return transaction_; + } + + public static final int RESULTS_FIELD_NUMBER = 2; + + @SuppressWarnings("serial") + private java.util.List results_; + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + @java.lang.Override + public java.util.List getResultsList() { + return results_; + } + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + @java.lang.Override + public java.util.List + getResultsOrBuilderList() { + return results_; + } + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + @java.lang.Override + public int getResultsCount() { + return results_.size(); + } + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + @java.lang.Override + public com.google.firestore.v1.Document getResults(int index) { + return results_.get(index); + } + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + @java.lang.Override + public com.google.firestore.v1.DocumentOrBuilder getResultsOrBuilder(int index) { + return results_.get(index); + } + + public static final int EXECUTION_TIME_FIELD_NUMBER = 3; + private com.google.protobuf.Timestamp executionTime_; + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return Whether the executionTime field is set. + */ + @java.lang.Override + public boolean hasExecutionTime() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return The executionTime. + */ + @java.lang.Override + public com.google.protobuf.Timestamp getExecutionTime() { + return executionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : executionTime_; + } + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + @java.lang.Override + public com.google.protobuf.TimestampOrBuilder getExecutionTimeOrBuilder() { + return executionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : executionTime_; + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (!transaction_.isEmpty()) { + output.writeBytes(1, transaction_); + } + for (int i = 0; i < results_.size(); i++) { + output.writeMessage(2, results_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(3, getExecutionTime()); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!transaction_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream.computeBytesSize(1, transaction_); + } + for (int i = 0; i < results_.size(); i++) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, results_.get(i)); + } + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(3, getExecutionTime()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.ExecutePipelineResponse)) { + return super.equals(obj); + } + com.google.firestore.v1.ExecutePipelineResponse other = + (com.google.firestore.v1.ExecutePipelineResponse) obj; + + if (!getTransaction().equals(other.getTransaction())) return false; + if (!getResultsList().equals(other.getResultsList())) return false; + if (hasExecutionTime() != other.hasExecutionTime()) return false; + if (hasExecutionTime()) { + if (!getExecutionTime().equals(other.getExecutionTime())) return false; + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + TRANSACTION_FIELD_NUMBER; + hash = (53 * hash) + getTransaction().hashCode(); + if (getResultsCount() > 0) { + hash = (37 * hash) + RESULTS_FIELD_NUMBER; + hash = (53 * hash) + getResultsList().hashCode(); + } + if (hasExecutionTime()) { + hash = (37 * hash) + EXECUTION_TIME_FIELD_NUMBER; + hash = (53 * hash) + getExecutionTime().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.ExecutePipelineResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.ExecutePipelineResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * The response for [Firestore.Execute][].
+   * 
+ * + * Protobuf type {@code google.firestore.v1.ExecutePipelineResponse} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.ExecutePipelineResponse) + com.google.firestore.v1.ExecutePipelineResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.ExecutePipelineResponse.class, + com.google.firestore.v1.ExecutePipelineResponse.Builder.class); + } + + // Construct using com.google.firestore.v1.ExecutePipelineResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) { + getResultsFieldBuilder(); + getExecutionTimeFieldBuilder(); + } + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + transaction_ = com.google.protobuf.ByteString.EMPTY; + if (resultsBuilder_ == null) { + results_ = java.util.Collections.emptyList(); + } else { + results_ = null; + resultsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + executionTime_ = null; + if (executionTimeBuilder_ != null) { + executionTimeBuilder_.dispose(); + executionTimeBuilder_ = null; + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.FirestoreProto + .internal_static_google_firestore_v1_ExecutePipelineResponse_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineResponse getDefaultInstanceForType() { + return com.google.firestore.v1.ExecutePipelineResponse.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineResponse build() { + com.google.firestore.v1.ExecutePipelineResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineResponse buildPartial() { + com.google.firestore.v1.ExecutePipelineResponse result = + new com.google.firestore.v1.ExecutePipelineResponse(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields( + com.google.firestore.v1.ExecutePipelineResponse result) { + if (resultsBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + results_ = java.util.Collections.unmodifiableList(results_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.results_ = results_; + } else { + result.results_ = resultsBuilder_.build(); + } + } + + private void buildPartial0(com.google.firestore.v1.ExecutePipelineResponse result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.transaction_ = transaction_; + } + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000004) != 0)) { + result.executionTime_ = + executionTimeBuilder_ == null ? executionTime_ : executionTimeBuilder_.build(); + to_bitField0_ |= 0x00000001; + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.ExecutePipelineResponse) { + return mergeFrom((com.google.firestore.v1.ExecutePipelineResponse) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.ExecutePipelineResponse other) { + if (other == com.google.firestore.v1.ExecutePipelineResponse.getDefaultInstance()) + return this; + if (other.getTransaction() != com.google.protobuf.ByteString.EMPTY) { + setTransaction(other.getTransaction()); + } + if (resultsBuilder_ == null) { + if (!other.results_.isEmpty()) { + if (results_.isEmpty()) { + results_ = other.results_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureResultsIsMutable(); + results_.addAll(other.results_); + } + onChanged(); + } + } else { + if (!other.results_.isEmpty()) { + if (resultsBuilder_.isEmpty()) { + resultsBuilder_.dispose(); + resultsBuilder_ = null; + results_ = other.results_; + bitField0_ = (bitField0_ & ~0x00000002); + resultsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders + ? getResultsFieldBuilder() + : null; + } else { + resultsBuilder_.addAllMessages(other.results_); + } + } + } + if (other.hasExecutionTime()) { + mergeExecutionTime(other.getExecutionTime()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + transaction_ = input.readBytes(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: + { + com.google.firestore.v1.Document m = + input.readMessage(com.google.firestore.v1.Document.parser(), extensionRegistry); + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + results_.add(m); + } else { + resultsBuilder_.addMessage(m); + } + break; + } // case 18 + case 26: + { + input.readMessage(getExecutionTimeFieldBuilder().getBuilder(), extensionRegistry); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private com.google.protobuf.ByteString transaction_ = com.google.protobuf.ByteString.EMPTY; + /** + * + * + *
+     * Newly created transaction identifier.
+     *
+     * This field is only specified on the first response from the server when
+     * the request specified [ExecuteRequest.new_transaction][].
+     * 
+ * + * bytes transaction = 1; + * + * @return The transaction. + */ + @java.lang.Override + public com.google.protobuf.ByteString getTransaction() { + return transaction_; + } + /** + * + * + *
+     * Newly created transaction identifier.
+     *
+     * This field is only specified on the first response from the server when
+     * the request specified [ExecuteRequest.new_transaction][].
+     * 
+ * + * bytes transaction = 1; + * + * @param value The transaction to set. + * @return This builder for chaining. + */ + public Builder setTransaction(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + transaction_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * Newly created transaction identifier.
+     *
+     * This field is only specified on the first response from the server when
+     * the request specified [ExecuteRequest.new_transaction][].
+     * 
+ * + * bytes transaction = 1; + * + * @return This builder for chaining. + */ + public Builder clearTransaction() { + bitField0_ = (bitField0_ & ~0x00000001); + transaction_ = getDefaultInstance().getTransaction(); + onChanged(); + return this; + } + + private java.util.List results_ = + java.util.Collections.emptyList(); + + private void ensureResultsIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + results_ = new java.util.ArrayList(results_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Document, + com.google.firestore.v1.Document.Builder, + com.google.firestore.v1.DocumentOrBuilder> + resultsBuilder_; + + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public java.util.List getResultsList() { + if (resultsBuilder_ == null) { + return java.util.Collections.unmodifiableList(results_); + } else { + return resultsBuilder_.getMessageList(); + } + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public int getResultsCount() { + if (resultsBuilder_ == null) { + return results_.size(); + } else { + return resultsBuilder_.getCount(); + } + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public com.google.firestore.v1.Document getResults(int index) { + if (resultsBuilder_ == null) { + return results_.get(index); + } else { + return resultsBuilder_.getMessage(index); + } + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder setResults(int index, com.google.firestore.v1.Document value) { + if (resultsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.set(index, value); + onChanged(); + } else { + resultsBuilder_.setMessage(index, value); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder setResults(int index, com.google.firestore.v1.Document.Builder builderForValue) { + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + results_.set(index, builderForValue.build()); + onChanged(); + } else { + resultsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder addResults(com.google.firestore.v1.Document value) { + if (resultsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.add(value); + onChanged(); + } else { + resultsBuilder_.addMessage(value); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder addResults(int index, com.google.firestore.v1.Document value) { + if (resultsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureResultsIsMutable(); + results_.add(index, value); + onChanged(); + } else { + resultsBuilder_.addMessage(index, value); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder addResults(com.google.firestore.v1.Document.Builder builderForValue) { + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + results_.add(builderForValue.build()); + onChanged(); + } else { + resultsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder addResults(int index, com.google.firestore.v1.Document.Builder builderForValue) { + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + results_.add(index, builderForValue.build()); + onChanged(); + } else { + resultsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder addAllResults( + java.lang.Iterable values) { + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll(values, results_); + onChanged(); + } else { + resultsBuilder_.addAllMessages(values); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder clearResults() { + if (resultsBuilder_ == null) { + results_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + resultsBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public Builder removeResults(int index) { + if (resultsBuilder_ == null) { + ensureResultsIsMutable(); + results_.remove(index); + onChanged(); + } else { + resultsBuilder_.remove(index); + } + return this; + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public com.google.firestore.v1.Document.Builder getResultsBuilder(int index) { + return getResultsFieldBuilder().getBuilder(index); + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public com.google.firestore.v1.DocumentOrBuilder getResultsOrBuilder(int index) { + if (resultsBuilder_ == null) { + return results_.get(index); + } else { + return resultsBuilder_.getMessageOrBuilder(index); + } + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public java.util.List + getResultsOrBuilderList() { + if (resultsBuilder_ != null) { + return resultsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(results_); + } + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public com.google.firestore.v1.Document.Builder addResultsBuilder() { + return getResultsFieldBuilder() + .addBuilder(com.google.firestore.v1.Document.getDefaultInstance()); + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public com.google.firestore.v1.Document.Builder addResultsBuilder(int index) { + return getResultsFieldBuilder() + .addBuilder(index, com.google.firestore.v1.Document.getDefaultInstance()); + } + /** + * + * + *
+     * An ordered batch of results returned executing a pipeline.
+     *
+     * The batch size is variable, and can even be zero for when only a partial
+     * progress message is returned.
+     *
+     * The fields present in the returned documents are only those that were
+     * explicitly requested in the pipeline, this include those like
+     * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+     * This is explicitly a divergence from `Firestore.RunQuery` /
+     * `Firestore.GetDocument` RPCs which always return such fields even when they
+     * are not specified in the [`mask`][DocumentMask].
+     * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + public java.util.List getResultsBuilderList() { + return getResultsFieldBuilder().getBuilderList(); + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Document, + com.google.firestore.v1.Document.Builder, + com.google.firestore.v1.DocumentOrBuilder> + getResultsFieldBuilder() { + if (resultsBuilder_ == null) { + resultsBuilder_ = + new com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Document, + com.google.firestore.v1.Document.Builder, + com.google.firestore.v1.DocumentOrBuilder>( + results_, ((bitField0_ & 0x00000002) != 0), getParentForChildren(), isClean()); + results_ = null; + } + return resultsBuilder_; + } + + private com.google.protobuf.Timestamp executionTime_; + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + executionTimeBuilder_; + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return Whether the executionTime field is set. + */ + public boolean hasExecutionTime() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return The executionTime. + */ + public com.google.protobuf.Timestamp getExecutionTime() { + if (executionTimeBuilder_ == null) { + return executionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : executionTime_; + } else { + return executionTimeBuilder_.getMessage(); + } + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public Builder setExecutionTime(com.google.protobuf.Timestamp value) { + if (executionTimeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + executionTime_ = value; + } else { + executionTimeBuilder_.setMessage(value); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public Builder setExecutionTime(com.google.protobuf.Timestamp.Builder builderForValue) { + if (executionTimeBuilder_ == null) { + executionTime_ = builderForValue.build(); + } else { + executionTimeBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000004; + onChanged(); + return this; + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public Builder mergeExecutionTime(com.google.protobuf.Timestamp value) { + if (executionTimeBuilder_ == null) { + if (((bitField0_ & 0x00000004) != 0) + && executionTime_ != null + && executionTime_ != com.google.protobuf.Timestamp.getDefaultInstance()) { + getExecutionTimeBuilder().mergeFrom(value); + } else { + executionTime_ = value; + } + } else { + executionTimeBuilder_.mergeFrom(value); + } + if (executionTime_ != null) { + bitField0_ |= 0x00000004; + onChanged(); + } + return this; + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public Builder clearExecutionTime() { + bitField0_ = (bitField0_ & ~0x00000004); + executionTime_ = null; + if (executionTimeBuilder_ != null) { + executionTimeBuilder_.dispose(); + executionTimeBuilder_ = null; + } + onChanged(); + return this; + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public com.google.protobuf.Timestamp.Builder getExecutionTimeBuilder() { + bitField0_ |= 0x00000004; + onChanged(); + return getExecutionTimeFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + public com.google.protobuf.TimestampOrBuilder getExecutionTimeOrBuilder() { + if (executionTimeBuilder_ != null) { + return executionTimeBuilder_.getMessageOrBuilder(); + } else { + return executionTime_ == null + ? com.google.protobuf.Timestamp.getDefaultInstance() + : executionTime_; + } + } + /** + * + * + *
+     * The time at which the document(s) were read.
+     *
+     * This may be monotonically increasing; in this case, the previous documents
+     * in the result stream are guaranteed not to have changed between their
+     * `execution_time` and this one.
+     *
+     * If the query returns no results, a response with `execution_time` and no
+     * `results` will be sent, and this represents the time at which the operation
+     * was run.
+     * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder> + getExecutionTimeFieldBuilder() { + if (executionTimeBuilder_ == null) { + executionTimeBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, + com.google.protobuf.Timestamp.Builder, + com.google.protobuf.TimestampOrBuilder>( + getExecutionTime(), getParentForChildren(), isClean()); + executionTime_ = null; + } + return executionTimeBuilder_; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.ExecutePipelineResponse) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.ExecutePipelineResponse) + private static final com.google.firestore.v1.ExecutePipelineResponse DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.ExecutePipelineResponse(); + } + + public static com.google.firestore.v1.ExecutePipelineResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ExecutePipelineResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.ExecutePipelineResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponseOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponseOrBuilder.java new file mode 100644 index 000000000..9aec28083 --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutePipelineResponseOrBuilder.java @@ -0,0 +1,202 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public interface ExecutePipelineResponseOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.ExecutePipelineResponse) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * Newly created transaction identifier.
+   *
+   * This field is only specified on the first response from the server when
+   * the request specified [ExecuteRequest.new_transaction][].
+   * 
+ * + * bytes transaction = 1; + * + * @return The transaction. + */ + com.google.protobuf.ByteString getTransaction(); + + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + java.util.List getResultsList(); + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + com.google.firestore.v1.Document getResults(int index); + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + int getResultsCount(); + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + java.util.List getResultsOrBuilderList(); + /** + * + * + *
+   * An ordered batch of results returned executing a pipeline.
+   *
+   * The batch size is variable, and can even be zero for when only a partial
+   * progress message is returned.
+   *
+   * The fields present in the returned documents are only those that were
+   * explicitly requested in the pipeline, this include those like
+   * [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
+   * This is explicitly a divergence from `Firestore.RunQuery` /
+   * `Firestore.GetDocument` RPCs which always return such fields even when they
+   * are not specified in the [`mask`][DocumentMask].
+   * 
+ * + * repeated .google.firestore.v1.Document results = 2; + */ + com.google.firestore.v1.DocumentOrBuilder getResultsOrBuilder(int index); + + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return Whether the executionTime field is set. + */ + boolean hasExecutionTime(); + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + * + * @return The executionTime. + */ + com.google.protobuf.Timestamp getExecutionTime(); + /** + * + * + *
+   * The time at which the document(s) were read.
+   *
+   * This may be monotonically increasing; in this case, the previous documents
+   * in the result stream are guaranteed not to have changed between their
+   * `execution_time` and this one.
+   *
+   * If the query returns no results, a response with `execution_time` and no
+   * `results` will be sent, and this represents the time at which the operation
+   * was run.
+   * 
+ * + * .google.protobuf.Timestamp execution_time = 3; + */ + com.google.protobuf.TimestampOrBuilder getExecutionTimeOrBuilder(); +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStats.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStats.java index 0453944ab..3c3fd0a97 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStats.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStats.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; /** diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStatsOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStatsOrBuilder.java index ec86aab5e..1694bea5f 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStatsOrBuilder.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExecutionStatsOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public interface ExecutionStatsOrBuilder diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetrics.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetrics.java index 4507ad57f..9f862e933 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetrics.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetrics.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; /** diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetricsOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetricsOrBuilder.java index b66033555..ba5a87f0f 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetricsOrBuilder.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainMetricsOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public interface ExplainMetricsOrBuilder diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptions.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptions.java index 6e18d6a65..82c242b89 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptions.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptions.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; /** diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptionsOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptionsOrBuilder.java index 80a82dee4..2acb95c56 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptionsOrBuilder.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ExplainOptionsOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public interface ExplainOptionsOrBuilder diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreProto.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreProto.java index dcc7ca8de..cb7375ccc 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreProto.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FirestoreProto.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/firestore.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public final class FirestoreProto { @@ -88,6 +88,14 @@ public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry r internal_static_google_firestore_v1_RunQueryResponse_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable internal_static_google_firestore_v1_RunQueryResponse_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_ExecutePipelineRequest_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_ExecutePipelineRequest_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_ExecutePipelineResponse_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_ExecutePipelineResponse_fieldAccessorTable; static final com.google.protobuf.Descriptors.Descriptor internal_static_google_firestore_v1_RunAggregationQueryRequest_descriptor; static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable @@ -179,249 +187,259 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "e/api/field_behavior.proto\032,google/fires" + "tore/v1/aggregation_result.proto\032 google" + "/firestore/v1/common.proto\032\"google/fires" - + "tore/v1/document.proto\032\037google/firestore" - + "/v1/query.proto\032\'google/firestore/v1/que" - + "ry_profile.proto\032\037google/firestore/v1/wr" - + "ite.proto\032\033google/protobuf/empty.proto\032\037" - + "google/protobuf/timestamp.proto\032\036google/" - + "protobuf/wrappers.proto\032\027google/rpc/stat" - + "us.proto\"\270\001\n\022GetDocumentRequest\022\021\n\004name\030" - + "\001 \001(\tB\003\340A\002\022/\n\004mask\030\002 \001(\0132!.google.firest" - + "ore.v1.DocumentMask\022\025\n\013transaction\030\003 \001(\014" - + "H\000\022/\n\tread_time\030\005 \001(\0132\032.google.protobuf." - + "TimestampH\000B\026\n\024consistency_selector\"\273\002\n\024" - + "ListDocumentsRequest\022\023\n\006parent\030\001 \001(\tB\003\340A" - + "\002\022\032\n\rcollection_id\030\002 \001(\tB\003\340A\001\022\026\n\tpage_si" - + "ze\030\003 \001(\005B\003\340A\001\022\027\n\npage_token\030\004 \001(\tB\003\340A\001\022\025" - + "\n\010order_by\030\006 \001(\tB\003\340A\001\0224\n\004mask\030\007 \001(\0132!.go" - + "ogle.firestore.v1.DocumentMaskB\003\340A\001\022\025\n\013t" - + "ransaction\030\010 \001(\014H\000\022/\n\tread_time\030\n \001(\0132\032." - + "google.protobuf.TimestampH\000\022\024\n\014show_miss" - + "ing\030\014 \001(\010B\026\n\024consistency_selector\"b\n\025Lis" - + "tDocumentsResponse\0220\n\tdocuments\030\001 \003(\0132\035." - + "google.firestore.v1.Document\022\027\n\017next_pag" - + "e_token\030\002 \001(\t\"\304\001\n\025CreateDocumentRequest\022" - + "\023\n\006parent\030\001 \001(\tB\003\340A\002\022\032\n\rcollection_id\030\002 " - + "\001(\tB\003\340A\002\022\023\n\013document_id\030\003 \001(\t\0224\n\010documen" - + "t\030\004 \001(\0132\035.google.firestore.v1.DocumentB\003" - + "\340A\002\022/\n\004mask\030\005 \001(\0132!.google.firestore.v1." - + "DocumentMask\"\363\001\n\025UpdateDocumentRequest\0224" + + "tore/v1/document.proto\032\"google/firestore" + + "/v1/pipeline.proto\032\037google/firestore/v1/" + + "query.proto\032\037google/firestore/v1/write.p" + + "roto\032\033google/protobuf/empty.proto\032\037googl" + + "e/protobuf/timestamp.proto\032\036google/proto" + + "buf/wrappers.proto\032\027google/rpc/status.pr" + + "oto\"\270\001\n\022GetDocumentRequest\022\021\n\004name\030\001 \001(\t" + + "B\003\340A\002\022/\n\004mask\030\002 \001(\0132!.google.firestore.v" + + "1.DocumentMask\022\025\n\013transaction\030\003 \001(\014H\000\022/\n" + + "\tread_time\030\005 \001(\0132\032.google.protobuf.Times" + + "tampH\000B\026\n\024consistency_selector\"\273\002\n\024ListD" + + "ocumentsRequest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022\032\n\r" + + "collection_id\030\002 \001(\tB\003\340A\001\022\026\n\tpage_size\030\003 " + + "\001(\005B\003\340A\001\022\027\n\npage_token\030\004 \001(\tB\003\340A\001\022\025\n\010ord" + + "er_by\030\006 \001(\tB\003\340A\001\0224\n\004mask\030\007 \001(\0132!.google." + + "firestore.v1.DocumentMaskB\003\340A\001\022\025\n\013transa" + + "ction\030\010 \001(\014H\000\022/\n\tread_time\030\n \001(\0132\032.googl" + + "e.protobuf.TimestampH\000\022\024\n\014show_missing\030\014" + + " \001(\010B\026\n\024consistency_selector\"b\n\025ListDocu" + + "mentsResponse\0220\n\tdocuments\030\001 \003(\0132\035.googl" + + "e.firestore.v1.Document\022\027\n\017next_page_tok" + + "en\030\002 \001(\t\"\304\001\n\025CreateDocumentRequest\022\023\n\006pa" + + "rent\030\001 \001(\tB\003\340A\002\022\032\n\rcollection_id\030\002 \001(\tB\003" + + "\340A\002\022\023\n\013document_id\030\003 \001(\t\0224\n\010document\030\004 \001" + + "(\0132\035.google.firestore.v1.DocumentB\003\340A\002\022/" + + "\n\004mask\030\005 \001(\0132!.google.firestore.v1.Docum" + + "entMask\"\363\001\n\025UpdateDocumentRequest\0224\n\010doc" + + "ument\030\001 \001(\0132\035.google.firestore.v1.Docume" + + "ntB\003\340A\002\0226\n\013update_mask\030\002 \001(\0132!.google.fi" + + "restore.v1.DocumentMask\022/\n\004mask\030\003 \001(\0132!." + + "google.firestore.v1.DocumentMask\022;\n\020curr" + + "ent_document\030\004 \001(\0132!.google.firestore.v1" + + ".Precondition\"g\n\025DeleteDocumentRequest\022\021" + + "\n\004name\030\001 \001(\tB\003\340A\002\022;\n\020current_document\030\002 " + + "\001(\0132!.google.firestore.v1.Precondition\"\231" + + "\002\n\030BatchGetDocumentsRequest\022\025\n\010database\030" + + "\001 \001(\tB\003\340A\002\022\021\n\tdocuments\030\002 \003(\t\022/\n\004mask\030\003 " + + "\001(\0132!.google.firestore.v1.DocumentMask\022\025" + + "\n\013transaction\030\004 \001(\014H\000\022B\n\017new_transaction" + + "\030\005 \001(\0132\'.google.firestore.v1.Transaction" + + "OptionsH\000\022/\n\tread_time\030\007 \001(\0132\032.google.pr" + + "otobuf.TimestampH\000B\026\n\024consistency_select" + + "or\"\254\001\n\031BatchGetDocumentsResponse\022.\n\005foun" + + "d\030\001 \001(\0132\035.google.firestore.v1.DocumentH\000" + + "\022\021\n\007missing\030\002 \001(\tH\000\022\023\n\013transaction\030\003 \001(\014" + + "\022-\n\tread_time\030\004 \001(\0132\032.google.protobuf.Ti" + + "mestampB\010\n\006result\"j\n\027BeginTransactionReq" + + "uest\022\025\n\010database\030\001 \001(\tB\003\340A\002\0228\n\007options\030\002" + + " \001(\0132\'.google.firestore.v1.TransactionOp" + + "tions\"/\n\030BeginTransactionResponse\022\023\n\013tra" + + "nsaction\030\001 \001(\014\"g\n\rCommitRequest\022\025\n\010datab" + + "ase\030\001 \001(\tB\003\340A\002\022*\n\006writes\030\002 \003(\0132\032.google." + + "firestore.v1.Write\022\023\n\013transaction\030\003 \001(\014\"" + + "z\n\016CommitResponse\0227\n\rwrite_results\030\001 \003(\013" + + "2 .google.firestore.v1.WriteResult\022/\n\013co" + + "mmit_time\030\002 \001(\0132\032.google.protobuf.Timest" + + "amp\"B\n\017RollbackRequest\022\025\n\010database\030\001 \001(\t" + + "B\003\340A\002\022\030\n\013transaction\030\002 \001(\014B\003\340A\002\"\232\002\n\017RunQ" + + "ueryRequest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022@\n\020stru" + + "ctured_query\030\002 \001(\0132$.google.firestore.v1" + + ".StructuredQueryH\000\022\025\n\013transaction\030\005 \001(\014H" + + "\001\022B\n\017new_transaction\030\006 \001(\0132\'.google.fire" + + "store.v1.TransactionOptionsH\001\022/\n\tread_ti" + + "me\030\007 \001(\0132\032.google.protobuf.TimestampH\001B\014" + + "\n\nquery_typeB\026\n\024consistency_selector\"\311\001\n" + + "\020RunQueryResponse\022\023\n\013transaction\030\002 \001(\014\022/" + "\n\010document\030\001 \001(\0132\035.google.firestore.v1.D" - + "ocumentB\003\340A\002\0226\n\013update_mask\030\002 \001(\0132!.goog" - + "le.firestore.v1.DocumentMask\022/\n\004mask\030\003 \001" - + "(\0132!.google.firestore.v1.DocumentMask\022;\n" - + "\020current_document\030\004 \001(\0132!.google.firesto" - + "re.v1.Precondition\"g\n\025DeleteDocumentRequ" - + "est\022\021\n\004name\030\001 \001(\tB\003\340A\002\022;\n\020current_docume" - + "nt\030\002 \001(\0132!.google.firestore.v1.Precondit" - + "ion\"\231\002\n\030BatchGetDocumentsRequest\022\025\n\010data" - + "base\030\001 \001(\tB\003\340A\002\022\021\n\tdocuments\030\002 \003(\t\022/\n\004ma" - + "sk\030\003 \001(\0132!.google.firestore.v1.DocumentM" - + "ask\022\025\n\013transaction\030\004 \001(\014H\000\022B\n\017new_transa" - + "ction\030\005 \001(\0132\'.google.firestore.v1.Transa" - + "ctionOptionsH\000\022/\n\tread_time\030\007 \001(\0132\032.goog" - + "le.protobuf.TimestampH\000B\026\n\024consistency_s" - + "elector\"\254\001\n\031BatchGetDocumentsResponse\022.\n" - + "\005found\030\001 \001(\0132\035.google.firestore.v1.Docum" - + "entH\000\022\021\n\007missing\030\002 \001(\tH\000\022\023\n\013transaction\030" - + "\003 \001(\014\022-\n\tread_time\030\004 \001(\0132\032.google.protob" - + "uf.TimestampB\010\n\006result\"j\n\027BeginTransacti" - + "onRequest\022\025\n\010database\030\001 \001(\tB\003\340A\002\0228\n\007opti" - + "ons\030\002 \001(\0132\'.google.firestore.v1.Transact" - + "ionOptions\"/\n\030BeginTransactionResponse\022\023" - + "\n\013transaction\030\001 \001(\014\"g\n\rCommitRequest\022\025\n\010" - + "database\030\001 \001(\tB\003\340A\002\022*\n\006writes\030\002 \003(\0132\032.go" - + "ogle.firestore.v1.Write\022\023\n\013transaction\030\003" - + " \001(\014\"z\n\016CommitResponse\0227\n\rwrite_results\030" - + "\001 \003(\0132 .google.firestore.v1.WriteResult\022" - + "/\n\013commit_time\030\002 \001(\0132\032.google.protobuf.T" - + "imestamp\"B\n\017RollbackRequest\022\025\n\010database\030" - + "\001 \001(\tB\003\340A\002\022\030\n\013transaction\030\002 \001(\014B\003\340A\002\"\335\002\n" - + "\017RunQueryRequest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022@\n" - + "\020structured_query\030\002 \001(\0132$.google.firesto" - + "re.v1.StructuredQueryH\000\022\025\n\013transaction\030\005" - + " \001(\014H\001\022B\n\017new_transaction\030\006 \001(\0132\'.google" - + ".firestore.v1.TransactionOptionsH\001\022/\n\tre" - + "ad_time\030\007 \001(\0132\032.google.protobuf.Timestam" - + "pH\001\022A\n\017explain_options\030\n \001(\0132#.google.fi" - + "restore.v1.ExplainOptionsB\003\340A\001B\014\n\nquery_" - + "typeB\026\n\024consistency_selector\"\207\002\n\020RunQuer" - + "yResponse\022\023\n\013transaction\030\002 \001(\014\022/\n\010docume" - + "nt\030\001 \001(\0132\035.google.firestore.v1.Document\022" - + "-\n\tread_time\030\003 \001(\0132\032.google.protobuf.Tim" - + "estamp\022\027\n\017skipped_results\030\004 \001(\005\022\016\n\004done\030" - + "\006 \001(\010H\000\022<\n\017explain_metrics\030\013 \001(\0132#.googl" - + "e.firestore.v1.ExplainMetricsB\027\n\025continu" - + "ation_selector\"\377\002\n\032RunAggregationQueryRe" - + "quest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022W\n\034structured" - + "_aggregation_query\030\002 \001(\0132/.google.firest" - + "ore.v1.StructuredAggregationQueryH\000\022\025\n\013t" - + "ransaction\030\004 \001(\014H\001\022B\n\017new_transaction\030\005 " - + "\001(\0132\'.google.firestore.v1.TransactionOpt" - + "ionsH\001\022/\n\tread_time\030\006 \001(\0132\032.google.proto" - + "buf.TimestampH\001\022A\n\017explain_options\030\010 \001(\013" - + "2#.google.firestore.v1.ExplainOptionsB\003\340" - + "A\001B\014\n\nquery_typeB\026\n\024consistency_selector" - + "\"\327\001\n\033RunAggregationQueryResponse\0226\n\006resu" - + "lt\030\001 \001(\0132&.google.firestore.v1.Aggregati" - + "onResult\022\023\n\013transaction\030\002 \001(\014\022-\n\tread_ti" - + "me\030\003 \001(\0132\032.google.protobuf.Timestamp\022<\n\017" - + "explain_metrics\030\n \001(\0132#.google.firestore" - + ".v1.ExplainMetrics\"\205\002\n\025PartitionQueryReq" - + "uest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022@\n\020structured_" - + "query\030\002 \001(\0132$.google.firestore.v1.Struct" - + "uredQueryH\000\022\027\n\017partition_count\030\003 \001(\003\022\022\n\n" - + "page_token\030\004 \001(\t\022\021\n\tpage_size\030\005 \001(\005\022/\n\tr" - + "ead_time\030\006 \001(\0132\032.google.protobuf.Timesta" - + "mpH\001B\014\n\nquery_typeB\026\n\024consistency_select" - + "or\"b\n\026PartitionQueryResponse\022/\n\npartitio" - + "ns\030\001 \003(\0132\033.google.firestore.v1.Cursor\022\027\n" - + "\017next_page_token\030\002 \001(\t\"\350\001\n\014WriteRequest\022" - + "\025\n\010database\030\001 \001(\tB\003\340A\002\022\021\n\tstream_id\030\002 \001(" - + "\t\022*\n\006writes\030\003 \003(\0132\032.google.firestore.v1." - + "Write\022\024\n\014stream_token\030\004 \001(\014\022=\n\006labels\030\005 " - + "\003(\0132-.google.firestore.v1.WriteRequest.L" - + "abelsEntry\032-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r" - + "\n\005value\030\002 \001(\t:\0028\001\"\242\001\n\rWriteResponse\022\021\n\ts" - + "tream_id\030\001 \001(\t\022\024\n\014stream_token\030\002 \001(\014\0227\n\r" - + "write_results\030\003 \003(\0132 .google.firestore.v" - + "1.WriteResult\022/\n\013commit_time\030\004 \001(\0132\032.goo" - + "gle.protobuf.Timestamp\"\362\001\n\rListenRequest" - + "\022\025\n\010database\030\001 \001(\tB\003\340A\002\0221\n\nadd_target\030\002 " - + "\001(\0132\033.google.firestore.v1.TargetH\000\022\027\n\rre" - + "move_target\030\003 \001(\005H\000\022>\n\006labels\030\004 \003(\0132..go" - + "ogle.firestore.v1.ListenRequest.LabelsEn" - + "try\032-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value" - + "\030\002 \001(\t:\0028\001B\017\n\rtarget_change\"\325\002\n\016ListenRe" - + "sponse\022:\n\rtarget_change\030\002 \001(\0132!.google.f" - + "irestore.v1.TargetChangeH\000\022>\n\017document_c" - + "hange\030\003 \001(\0132#.google.firestore.v1.Docume" - + "ntChangeH\000\022>\n\017document_delete\030\004 \001(\0132#.go" - + "ogle.firestore.v1.DocumentDeleteH\000\022>\n\017do" - + "cument_remove\030\006 \001(\0132#.google.firestore.v" - + "1.DocumentRemoveH\000\0226\n\006filter\030\005 \001(\0132$.goo" - + "gle.firestore.v1.ExistenceFilterH\000B\017\n\rre" - + "sponse_type\"\326\003\n\006Target\0228\n\005query\030\002 \001(\0132\'." - + "google.firestore.v1.Target.QueryTargetH\000" - + "\022@\n\tdocuments\030\003 \001(\0132+.google.firestore.v" - + "1.Target.DocumentsTargetH\000\022\026\n\014resume_tok" - + "en\030\004 \001(\014H\001\022/\n\tread_time\030\013 \001(\0132\032.google.p" - + "rotobuf.TimestampH\001\022\021\n\ttarget_id\030\005 \001(\005\022\014" - + "\n\004once\030\006 \001(\010\0223\n\016expected_count\030\014 \001(\0132\033.g" - + "oogle.protobuf.Int32Value\032$\n\017DocumentsTa" - + "rget\022\021\n\tdocuments\030\002 \003(\t\032m\n\013QueryTarget\022\016" - + "\n\006parent\030\001 \001(\t\022@\n\020structured_query\030\002 \001(\013" + + "ocument\022-\n\tread_time\030\003 \001(\0132\032.google.prot" + + "obuf.Timestamp\022\027\n\017skipped_results\030\004 \001(\005\022" + + "\016\n\004done\030\006 \001(\010H\000B\027\n\025continuation_selector" + + "\"\254\002\n\026ExecutePipelineRequest\022\025\n\010database\030" + + "\001 \001(\tB\003\340A\002\022F\n\023structured_pipeline\030\002 \001(\0132" + + "\'.google.firestore.v1.StructuredPipeline" + + "H\000\022\025\n\013transaction\030\005 \001(\014H\001\022B\n\017new_transac" + + "tion\030\006 \001(\0132\'.google.firestore.v1.Transac" + + "tionOptionsH\001\022/\n\tread_time\030\007 \001(\0132\032.googl" + + "e.protobuf.TimestampH\001B\017\n\rpipeline_typeB" + + "\026\n\024consistency_selector\"\222\001\n\027ExecutePipel" + + "ineResponse\022\023\n\013transaction\030\001 \001(\014\022.\n\007resu" + + "lts\030\002 \003(\0132\035.google.firestore.v1.Document" + + "\0222\n\016execution_time\030\003 \001(\0132\032.google.protob" + + "uf.Timestamp\"\274\002\n\032RunAggregationQueryRequ" + + "est\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022W\n\034structured_a" + + "ggregation_query\030\002 \001(\0132/.google.firestor" + + "e.v1.StructuredAggregationQueryH\000\022\025\n\013tra" + + "nsaction\030\004 \001(\014H\001\022B\n\017new_transaction\030\005 \001(" + + "\0132\'.google.firestore.v1.TransactionOptio" + + "nsH\001\022/\n\tread_time\030\006 \001(\0132\032.google.protobu" + + "f.TimestampH\001B\014\n\nquery_typeB\026\n\024consisten" + + "cy_selector\"\231\001\n\033RunAggregationQueryRespo" + + "nse\0226\n\006result\030\001 \001(\0132&.google.firestore.v" + + "1.AggregationResult\022\023\n\013transaction\030\002 \001(\014" + + "\022-\n\tread_time\030\003 \001(\0132\032.google.protobuf.Ti" + + "mestamp\"\205\002\n\025PartitionQueryRequest\022\023\n\006par" + + "ent\030\001 \001(\tB\003\340A\002\022@\n\020structured_query\030\002 \001(\013" + "2$.google.firestore.v1.StructuredQueryH\000" - + "B\014\n\nquery_typeB\r\n\013target_typeB\r\n\013resume_" - + "type\"\252\002\n\014TargetChange\022N\n\022target_change_t" - + "ype\030\001 \001(\01622.google.firestore.v1.TargetCh" - + "ange.TargetChangeType\022\022\n\ntarget_ids\030\002 \003(" - + "\005\022!\n\005cause\030\003 \001(\0132\022.google.rpc.Status\022\024\n\014" - + "resume_token\030\004 \001(\014\022-\n\tread_time\030\006 \001(\0132\032." - + "google.protobuf.Timestamp\"N\n\020TargetChang" - + "eType\022\r\n\tNO_CHANGE\020\000\022\007\n\003ADD\020\001\022\n\n\006REMOVE\020" - + "\002\022\013\n\007CURRENT\020\003\022\t\n\005RESET\020\004\"\237\001\n\030ListCollec" - + "tionIdsRequest\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022\021\n\tp" - + "age_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\022/\n\tre" - + "ad_time\030\004 \001(\0132\032.google.protobuf.Timestam" - + "pH\000B\026\n\024consistency_selector\"L\n\031ListColle" - + "ctionIdsResponse\022\026\n\016collection_ids\030\001 \003(\t" - + "\022\027\n\017next_page_token\030\002 \001(\t\"\311\001\n\021BatchWrite" - + "Request\022\025\n\010database\030\001 \001(\tB\003\340A\002\022*\n\006writes" - + "\030\002 \003(\0132\032.google.firestore.v1.Write\022B\n\006la" - + "bels\030\003 \003(\01322.google.firestore.v1.BatchWr" - + "iteRequest.LabelsEntry\032-\n\013LabelsEntry\022\013\n" - + "\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"q\n\022BatchWr" - + "iteResponse\0227\n\rwrite_results\030\001 \003(\0132 .goo" - + "gle.firestore.v1.WriteResult\022\"\n\006status\030\002" - + " \003(\0132\022.google.rpc.Status2\332\031\n\tFirestore\022\217" - + "\001\n\013GetDocument\022\'.google.firestore.v1.Get" - + "DocumentRequest\032\035.google.firestore.v1.Do" - + "cument\"8\202\323\344\223\0022\0220/v1/{name=projects/*/dat" - + "abases/*/documents/*/**}\022\365\001\n\rListDocumen" - + "ts\022).google.firestore.v1.ListDocumentsRe" - + "quest\032*.google.firestore.v1.ListDocument" - + "sResponse\"\214\001\202\323\344\223\002\205\001\022B/v1/{parent=project" - + "s/*/databases/*/documents/*/**}/{collect" - + "ion_id}Z?\022=/v1/{parent=projects/*/databa" - + "ses/*/documents}/{collection_id}\022\277\001\n\016Upd" - + "ateDocument\022*.google.firestore.v1.Update" + + "\022\027\n\017partition_count\030\003 \001(\003\022\022\n\npage_token\030" + + "\004 \001(\t\022\021\n\tpage_size\030\005 \001(\005\022/\n\tread_time\030\006 " + + "\001(\0132\032.google.protobuf.TimestampH\001B\014\n\nque" + + "ry_typeB\026\n\024consistency_selector\"b\n\026Parti" + + "tionQueryResponse\022/\n\npartitions\030\001 \003(\0132\033." + + "google.firestore.v1.Cursor\022\027\n\017next_page_" + + "token\030\002 \001(\t\"\350\001\n\014WriteRequest\022\025\n\010database" + + "\030\001 \001(\tB\003\340A\002\022\021\n\tstream_id\030\002 \001(\t\022*\n\006writes" + + "\030\003 \003(\0132\032.google.firestore.v1.Write\022\024\n\014st" + + "ream_token\030\004 \001(\014\022=\n\006labels\030\005 \003(\0132-.googl" + + "e.firestore.v1.WriteRequest.LabelsEntry\032" + + "-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001" + + "(\t:\0028\001\"\242\001\n\rWriteResponse\022\021\n\tstream_id\030\001 " + + "\001(\t\022\024\n\014stream_token\030\002 \001(\014\0227\n\rwrite_resul" + + "ts\030\003 \003(\0132 .google.firestore.v1.WriteResu" + + "lt\022/\n\013commit_time\030\004 \001(\0132\032.google.protobu" + + "f.Timestamp\"\362\001\n\rListenRequest\022\025\n\010databas" + + "e\030\001 \001(\tB\003\340A\002\0221\n\nadd_target\030\002 \001(\0132\033.googl" + + "e.firestore.v1.TargetH\000\022\027\n\rremove_target" + + "\030\003 \001(\005H\000\022>\n\006labels\030\004 \003(\0132..google.firest" + + "ore.v1.ListenRequest.LabelsEntry\032-\n\013Labe" + + "lsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B" + + "\017\n\rtarget_change\"\325\002\n\016ListenResponse\022:\n\rt" + + "arget_change\030\002 \001(\0132!.google.firestore.v1" + + ".TargetChangeH\000\022>\n\017document_change\030\003 \001(\013" + + "2#.google.firestore.v1.DocumentChangeH\000\022" + + ">\n\017document_delete\030\004 \001(\0132#.google.firest" + + "ore.v1.DocumentDeleteH\000\022>\n\017document_remo" + + "ve\030\006 \001(\0132#.google.firestore.v1.DocumentR" + + "emoveH\000\0226\n\006filter\030\005 \001(\0132$.google.firesto" + + "re.v1.ExistenceFilterH\000B\017\n\rresponse_type" + + "\"\326\003\n\006Target\0228\n\005query\030\002 \001(\0132\'.google.fire" + + "store.v1.Target.QueryTargetH\000\022@\n\tdocumen" + + "ts\030\003 \001(\0132+.google.firestore.v1.Target.Do" + + "cumentsTargetH\000\022\026\n\014resume_token\030\004 \001(\014H\001\022" + + "/\n\tread_time\030\013 \001(\0132\032.google.protobuf.Tim" + + "estampH\001\022\021\n\ttarget_id\030\005 \001(\005\022\014\n\004once\030\006 \001(" + + "\010\0223\n\016expected_count\030\014 \001(\0132\033.google.proto" + + "buf.Int32Value\032$\n\017DocumentsTarget\022\021\n\tdoc" + + "uments\030\002 \003(\t\032m\n\013QueryTarget\022\016\n\006parent\030\001 " + + "\001(\t\022@\n\020structured_query\030\002 \001(\0132$.google.f" + + "irestore.v1.StructuredQueryH\000B\014\n\nquery_t" + + "ypeB\r\n\013target_typeB\r\n\013resume_type\"\252\002\n\014Ta" + + "rgetChange\022N\n\022target_change_type\030\001 \001(\01622" + + ".google.firestore.v1.TargetChange.Target" + + "ChangeType\022\022\n\ntarget_ids\030\002 \003(\005\022!\n\005cause\030" + + "\003 \001(\0132\022.google.rpc.Status\022\024\n\014resume_toke" + + "n\030\004 \001(\014\022-\n\tread_time\030\006 \001(\0132\032.google.prot" + + "obuf.Timestamp\"N\n\020TargetChangeType\022\r\n\tNO" + + "_CHANGE\020\000\022\007\n\003ADD\020\001\022\n\n\006REMOVE\020\002\022\013\n\007CURREN" + + "T\020\003\022\t\n\005RESET\020\004\"\237\001\n\030ListCollectionIdsRequ" + + "est\022\023\n\006parent\030\001 \001(\tB\003\340A\002\022\021\n\tpage_size\030\002 " + + "\001(\005\022\022\n\npage_token\030\003 \001(\t\022/\n\tread_time\030\004 \001" + + "(\0132\032.google.protobuf.TimestampH\000B\026\n\024cons" + + "istency_selector\"L\n\031ListCollectionIdsRes" + + "ponse\022\026\n\016collection_ids\030\001 \003(\t\022\027\n\017next_pa" + + "ge_token\030\002 \001(\t\"\311\001\n\021BatchWriteRequest\022\025\n\010" + + "database\030\001 \001(\tB\003\340A\002\022*\n\006writes\030\002 \003(\0132\032.go" + + "ogle.firestore.v1.Write\022B\n\006labels\030\003 \003(\0132" + + "2.google.firestore.v1.BatchWriteRequest." + + "LabelsEntry\032-\n\013LabelsEntry\022\013\n\003key\030\001 \001(\t\022" + + "\r\n\005value\030\002 \001(\t:\0028\001\"q\n\022BatchWriteResponse" + + "\0227\n\rwrite_results\030\001 \003(\0132 .google.firesto" + + "re.v1.WriteResult\022\"\n\006status\030\002 \003(\0132\022.goog" + + "le.rpc.Status2\222\033\n\tFirestore\022\217\001\n\013GetDocum" + + "ent\022\'.google.firestore.v1.GetDocumentReq" + + "uest\032\035.google.firestore.v1.Document\"8\202\323\344" + + "\223\0022\0220/v1/{name=projects/*/databases/*/do" + + "cuments/*/**}\022\365\001\n\rListDocuments\022).google" + + ".firestore.v1.ListDocumentsRequest\032*.goo" + + "gle.firestore.v1.ListDocumentsResponse\"\214" + + "\001\202\323\344\223\002\205\001\022B/v1/{parent=projects/*/databas" + + "es/*/documents/*/**}/{collection_id}Z?\022=" + + "/v1/{parent=projects/*/databases/*/docum" + + "ents}/{collection_id}\022\277\001\n\016UpdateDocument" + + "\022*.google.firestore.v1.UpdateDocumentReq" + + "uest\032\035.google.firestore.v1.Document\"b\332A\024" + + "document,update_mask\202\323\344\223\002E29/v1/{documen" + + "t.name=projects/*/databases/*/documents/" + + "*/**}:\010document\022\225\001\n\016DeleteDocument\022*.goo" + + "gle.firestore.v1.DeleteDocumentRequest\032\026" + + ".google.protobuf.Empty\"?\332A\004name\202\323\344\223\0022*0/" + + "v1/{name=projects/*/databases/*/document" + + "s/*/**}\022\271\001\n\021BatchGetDocuments\022-.google.f" + + "irestore.v1.BatchGetDocumentsRequest\032..g" + + "oogle.firestore.v1.BatchGetDocumentsResp" + + "onse\"C\202\323\344\223\002=\"8/v1/{database=projects/*/d" + + "atabases/*}/documents:batchGet:\001*0\001\022\307\001\n\020" + + "BeginTransaction\022,.google.firestore.v1.B" + + "eginTransactionRequest\032-.google.firestor" + + "e.v1.BeginTransactionResponse\"V\332A\010databa" + + "se\202\323\344\223\002E\"@/v1/{database=projects/*/datab" + + "ases/*}/documents:beginTransaction:\001*\022\246\001" + + "\n\006Commit\022\".google.firestore.v1.CommitReq" + + "uest\032#.google.firestore.v1.CommitRespons" + + "e\"S\332A\017database,writes\202\323\344\223\002;\"6/v1/{databa" + + "se=projects/*/databases/*}/documents:com" + + "mit:\001*\022\244\001\n\010Rollback\022$.google.firestore.v" + + "1.RollbackRequest\032\026.google.protobuf.Empt" + + "y\"Z\332A\024database,transaction\202\323\344\223\002=\"8/v1/{d" + + "atabase=projects/*/databases/*}/document" + + "s:rollback:\001*\022\337\001\n\010RunQuery\022$.google.fire" + + "store.v1.RunQueryRequest\032%.google.firest" + + "ore.v1.RunQueryResponse\"\203\001\202\323\344\223\002}\"6/v1/{p" + + "arent=projects/*/databases/*/documents}:" + + "runQuery:\001*Z@\";/v1/{parent=projects/*/da" + + "tabases/*/documents/*/**}:runQuery:\001*0\001\022" + + "\265\001\n\017ExecutePipeline\022+.google.firestore.v" + + "1.ExecutePipelineRequest\032,.google.firest" + + "ore.v1.ExecutePipelineResponse\"E\202\323\344\223\002?\":" + + "/v1beta1/{database=projects/*/databases/" + + "*}:executePipeline:\001*0\001\022\227\002\n\023RunAggregati" + + "onQuery\022/.google.firestore.v1.RunAggrega" + + "tionQueryRequest\0320.google.firestore.v1.R" + + "unAggregationQueryResponse\"\232\001\202\323\344\223\002\223\001\"A/v" + + "1/{parent=projects/*/databases/*/documen" + + "ts}:runAggregationQuery:\001*ZK\"F/v1/{paren" + + "t=projects/*/databases/*/documents/*/**}" + + ":runAggregationQuery:\001*0\001\022\374\001\n\016PartitionQ" + + "uery\022*.google.firestore.v1.PartitionQuer" + + "yRequest\032+.google.firestore.v1.Partition" + + "QueryResponse\"\220\001\202\323\344\223\002\211\001\" + * Represents an unevaluated scalar expression. + * + * For example, the expression `like(user_name, "%alice%")` is represented as: + * + * ``` + * name: "like" + * args { field_reference: "user_name" } + * args { string_value: "%alice%" } + * ``` + * + * (-- api-linter: core::0123::resource-annotation=disabled + * aip.dev/not-precedent: this is not a One Platform API resource. --) + * + * + * Protobuf type {@code google.firestore.v1.Function} + */ +public final class Function extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.Function) + FunctionOrBuilder { + private static final long serialVersionUID = 0L; + // Use Function.newBuilder() to construct. + private Function(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private Function() { + name_ = ""; + args_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new Function(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @java.lang.Override + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Function.class, com.google.firestore.v1.Function.Builder.class); + } + + public static final int NAME_FIELD_NUMBER = 1; + + @SuppressWarnings("serial") + private volatile java.lang.Object name_ = ""; + /** + * + * + *
+   * The name of the function to evaluate.
+   *
+   * **Requires:**
+   *
+   * * must be in snake case (lower case with underscore separator).
+   * 
+ * + * string name = 1; + * + * @return The name. + */ + @java.lang.Override + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } + } + /** + * + * + *
+   * The name of the function to evaluate.
+   *
+   * **Requires:**
+   *
+   * * must be in snake case (lower case with underscore separator).
+   * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ARGS_FIELD_NUMBER = 2; + + @SuppressWarnings("serial") + private java.util.List args_; + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public java.util.List getArgsList() { + return args_; + } + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public java.util.List getArgsOrBuilderList() { + return args_; + } + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public int getArgsCount() { + return args_.size(); + } + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public com.google.firestore.v1.Value getArgs(int index) { + return args_.get(index); + } + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index) { + return args_.get(index); + } + + public static final int OPTIONS_FIELD_NUMBER = 3; + + private static final class OptionsDefaultEntryHolder { + static final com.google.protobuf.MapEntry + defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_OptionsEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.MESSAGE, + com.google.firestore.v1.Value.getDefaultInstance()); + } + + @SuppressWarnings("serial") + private com.google.protobuf.MapField options_; + + private com.google.protobuf.MapField + internalGetOptions() { + if (options_ == null) { + return com.google.protobuf.MapField.emptyMapField(OptionsDefaultEntryHolder.defaultEntry); + } + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().getMap().size(); + } + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().getMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getMap(); + } + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_); + } + for (int i = 0; i < args_.size(); i++) { + output.writeMessage(2, args_.get(i)); + } + com.google.protobuf.GeneratedMessageV3.serializeStringMapTo( + output, internalGetOptions(), OptionsDefaultEntryHolder.defaultEntry, 3); + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_); + } + for (int i = 0; i < args_.size(); i++) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, args_.get(i)); + } + for (java.util.Map.Entry entry : + internalGetOptions().getMap().entrySet()) { + com.google.protobuf.MapEntry options__ = + OptionsDefaultEntryHolder.defaultEntry + .newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream.computeMessageSize(3, options__); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.Function)) { + return super.equals(obj); + } + com.google.firestore.v1.Function other = (com.google.firestore.v1.Function) obj; + + if (!getName().equals(other.getName())) return false; + if (!getArgsList().equals(other.getArgsList())) return false; + if (!internalGetOptions().equals(other.internalGetOptions())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + if (getArgsCount() > 0) { + hash = (37 * hash) + ARGS_FIELD_NUMBER; + hash = (53 * hash) + getArgsList().hashCode(); + } + if (!internalGetOptions().getMap().isEmpty()) { + hash = (37 * hash) + OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + internalGetOptions().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.Function parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Function parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Function parseFrom(com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Function parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Function parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Function parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Function parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Function parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Function parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Function parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Function parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Function parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.Function prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * Represents an unevaluated scalar expression.
+   *
+   * For example, the expression `like(user_name, "%alice%")` is represented as:
+   *
+   * ```
+   * name: "like"
+   * args { field_reference: "user_name" }
+   * args { string_value: "%alice%" }
+   * ```
+   *
+   * (-- api-linter: core::0123::resource-annotation=disabled
+   *     aip.dev/not-precedent: this is not a One Platform API resource. --)
+   * 
+ * + * Protobuf type {@code google.firestore.v1.Function} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.Function) + com.google.firestore.v1.FunctionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMutableMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetMutableOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Function.class, + com.google.firestore.v1.Function.Builder.class); + } + + // Construct using com.google.firestore.v1.Function.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + name_ = ""; + if (argsBuilder_ == null) { + args_ = java.util.Collections.emptyList(); + } else { + args_ = null; + argsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + internalGetMutableOptions().clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Function_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.Function getDefaultInstanceForType() { + return com.google.firestore.v1.Function.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.Function build() { + com.google.firestore.v1.Function result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.Function buildPartial() { + com.google.firestore.v1.Function result = new com.google.firestore.v1.Function(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(com.google.firestore.v1.Function result) { + if (argsBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + args_ = java.util.Collections.unmodifiableList(args_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.args_ = args_; + } else { + result.args_ = argsBuilder_.build(); + } + } + + private void buildPartial0(com.google.firestore.v1.Function result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.name_ = name_; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.options_ = internalGetOptions().build(OptionsDefaultEntryHolder.defaultEntry); + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.Function) { + return mergeFrom((com.google.firestore.v1.Function) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.Function other) { + if (other == com.google.firestore.v1.Function.getDefaultInstance()) return this; + if (!other.getName().isEmpty()) { + name_ = other.name_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (argsBuilder_ == null) { + if (!other.args_.isEmpty()) { + if (args_.isEmpty()) { + args_ = other.args_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureArgsIsMutable(); + args_.addAll(other.args_); + } + onChanged(); + } + } else { + if (!other.args_.isEmpty()) { + if (argsBuilder_.isEmpty()) { + argsBuilder_.dispose(); + argsBuilder_ = null; + args_ = other.args_; + bitField0_ = (bitField0_ & ~0x00000002); + argsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders + ? getArgsFieldBuilder() + : null; + } else { + argsBuilder_.addAllMessages(other.args_); + } + } + } + internalGetMutableOptions().mergeFrom(other.internalGetOptions()); + bitField0_ |= 0x00000004; + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + name_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: + { + com.google.firestore.v1.Value m = + input.readMessage(com.google.firestore.v1.Value.parser(), extensionRegistry); + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(m); + } else { + argsBuilder_.addMessage(m); + } + break; + } // case 18 + case 26: + { + com.google.protobuf.MapEntry + options__ = + input.readMessage( + OptionsDefaultEntryHolder.defaultEntry.getParserForType(), + extensionRegistry); + internalGetMutableOptions() + .ensureBuilderMap() + .put(options__.getKey(), options__.getValue()); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private java.lang.Object name_ = ""; + /** + * + * + *
+     * The name of the function to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The name. + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * The name of the function to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * The name of the function to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @param value The name to set. + * @return This builder for chaining. + */ + public Builder setName(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * The name of the function to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return This builder for chaining. + */ + public Builder clearName() { + name_ = getDefaultInstance().getName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * + * + *
+     * The name of the function to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @param value The bytes for name to set. + * @return This builder for chaining. + */ + public Builder setNameBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private java.util.List args_ = java.util.Collections.emptyList(); + + private void ensureArgsIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + args_ = new java.util.ArrayList(args_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder> + argsBuilder_; + + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List getArgsList() { + if (argsBuilder_ == null) { + return java.util.Collections.unmodifiableList(args_); + } else { + return argsBuilder_.getMessageList(); + } + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public int getArgsCount() { + if (argsBuilder_ == null) { + return args_.size(); + } else { + return argsBuilder_.getCount(); + } + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value getArgs(int index) { + if (argsBuilder_ == null) { + return args_.get(index); + } else { + return argsBuilder_.getMessage(index); + } + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder setArgs(int index, com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.set(index, value); + onChanged(); + } else { + argsBuilder_.setMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder setArgs(int index, com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.set(index, builderForValue.build()); + onChanged(); + } else { + argsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.add(value); + onChanged(); + } else { + argsBuilder_.addMessage(value); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(int index, com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.add(index, value); + onChanged(); + } else { + argsBuilder_.addMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(builderForValue.build()); + onChanged(); + } else { + argsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(int index, com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(index, builderForValue.build()); + onChanged(); + } else { + argsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addAllArgs(java.lang.Iterable values) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll(values, args_); + onChanged(); + } else { + argsBuilder_.addAllMessages(values); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder clearArgs() { + if (argsBuilder_ == null) { + args_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + argsBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder removeArgs(int index) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.remove(index); + onChanged(); + } else { + argsBuilder_.remove(index); + } + return this; + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder getArgsBuilder(int index) { + return getArgsFieldBuilder().getBuilder(index); + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index) { + if (argsBuilder_ == null) { + return args_.get(index); + } else { + return argsBuilder_.getMessageOrBuilder(index); + } + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List getArgsOrBuilderList() { + if (argsBuilder_ != null) { + return argsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(args_); + } + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder addArgsBuilder() { + return getArgsFieldBuilder().addBuilder(com.google.firestore.v1.Value.getDefaultInstance()); + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder addArgsBuilder(int index) { + return getArgsFieldBuilder() + .addBuilder(index, com.google.firestore.v1.Value.getDefaultInstance()); + } + /** + * + * + *
+     * Ordered list of arguments the given function expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List getArgsBuilderList() { + return getArgsFieldBuilder().getBuilderList(); + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder> + getArgsFieldBuilder() { + if (argsBuilder_ == null) { + argsBuilder_ = + new com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder>( + args_, ((bitField0_ & 0x00000002) != 0), getParentForChildren(), isClean()); + args_ = null; + } + return argsBuilder_; + } + + private static final class OptionsConverter + implements com.google.protobuf.MapFieldBuilder.Converter< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value> { + @java.lang.Override + public com.google.firestore.v1.Value build(com.google.firestore.v1.ValueOrBuilder val) { + if (val instanceof com.google.firestore.v1.Value) { + return (com.google.firestore.v1.Value) val; + } + return ((com.google.firestore.v1.Value.Builder) val).build(); + } + + @java.lang.Override + public com.google.protobuf.MapEntry + defaultEntry() { + return OptionsDefaultEntryHolder.defaultEntry; + } + }; + + private static final OptionsConverter optionsConverter = new OptionsConverter(); + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + options_; + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetOptions() { + if (options_ == null) { + return new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + return options_; + } + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetMutableOptions() { + if (options_ == null) { + options_ = new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + bitField0_ |= 0x00000004; + onChanged(); + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().ensureBuilderMap().size(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().ensureBuilderMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getImmutableMap(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + return map.containsKey(key) ? optionsConverter.build(map.get(key)) : defaultValue; + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return optionsConverter.build(map.get(key)); + } + + public Builder clearOptions() { + bitField0_ = (bitField0_ & ~0x00000004); + internalGetMutableOptions().clear(); + return this; + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder removeOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + internalGetMutableOptions().ensureBuilderMap().remove(key); + return this; + } + /** Use alternate mutation accessors instead. */ + @java.lang.Deprecated + public java.util.Map getMutableOptions() { + bitField0_ |= 0x00000004; + return internalGetMutableOptions().ensureMessageMap(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder putOptions(java.lang.String key, com.google.firestore.v1.Value value) { + if (key == null) { + throw new NullPointerException("map key"); + } + if (value == null) { + throw new NullPointerException("map value"); + } + internalGetMutableOptions().ensureBuilderMap().put(key, value); + bitField0_ |= 0x00000004; + return this; + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder putAllOptions( + java.util.Map values) { + for (java.util.Map.Entry e : + values.entrySet()) { + if (e.getKey() == null || e.getValue() == null) { + throw new NullPointerException(); + } + } + internalGetMutableOptions().ensureBuilderMap().putAll(values); + bitField0_ |= 0x00000004; + return this; + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public com.google.firestore.v1.Value.Builder putOptionsBuilderIfAbsent(java.lang.String key) { + java.util.Map builderMap = + internalGetMutableOptions().ensureBuilderMap(); + com.google.firestore.v1.ValueOrBuilder entry = builderMap.get(key); + if (entry == null) { + entry = com.google.firestore.v1.Value.newBuilder(); + builderMap.put(key, entry); + } + if (entry instanceof com.google.firestore.v1.Value) { + entry = ((com.google.firestore.v1.Value) entry).toBuilder(); + builderMap.put(key, entry); + } + return (com.google.firestore.v1.Value.Builder) entry; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.Function) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.Function) + private static final com.google.firestore.v1.Function DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.Function(); + } + + public static com.google.firestore.v1.Function getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Function parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.Function getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FunctionOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FunctionOrBuilder.java new file mode 100644 index 000000000..e1ca51940 --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/FunctionOrBuilder.java @@ -0,0 +1,168 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/document.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public interface FunctionOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.Function) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * The name of the function to evaluate.
+   *
+   * **Requires:**
+   *
+   * * must be in snake case (lower case with underscore separator).
+   * 
+ * + * string name = 1; + * + * @return The name. + */ + java.lang.String getName(); + /** + * + * + *
+   * The name of the function to evaluate.
+   *
+   * **Requires:**
+   *
+   * * must be in snake case (lower case with underscore separator).
+   * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + com.google.protobuf.ByteString getNameBytes(); + + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + java.util.List getArgsList(); + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + com.google.firestore.v1.Value getArgs(int index); + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + int getArgsCount(); + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + java.util.List getArgsOrBuilderList(); + /** + * + * + *
+   * Ordered list of arguments the given function expects.
+   * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index); + + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + int getOptionsCount(); + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + boolean containsOptions(java.lang.String key); + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Deprecated + java.util.Map getOptions(); + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + java.util.Map getOptionsMap(); + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + /* nullable */ + com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue); + /** + * + * + *
+   * Optional named arguments that certain functions may support.
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key); +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Pipeline.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Pipeline.java new file mode 100644 index 000000000..5be2143a0 --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Pipeline.java @@ -0,0 +1,2640 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/document.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +/** + * + * + *
+ * A Firestore query represented as an ordered list of operations / stages.
+ * 
+ * + * Protobuf type {@code google.firestore.v1.Pipeline} + */ +public final class Pipeline extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.Pipeline) + PipelineOrBuilder { + private static final long serialVersionUID = 0L; + // Use Pipeline.newBuilder() to construct. + private Pipeline(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private Pipeline() { + stages_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new Pipeline(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Pipeline.class, com.google.firestore.v1.Pipeline.Builder.class); + } + + public interface StageOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.Pipeline.Stage) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+     * The name of the stage to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The name. + */ + java.lang.String getName(); + /** + * + * + *
+     * The name of the stage to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + com.google.protobuf.ByteString getNameBytes(); + + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + java.util.List getArgsList(); + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + com.google.firestore.v1.Value getArgs(int index); + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + int getArgsCount(); + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + java.util.List getArgsOrBuilderList(); + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index); + + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + int getOptionsCount(); + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + boolean containsOptions(java.lang.String key); + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Deprecated + java.util.Map getOptions(); + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + java.util.Map getOptionsMap(); + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + /* nullable */ + com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue); + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key); + } + /** + * + * + *
+   * A single operation within a pipeline.
+   *
+   * A stage is made up of a unique name, and a list of arguments. The exact
+   * number of arguments & types is dependent on the stage type.
+   *
+   * To give an example, the stage `filter(state = "MD")` would be encoded as:
+   *
+   * ```
+   * name: "filter"
+   * args {
+   *   function_value {
+   *     name: "eq"
+   *     args { field_reference_value: "state" }
+   *     args { string_value: "MD" }
+   *   }
+   * }
+   * ```
+   *
+   * See public documentation for the full list.
+   * 
+ * + * Protobuf type {@code google.firestore.v1.Pipeline.Stage} + */ + public static final class Stage extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.Pipeline.Stage) + StageOrBuilder { + private static final long serialVersionUID = 0L; + // Use Stage.newBuilder() to construct. + private Stage(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private Stage() { + name_ = ""; + args_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new Stage(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @java.lang.Override + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Pipeline.Stage.class, + com.google.firestore.v1.Pipeline.Stage.Builder.class); + } + + public static final int NAME_FIELD_NUMBER = 1; + + @SuppressWarnings("serial") + private volatile java.lang.Object name_ = ""; + /** + * + * + *
+     * The name of the stage to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The name. + */ + @java.lang.Override + public java.lang.String getName() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } + } + /** + * + * + *
+     * The name of the stage to evaluate.
+     *
+     * **Requires:**
+     *
+     * * must be in snake case (lower case with underscore separator).
+     * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ARGS_FIELD_NUMBER = 2; + + @SuppressWarnings("serial") + private java.util.List args_; + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public java.util.List getArgsList() { + return args_; + } + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public java.util.List getArgsOrBuilderList() { + return args_; + } + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public int getArgsCount() { + return args_.size(); + } + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public com.google.firestore.v1.Value getArgs(int index) { + return args_.get(index); + } + /** + * + * + *
+     * Ordered list of arguments the given stage expects.
+     * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + @java.lang.Override + public com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index) { + return args_.get(index); + } + + public static final int OPTIONS_FIELD_NUMBER = 3; + + private static final class OptionsDefaultEntryHolder { + static final com.google.protobuf.MapEntry + defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_OptionsEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.MESSAGE, + com.google.firestore.v1.Value.getDefaultInstance()); + } + + @SuppressWarnings("serial") + private com.google.protobuf.MapField options_; + + private com.google.protobuf.MapField + internalGetOptions() { + if (options_ == null) { + return com.google.protobuf.MapField.emptyMapField(OptionsDefaultEntryHolder.defaultEntry); + } + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().getMap().size(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().getMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getMap(); + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * + * + *
+     * Optional named arguments that certain functions may support.
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_); + } + for (int i = 0; i < args_.size(); i++) { + output.writeMessage(2, args_.get(i)); + } + com.google.protobuf.GeneratedMessageV3.serializeStringMapTo( + output, internalGetOptions(), OptionsDefaultEntryHolder.defaultEntry, 3); + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(name_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_); + } + for (int i = 0; i < args_.size(); i++) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, args_.get(i)); + } + for (java.util.Map.Entry entry : + internalGetOptions().getMap().entrySet()) { + com.google.protobuf.MapEntry options__ = + OptionsDefaultEntryHolder.defaultEntry + .newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream.computeMessageSize(3, options__); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.Pipeline.Stage)) { + return super.equals(obj); + } + com.google.firestore.v1.Pipeline.Stage other = (com.google.firestore.v1.Pipeline.Stage) obj; + + if (!getName().equals(other.getName())) return false; + if (!getArgsList().equals(other.getArgsList())) return false; + if (!internalGetOptions().equals(other.internalGetOptions())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + if (getArgsCount() > 0) { + hash = (37 * hash) + ARGS_FIELD_NUMBER; + hash = (53 * hash) + getArgsList().hashCode(); + } + if (!internalGetOptions().getMap().isEmpty()) { + hash = (37 * hash) + OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + internalGetOptions().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline.Stage parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline.Stage parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline.Stage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.Pipeline.Stage prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+     * A single operation within a pipeline.
+     *
+     * A stage is made up of a unique name, and a list of arguments. The exact
+     * number of arguments & types is dependent on the stage type.
+     *
+     * To give an example, the stage `filter(state = "MD")` would be encoded as:
+     *
+     * ```
+     * name: "filter"
+     * args {
+     *   function_value {
+     *     name: "eq"
+     *     args { field_reference_value: "state" }
+     *     args { string_value: "MD" }
+     *   }
+     * }
+     * ```
+     *
+     * See public documentation for the full list.
+     * 
+ * + * Protobuf type {@code google.firestore.v1.Pipeline.Stage} + */ + public static final class Builder + extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.Pipeline.Stage) + com.google.firestore.v1.Pipeline.StageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMutableMapFieldReflection( + int number) { + switch (number) { + case 3: + return internalGetMutableOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Pipeline.Stage.class, + com.google.firestore.v1.Pipeline.Stage.Builder.class); + } + + // Construct using com.google.firestore.v1.Pipeline.Stage.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + name_ = ""; + if (argsBuilder_ == null) { + args_ = java.util.Collections.emptyList(); + } else { + args_ = null; + argsBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + internalGetMutableOptions().clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_Stage_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline.Stage getDefaultInstanceForType() { + return com.google.firestore.v1.Pipeline.Stage.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline.Stage build() { + com.google.firestore.v1.Pipeline.Stage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline.Stage buildPartial() { + com.google.firestore.v1.Pipeline.Stage result = + new com.google.firestore.v1.Pipeline.Stage(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(com.google.firestore.v1.Pipeline.Stage result) { + if (argsBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + args_ = java.util.Collections.unmodifiableList(args_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.args_ = args_; + } else { + result.args_ = argsBuilder_.build(); + } + } + + private void buildPartial0(com.google.firestore.v1.Pipeline.Stage result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.name_ = name_; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.options_ = internalGetOptions().build(OptionsDefaultEntryHolder.defaultEntry); + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, + java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.Pipeline.Stage) { + return mergeFrom((com.google.firestore.v1.Pipeline.Stage) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.Pipeline.Stage other) { + if (other == com.google.firestore.v1.Pipeline.Stage.getDefaultInstance()) return this; + if (!other.getName().isEmpty()) { + name_ = other.name_; + bitField0_ |= 0x00000001; + onChanged(); + } + if (argsBuilder_ == null) { + if (!other.args_.isEmpty()) { + if (args_.isEmpty()) { + args_ = other.args_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureArgsIsMutable(); + args_.addAll(other.args_); + } + onChanged(); + } + } else { + if (!other.args_.isEmpty()) { + if (argsBuilder_.isEmpty()) { + argsBuilder_.dispose(); + argsBuilder_ = null; + args_ = other.args_; + bitField0_ = (bitField0_ & ~0x00000002); + argsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders + ? getArgsFieldBuilder() + : null; + } else { + argsBuilder_.addAllMessages(other.args_); + } + } + } + internalGetMutableOptions().mergeFrom(other.internalGetOptions()); + bitField0_ |= 0x00000004; + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + name_ = input.readStringRequireUtf8(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: + { + com.google.firestore.v1.Value m = + input.readMessage(com.google.firestore.v1.Value.parser(), extensionRegistry); + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(m); + } else { + argsBuilder_.addMessage(m); + } + break; + } // case 18 + case 26: + { + com.google.protobuf.MapEntry + options__ = + input.readMessage( + OptionsDefaultEntryHolder.defaultEntry.getParserForType(), + extensionRegistry); + internalGetMutableOptions() + .ensureBuilderMap() + .put(options__.getKey(), options__.getValue()); + bitField0_ |= 0x00000004; + break; + } // case 26 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private java.lang.Object name_ = ""; + /** + * + * + *
+       * The name of the stage to evaluate.
+       *
+       * **Requires:**
+       *
+       * * must be in snake case (lower case with underscore separator).
+       * 
+ * + * string name = 1; + * + * @return The name. + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+       * The name of the stage to evaluate.
+       *
+       * **Requires:**
+       *
+       * * must be in snake case (lower case with underscore separator).
+       * 
+ * + * string name = 1; + * + * @return The bytes for name. + */ + public com.google.protobuf.ByteString getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+       * The name of the stage to evaluate.
+       *
+       * **Requires:**
+       *
+       * * must be in snake case (lower case with underscore separator).
+       * 
+ * + * string name = 1; + * + * @param value The name to set. + * @return This builder for chaining. + */ + public Builder setName(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+       * The name of the stage to evaluate.
+       *
+       * **Requires:**
+       *
+       * * must be in snake case (lower case with underscore separator).
+       * 
+ * + * string name = 1; + * + * @return This builder for chaining. + */ + public Builder clearName() { + name_ = getDefaultInstance().getName(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * + * + *
+       * The name of the stage to evaluate.
+       *
+       * **Requires:**
+       *
+       * * must be in snake case (lower case with underscore separator).
+       * 
+ * + * string name = 1; + * + * @param value The bytes for name to set. + * @return This builder for chaining. + */ + public Builder setNameBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + name_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + + private java.util.List args_ = + java.util.Collections.emptyList(); + + private void ensureArgsIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + args_ = new java.util.ArrayList(args_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder> + argsBuilder_; + + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List getArgsList() { + if (argsBuilder_ == null) { + return java.util.Collections.unmodifiableList(args_); + } else { + return argsBuilder_.getMessageList(); + } + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public int getArgsCount() { + if (argsBuilder_ == null) { + return args_.size(); + } else { + return argsBuilder_.getCount(); + } + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value getArgs(int index) { + if (argsBuilder_ == null) { + return args_.get(index); + } else { + return argsBuilder_.getMessage(index); + } + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder setArgs(int index, com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.set(index, value); + onChanged(); + } else { + argsBuilder_.setMessage(index, value); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder setArgs(int index, com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.set(index, builderForValue.build()); + onChanged(); + } else { + argsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.add(value); + onChanged(); + } else { + argsBuilder_.addMessage(value); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(int index, com.google.firestore.v1.Value value) { + if (argsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureArgsIsMutable(); + args_.add(index, value); + onChanged(); + } else { + argsBuilder_.addMessage(index, value); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(builderForValue.build()); + onChanged(); + } else { + argsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addArgs(int index, com.google.firestore.v1.Value.Builder builderForValue) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.add(index, builderForValue.build()); + onChanged(); + } else { + argsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder addAllArgs( + java.lang.Iterable values) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll(values, args_); + onChanged(); + } else { + argsBuilder_.addAllMessages(values); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder clearArgs() { + if (argsBuilder_ == null) { + args_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + argsBuilder_.clear(); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public Builder removeArgs(int index) { + if (argsBuilder_ == null) { + ensureArgsIsMutable(); + args_.remove(index); + onChanged(); + } else { + argsBuilder_.remove(index); + } + return this; + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder getArgsBuilder(int index) { + return getArgsFieldBuilder().getBuilder(index); + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.ValueOrBuilder getArgsOrBuilder(int index) { + if (argsBuilder_ == null) { + return args_.get(index); + } else { + return argsBuilder_.getMessageOrBuilder(index); + } + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List + getArgsOrBuilderList() { + if (argsBuilder_ != null) { + return argsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(args_); + } + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder addArgsBuilder() { + return getArgsFieldBuilder().addBuilder(com.google.firestore.v1.Value.getDefaultInstance()); + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public com.google.firestore.v1.Value.Builder addArgsBuilder(int index) { + return getArgsFieldBuilder() + .addBuilder(index, com.google.firestore.v1.Value.getDefaultInstance()); + } + /** + * + * + *
+       * Ordered list of arguments the given stage expects.
+       * 
+ * + * repeated .google.firestore.v1.Value args = 2; + */ + public java.util.List getArgsBuilderList() { + return getArgsFieldBuilder().getBuilderList(); + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder> + getArgsFieldBuilder() { + if (argsBuilder_ == null) { + argsBuilder_ = + new com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder, + com.google.firestore.v1.ValueOrBuilder>( + args_, ((bitField0_ & 0x00000002) != 0), getParentForChildren(), isClean()); + args_ = null; + } + return argsBuilder_; + } + + private static final class OptionsConverter + implements com.google.protobuf.MapFieldBuilder.Converter< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value> { + @java.lang.Override + public com.google.firestore.v1.Value build(com.google.firestore.v1.ValueOrBuilder val) { + if (val instanceof com.google.firestore.v1.Value) { + return (com.google.firestore.v1.Value) val; + } + return ((com.google.firestore.v1.Value.Builder) val).build(); + } + + @java.lang.Override + public com.google.protobuf.MapEntry + defaultEntry() { + return OptionsDefaultEntryHolder.defaultEntry; + } + }; + + private static final OptionsConverter optionsConverter = new OptionsConverter(); + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + options_; + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetOptions() { + if (options_ == null) { + return new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + return options_; + } + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetMutableOptions() { + if (options_ == null) { + options_ = new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + bitField0_ |= 0x00000004; + onChanged(); + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().ensureBuilderMap().size(); + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().ensureBuilderMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getImmutableMap(); + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + return map.containsKey(key) ? optionsConverter.build(map.get(key)) : defaultValue; + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return optionsConverter.build(map.get(key)); + } + + public Builder clearOptions() { + bitField0_ = (bitField0_ & ~0x00000004); + internalGetMutableOptions().clear(); + return this; + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder removeOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + internalGetMutableOptions().ensureBuilderMap().remove(key); + return this; + } + /** Use alternate mutation accessors instead. */ + @java.lang.Deprecated + public java.util.Map getMutableOptions() { + bitField0_ |= 0x00000004; + return internalGetMutableOptions().ensureMessageMap(); + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder putOptions(java.lang.String key, com.google.firestore.v1.Value value) { + if (key == null) { + throw new NullPointerException("map key"); + } + if (value == null) { + throw new NullPointerException("map value"); + } + internalGetMutableOptions().ensureBuilderMap().put(key, value); + bitField0_ |= 0x00000004; + return this; + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public Builder putAllOptions( + java.util.Map values) { + for (java.util.Map.Entry e : + values.entrySet()) { + if (e.getKey() == null || e.getValue() == null) { + throw new NullPointerException(); + } + } + internalGetMutableOptions().ensureBuilderMap().putAll(values); + bitField0_ |= 0x00000004; + return this; + } + /** + * + * + *
+       * Optional named arguments that certain functions may support.
+       * 
+ * + * map<string, .google.firestore.v1.Value> options = 3; + */ + public com.google.firestore.v1.Value.Builder putOptionsBuilderIfAbsent(java.lang.String key) { + java.util.Map builderMap = + internalGetMutableOptions().ensureBuilderMap(); + com.google.firestore.v1.ValueOrBuilder entry = builderMap.get(key); + if (entry == null) { + entry = com.google.firestore.v1.Value.newBuilder(); + builderMap.put(key, entry); + } + if (entry instanceof com.google.firestore.v1.Value) { + entry = ((com.google.firestore.v1.Value) entry).toBuilder(); + builderMap.put(key, entry); + } + return (com.google.firestore.v1.Value.Builder) entry; + } + + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.Pipeline.Stage) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.Pipeline.Stage) + private static final com.google.firestore.v1.Pipeline.Stage DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.Pipeline.Stage(); + } + + public static com.google.firestore.v1.Pipeline.Stage getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Stage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException() + .setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline.Stage getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + } + + public static final int STAGES_FIELD_NUMBER = 1; + + @SuppressWarnings("serial") + private java.util.List stages_; + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + @java.lang.Override + public java.util.List getStagesList() { + return stages_; + } + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + @java.lang.Override + public java.util.List + getStagesOrBuilderList() { + return stages_; + } + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + @java.lang.Override + public int getStagesCount() { + return stages_.size(); + } + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + @java.lang.Override + public com.google.firestore.v1.Pipeline.Stage getStages(int index) { + return stages_.get(index); + } + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + @java.lang.Override + public com.google.firestore.v1.Pipeline.StageOrBuilder getStagesOrBuilder(int index) { + return stages_.get(index); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + for (int i = 0; i < stages_.size(); i++) { + output.writeMessage(1, stages_.get(i)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < stages_.size(); i++) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(1, stages_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.Pipeline)) { + return super.equals(obj); + } + com.google.firestore.v1.Pipeline other = (com.google.firestore.v1.Pipeline) obj; + + if (!getStagesList().equals(other.getStagesList())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getStagesCount() > 0) { + hash = (37 * hash) + STAGES_FIELD_NUMBER; + hash = (53 * hash) + getStagesList().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.Pipeline parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline parseFrom(com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.Pipeline parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.Pipeline prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * A Firestore query represented as an ordered list of operations / stages.
+   * 
+ * + * Protobuf type {@code google.firestore.v1.Pipeline} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.Pipeline) + com.google.firestore.v1.PipelineOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.Pipeline.class, + com.google.firestore.v1.Pipeline.Builder.class); + } + + // Construct using com.google.firestore.v1.Pipeline.newBuilder() + private Builder() {} + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + if (stagesBuilder_ == null) { + stages_ = java.util.Collections.emptyList(); + } else { + stages_ = null; + stagesBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.DocumentProto + .internal_static_google_firestore_v1_Pipeline_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline getDefaultInstanceForType() { + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline build() { + com.google.firestore.v1.Pipeline result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline buildPartial() { + com.google.firestore.v1.Pipeline result = new com.google.firestore.v1.Pipeline(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(com.google.firestore.v1.Pipeline result) { + if (stagesBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + stages_ = java.util.Collections.unmodifiableList(stages_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.stages_ = stages_; + } else { + result.stages_ = stagesBuilder_.build(); + } + } + + private void buildPartial0(com.google.firestore.v1.Pipeline result) { + int from_bitField0_ = bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.Pipeline) { + return mergeFrom((com.google.firestore.v1.Pipeline) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.Pipeline other) { + if (other == com.google.firestore.v1.Pipeline.getDefaultInstance()) return this; + if (stagesBuilder_ == null) { + if (!other.stages_.isEmpty()) { + if (stages_.isEmpty()) { + stages_ = other.stages_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureStagesIsMutable(); + stages_.addAll(other.stages_); + } + onChanged(); + } + } else { + if (!other.stages_.isEmpty()) { + if (stagesBuilder_.isEmpty()) { + stagesBuilder_.dispose(); + stagesBuilder_ = null; + stages_ = other.stages_; + bitField0_ = (bitField0_ & ~0x00000001); + stagesBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders + ? getStagesFieldBuilder() + : null; + } else { + stagesBuilder_.addAllMessages(other.stages_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + com.google.firestore.v1.Pipeline.Stage m = + input.readMessage( + com.google.firestore.v1.Pipeline.Stage.parser(), extensionRegistry); + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + stages_.add(m); + } else { + stagesBuilder_.addMessage(m); + } + break; + } // case 10 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private java.util.List stages_ = + java.util.Collections.emptyList(); + + private void ensureStagesIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + stages_ = new java.util.ArrayList(stages_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Pipeline.Stage, + com.google.firestore.v1.Pipeline.Stage.Builder, + com.google.firestore.v1.Pipeline.StageOrBuilder> + stagesBuilder_; + + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public java.util.List getStagesList() { + if (stagesBuilder_ == null) { + return java.util.Collections.unmodifiableList(stages_); + } else { + return stagesBuilder_.getMessageList(); + } + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public int getStagesCount() { + if (stagesBuilder_ == null) { + return stages_.size(); + } else { + return stagesBuilder_.getCount(); + } + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public com.google.firestore.v1.Pipeline.Stage getStages(int index) { + if (stagesBuilder_ == null) { + return stages_.get(index); + } else { + return stagesBuilder_.getMessage(index); + } + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder setStages(int index, com.google.firestore.v1.Pipeline.Stage value) { + if (stagesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStagesIsMutable(); + stages_.set(index, value); + onChanged(); + } else { + stagesBuilder_.setMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder setStages( + int index, com.google.firestore.v1.Pipeline.Stage.Builder builderForValue) { + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + stages_.set(index, builderForValue.build()); + onChanged(); + } else { + stagesBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder addStages(com.google.firestore.v1.Pipeline.Stage value) { + if (stagesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStagesIsMutable(); + stages_.add(value); + onChanged(); + } else { + stagesBuilder_.addMessage(value); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder addStages(int index, com.google.firestore.v1.Pipeline.Stage value) { + if (stagesBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureStagesIsMutable(); + stages_.add(index, value); + onChanged(); + } else { + stagesBuilder_.addMessage(index, value); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder addStages(com.google.firestore.v1.Pipeline.Stage.Builder builderForValue) { + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + stages_.add(builderForValue.build()); + onChanged(); + } else { + stagesBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder addStages( + int index, com.google.firestore.v1.Pipeline.Stage.Builder builderForValue) { + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + stages_.add(index, builderForValue.build()); + onChanged(); + } else { + stagesBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder addAllStages( + java.lang.Iterable values) { + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll(values, stages_); + onChanged(); + } else { + stagesBuilder_.addAllMessages(values); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder clearStages() { + if (stagesBuilder_ == null) { + stages_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + stagesBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public Builder removeStages(int index) { + if (stagesBuilder_ == null) { + ensureStagesIsMutable(); + stages_.remove(index); + onChanged(); + } else { + stagesBuilder_.remove(index); + } + return this; + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public com.google.firestore.v1.Pipeline.Stage.Builder getStagesBuilder(int index) { + return getStagesFieldBuilder().getBuilder(index); + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public com.google.firestore.v1.Pipeline.StageOrBuilder getStagesOrBuilder(int index) { + if (stagesBuilder_ == null) { + return stages_.get(index); + } else { + return stagesBuilder_.getMessageOrBuilder(index); + } + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public java.util.List + getStagesOrBuilderList() { + if (stagesBuilder_ != null) { + return stagesBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(stages_); + } + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public com.google.firestore.v1.Pipeline.Stage.Builder addStagesBuilder() { + return getStagesFieldBuilder() + .addBuilder(com.google.firestore.v1.Pipeline.Stage.getDefaultInstance()); + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public com.google.firestore.v1.Pipeline.Stage.Builder addStagesBuilder(int index) { + return getStagesFieldBuilder() + .addBuilder(index, com.google.firestore.v1.Pipeline.Stage.getDefaultInstance()); + } + /** + * + * + *
+     * Ordered list of stages to evaluate.
+     * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + public java.util.List getStagesBuilderList() { + return getStagesFieldBuilder().getBuilderList(); + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Pipeline.Stage, + com.google.firestore.v1.Pipeline.Stage.Builder, + com.google.firestore.v1.Pipeline.StageOrBuilder> + getStagesFieldBuilder() { + if (stagesBuilder_ == null) { + stagesBuilder_ = + new com.google.protobuf.RepeatedFieldBuilderV3< + com.google.firestore.v1.Pipeline.Stage, + com.google.firestore.v1.Pipeline.Stage.Builder, + com.google.firestore.v1.Pipeline.StageOrBuilder>( + stages_, ((bitField0_ & 0x00000001) != 0), getParentForChildren(), isClean()); + stages_ = null; + } + return stagesBuilder_; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.Pipeline) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.Pipeline) + private static final com.google.firestore.v1.Pipeline DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.Pipeline(); + } + + public static com.google.firestore.v1.Pipeline getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Pipeline parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.Pipeline getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineOrBuilder.java new file mode 100644 index 000000000..3373b5e73 --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineOrBuilder.java @@ -0,0 +1,78 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/document.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public interface PipelineOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.Pipeline) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + java.util.List getStagesList(); + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + com.google.firestore.v1.Pipeline.Stage getStages(int index); + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + int getStagesCount(); + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + java.util.List + getStagesOrBuilderList(); + /** + * + * + *
+   * Ordered list of stages to evaluate.
+   * 
+ * + * repeated .google.firestore.v1.Pipeline.Stage stages = 1; + */ + com.google.firestore.v1.Pipeline.StageOrBuilder getStagesOrBuilder(int index); +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineProto.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineProto.java new file mode 100644 index 000000000..816d3fe3f --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PipelineProto.java @@ -0,0 +1,87 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/pipeline.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public final class PipelineProto { + private PipelineProto() {} + + public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {} + + public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry); + } + + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_StructuredPipeline_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_StructuredPipeline_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_descriptor; + static final com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + return descriptor; + } + + private static com.google.protobuf.Descriptors.FileDescriptor descriptor; + + static { + java.lang.String[] descriptorData = { + "\n\"google/firestore/v1/pipeline.proto\022\023go" + + "ogle.firestore.v1\032\"google/firestore/v1/d" + + "ocument.proto\"\330\001\n\022StructuredPipeline\022/\n\010" + + "pipeline\030\001 \001(\0132\035.google.firestore.v1.Pip" + + "eline\022E\n\007options\030\002 \003(\01324.google.firestor" + + "e.v1.StructuredPipeline.OptionsEntry\032J\n\014" + + "OptionsEntry\022\013\n\003key\030\001 \001(\t\022)\n\005value\030\002 \001(\013" + + "2\032.google.firestore.v1.Value:\0028\001B\210\001\n\027com" + + ".google.firestore.v1B\rPipelineProtoP\001\242\002\004" + + "GCFS\252\002\031Google.Cloud.Firestore.V1\312\002\031Googl" + + "e\\Cloud\\Firestore\\V1\352\002\034Google::Cloud::Fi" + + "restore::V1b\006proto3" + }; + descriptor = + com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( + descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.firestore.v1.DocumentProto.getDescriptor(), + }); + internal_static_google_firestore_v1_StructuredPipeline_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_google_firestore_v1_StructuredPipeline_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_StructuredPipeline_descriptor, + new java.lang.String[] { + "Pipeline", "Options", + }); + internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_descriptor = + internal_static_google_firestore_v1_StructuredPipeline_descriptor.getNestedTypes().get(0); + internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_fieldAccessorTable = + new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_descriptor, + new java.lang.String[] { + "Key", "Value", + }); + com.google.firestore.v1.DocumentProto.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummary.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummary.java index 0c7bf4202..43bafcd6f 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummary.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummary.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; /** diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummaryOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummaryOrBuilder.java index 9bdf339a9..4f3c0d8f3 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummaryOrBuilder.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/PlanSummaryOrBuilder.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public interface PlanSummaryOrBuilder diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/QueryProfileProto.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/QueryProfileProto.java index a58b1aa00..e1195e5d7 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/QueryProfileProto.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/QueryProfileProto.java @@ -16,7 +16,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/firestore/v1/query_profile.proto -// Protobuf Java Version: 3.25.3 +// Protobuf Java Version: 3.25.2 package com.google.firestore.v1; public final class QueryProfileProto { diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipeline.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipeline.java new file mode 100644 index 000000000..860bd4e1c --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipeline.java @@ -0,0 +1,1177 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/pipeline.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +/** + * + * + *
+ * A Firestore query represented as an ordered list of operations / stages.
+ *
+ * This is considered the top-level function which plans & executes a query.
+ * It is logically equivalent to `query(stages, options)`, but prevents the
+ * client from having to build a function wrapper.
+ * 
+ * + * Protobuf type {@code google.firestore.v1.StructuredPipeline} + */ +public final class StructuredPipeline extends com.google.protobuf.GeneratedMessageV3 + implements + // @@protoc_insertion_point(message_implements:google.firestore.v1.StructuredPipeline) + StructuredPipelineOrBuilder { + private static final long serialVersionUID = 0L; + // Use StructuredPipeline.newBuilder() to construct. + private StructuredPipeline(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + + private StructuredPipeline() {} + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance(UnusedPrivateParameter unused) { + return new StructuredPipeline(); + } + + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @java.lang.Override + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 2: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.StructuredPipeline.class, + com.google.firestore.v1.StructuredPipeline.Builder.class); + } + + private int bitField0_; + public static final int PIPELINE_FIELD_NUMBER = 1; + private com.google.firestore.v1.Pipeline pipeline_; + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return Whether the pipeline field is set. + */ + @java.lang.Override + public boolean hasPipeline() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return The pipeline. + */ + @java.lang.Override + public com.google.firestore.v1.Pipeline getPipeline() { + return pipeline_ == null ? com.google.firestore.v1.Pipeline.getDefaultInstance() : pipeline_; + } + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + @java.lang.Override + public com.google.firestore.v1.PipelineOrBuilder getPipelineOrBuilder() { + return pipeline_ == null ? com.google.firestore.v1.Pipeline.getDefaultInstance() : pipeline_; + } + + public static final int OPTIONS_FIELD_NUMBER = 2; + + private static final class OptionsDefaultEntryHolder { + static final com.google.protobuf.MapEntry + defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_OptionsEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.MESSAGE, + com.google.firestore.v1.Value.getDefaultInstance()); + } + + @SuppressWarnings("serial") + private com.google.protobuf.MapField options_; + + private com.google.protobuf.MapField + internalGetOptions() { + if (options_ == null) { + return com.google.protobuf.MapField.emptyMapField(OptionsDefaultEntryHolder.defaultEntry); + } + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().getMap().size(); + } + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().getMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getMap(); + } + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetOptions().getMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return map.get(key); + } + + private byte memoizedIsInitialized = -1; + + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeMessage(1, getPipeline()); + } + com.google.protobuf.GeneratedMessageV3.serializeStringMapTo( + output, internalGetOptions(), OptionsDefaultEntryHolder.defaultEntry, 2); + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream.computeMessageSize(1, getPipeline()); + } + for (java.util.Map.Entry entry : + internalGetOptions().getMap().entrySet()) { + com.google.protobuf.MapEntry options__ = + OptionsDefaultEntryHolder.defaultEntry + .newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream.computeMessageSize(2, options__); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.google.firestore.v1.StructuredPipeline)) { + return super.equals(obj); + } + com.google.firestore.v1.StructuredPipeline other = + (com.google.firestore.v1.StructuredPipeline) obj; + + if (hasPipeline() != other.hasPipeline()) return false; + if (hasPipeline()) { + if (!getPipeline().equals(other.getPipeline())) return false; + } + if (!internalGetOptions().equals(other.internalGetOptions())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasPipeline()) { + hash = (37 * hash) + PIPELINE_FIELD_NUMBER; + hash = (53 * hash) + getPipeline().hashCode(); + } + if (!internalGetOptions().getMap().isEmpty()) { + hash = (37 * hash) + OPTIONS_FIELD_NUMBER; + hash = (53 * hash) + internalGetOptions().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom(java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.StructuredPipeline parseDelimitedFrom( + java.io.InputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.StructuredPipeline parseDelimitedFrom( + java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException( + PARSER, input, extensionRegistry); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + com.google.protobuf.CodedInputStream input) throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input); + } + + public static com.google.firestore.v1.StructuredPipeline parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3.parseWithIOException( + PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { + return newBuilder(); + } + + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + + public static Builder newBuilder(com.google.firestore.v1.StructuredPipeline prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * + * + *
+   * A Firestore query represented as an ordered list of operations / stages.
+   *
+   * This is considered the top-level function which plans & executes a query.
+   * It is logically equivalent to `query(stages, options)`, but prevents the
+   * client from having to build a function wrapper.
+   * 
+ * + * Protobuf type {@code google.firestore.v1.StructuredPipeline} + */ + public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder + implements + // @@protoc_insertion_point(builder_implements:google.firestore.v1.StructuredPipeline) + com.google.firestore.v1.StructuredPipelineOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { + return com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldReflection( + int number) { + switch (number) { + case 2: + return internalGetOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapFieldReflectionAccessor internalGetMutableMapFieldReflection( + int number) { + switch (number) { + case 2: + return internalGetMutableOptions(); + default: + throw new RuntimeException("Invalid map field number: " + number); + } + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.google.firestore.v1.StructuredPipeline.class, + com.google.firestore.v1.StructuredPipeline.Builder.class); + } + + // Construct using com.google.firestore.v1.StructuredPipeline.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders) { + getPipelineFieldBuilder(); + } + } + + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + pipeline_ = null; + if (pipelineBuilder_ != null) { + pipelineBuilder_.dispose(); + pipelineBuilder_ = null; + } + internalGetMutableOptions().clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { + return com.google.firestore.v1.PipelineProto + .internal_static_google_firestore_v1_StructuredPipeline_descriptor; + } + + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline getDefaultInstanceForType() { + return com.google.firestore.v1.StructuredPipeline.getDefaultInstance(); + } + + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline build() { + com.google.firestore.v1.StructuredPipeline result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline buildPartial() { + com.google.firestore.v1.StructuredPipeline result = + new com.google.firestore.v1.StructuredPipeline(this); + if (bitField0_ != 0) { + buildPartial0(result); + } + onBuilt(); + return result; + } + + private void buildPartial0(com.google.firestore.v1.StructuredPipeline result) { + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.pipeline_ = pipelineBuilder_ == null ? pipeline_ : pipelineBuilder_.build(); + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.options_ = internalGetOptions().build(OptionsDefaultEntryHolder.defaultEntry); + } + result.bitField0_ |= to_bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.setField(field, value); + } + + @java.lang.Override + public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + + @java.lang.Override + public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) { + return super.addRepeatedField(field, value); + } + + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.google.firestore.v1.StructuredPipeline) { + return mergeFrom((com.google.firestore.v1.StructuredPipeline) other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.google.firestore.v1.StructuredPipeline other) { + if (other == com.google.firestore.v1.StructuredPipeline.getDefaultInstance()) return this; + if (other.hasPipeline()) { + mergePipeline(other.getPipeline()); + } + internalGetMutableOptions().mergeFrom(other.internalGetOptions()); + bitField0_ |= 0x00000002; + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: + { + input.readMessage(getPipelineFieldBuilder().getBuilder(), extensionRegistry); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: + { + com.google.protobuf.MapEntry + options__ = + input.readMessage( + OptionsDefaultEntryHolder.defaultEntry.getParserForType(), + extensionRegistry); + internalGetMutableOptions() + .ensureBuilderMap() + .put(options__.getKey(), options__.getValue()); + bitField0_ |= 0x00000002; + break; + } // case 18 + default: + { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + + private int bitField0_; + + private com.google.firestore.v1.Pipeline pipeline_; + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder> + pipelineBuilder_; + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return Whether the pipeline field is set. + */ + public boolean hasPipeline() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return The pipeline. + */ + public com.google.firestore.v1.Pipeline getPipeline() { + if (pipelineBuilder_ == null) { + return pipeline_ == null + ? com.google.firestore.v1.Pipeline.getDefaultInstance() + : pipeline_; + } else { + return pipelineBuilder_.getMessage(); + } + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public Builder setPipeline(com.google.firestore.v1.Pipeline value) { + if (pipelineBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + pipeline_ = value; + } else { + pipelineBuilder_.setMessage(value); + } + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public Builder setPipeline(com.google.firestore.v1.Pipeline.Builder builderForValue) { + if (pipelineBuilder_ == null) { + pipeline_ = builderForValue.build(); + } else { + pipelineBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public Builder mergePipeline(com.google.firestore.v1.Pipeline value) { + if (pipelineBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0) + && pipeline_ != null + && pipeline_ != com.google.firestore.v1.Pipeline.getDefaultInstance()) { + getPipelineBuilder().mergeFrom(value); + } else { + pipeline_ = value; + } + } else { + pipelineBuilder_.mergeFrom(value); + } + if (pipeline_ != null) { + bitField0_ |= 0x00000001; + onChanged(); + } + return this; + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public Builder clearPipeline() { + bitField0_ = (bitField0_ & ~0x00000001); + pipeline_ = null; + if (pipelineBuilder_ != null) { + pipelineBuilder_.dispose(); + pipelineBuilder_ = null; + } + onChanged(); + return this; + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public com.google.firestore.v1.Pipeline.Builder getPipelineBuilder() { + bitField0_ |= 0x00000001; + onChanged(); + return getPipelineFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + public com.google.firestore.v1.PipelineOrBuilder getPipelineOrBuilder() { + if (pipelineBuilder_ != null) { + return pipelineBuilder_.getMessageOrBuilder(); + } else { + return pipeline_ == null + ? com.google.firestore.v1.Pipeline.getDefaultInstance() + : pipeline_; + } + } + /** + * + * + *
+     * The pipeline query to execute.
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder> + getPipelineFieldBuilder() { + if (pipelineBuilder_ == null) { + pipelineBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder>( + getPipeline(), getParentForChildren(), isClean()); + pipeline_ = null; + } + return pipelineBuilder_; + } + + private static final class OptionsConverter + implements com.google.protobuf.MapFieldBuilder.Converter< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value> { + @java.lang.Override + public com.google.firestore.v1.Value build(com.google.firestore.v1.ValueOrBuilder val) { + if (val instanceof com.google.firestore.v1.Value) { + return (com.google.firestore.v1.Value) val; + } + return ((com.google.firestore.v1.Value.Builder) val).build(); + } + + @java.lang.Override + public com.google.protobuf.MapEntry + defaultEntry() { + return OptionsDefaultEntryHolder.defaultEntry; + } + }; + + private static final OptionsConverter optionsConverter = new OptionsConverter(); + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + options_; + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetOptions() { + if (options_ == null) { + return new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + return options_; + } + + private com.google.protobuf.MapFieldBuilder< + java.lang.String, + com.google.firestore.v1.ValueOrBuilder, + com.google.firestore.v1.Value, + com.google.firestore.v1.Value.Builder> + internalGetMutableOptions() { + if (options_ == null) { + options_ = new com.google.protobuf.MapFieldBuilder<>(optionsConverter); + } + bitField0_ |= 0x00000002; + onChanged(); + return options_; + } + + public int getOptionsCount() { + return internalGetOptions().ensureBuilderMap().size(); + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public boolean containsOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + return internalGetOptions().ensureBuilderMap().containsKey(key); + } + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Override + @java.lang.Deprecated + public java.util.Map getOptions() { + return getOptionsMap(); + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public java.util.Map getOptionsMap() { + return internalGetOptions().getImmutableMap(); + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public /* nullable */ com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + return map.containsKey(key) ? optionsConverter.build(map.get(key)) : defaultValue; + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + @java.lang.Override + public com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + java.util.Map map = + internalGetMutableOptions().ensureBuilderMap(); + if (!map.containsKey(key)) { + throw new java.lang.IllegalArgumentException(); + } + return optionsConverter.build(map.get(key)); + } + + public Builder clearOptions() { + bitField0_ = (bitField0_ & ~0x00000002); + internalGetMutableOptions().clear(); + return this; + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + public Builder removeOptions(java.lang.String key) { + if (key == null) { + throw new NullPointerException("map key"); + } + internalGetMutableOptions().ensureBuilderMap().remove(key); + return this; + } + /** Use alternate mutation accessors instead. */ + @java.lang.Deprecated + public java.util.Map getMutableOptions() { + bitField0_ |= 0x00000002; + return internalGetMutableOptions().ensureMessageMap(); + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + public Builder putOptions(java.lang.String key, com.google.firestore.v1.Value value) { + if (key == null) { + throw new NullPointerException("map key"); + } + if (value == null) { + throw new NullPointerException("map value"); + } + internalGetMutableOptions().ensureBuilderMap().put(key, value); + bitField0_ |= 0x00000002; + return this; + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + public Builder putAllOptions( + java.util.Map values) { + for (java.util.Map.Entry e : + values.entrySet()) { + if (e.getKey() == null || e.getValue() == null) { + throw new NullPointerException(); + } + } + internalGetMutableOptions().ensureBuilderMap().putAll(values); + bitField0_ |= 0x00000002; + return this; + } + /** + * + * + *
+     * Optional query-level arguments.
+     *
+     * (-- Think query statement hints. --)
+     *
+     * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+     * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + public com.google.firestore.v1.Value.Builder putOptionsBuilderIfAbsent(java.lang.String key) { + java.util.Map builderMap = + internalGetMutableOptions().ensureBuilderMap(); + com.google.firestore.v1.ValueOrBuilder entry = builderMap.get(key); + if (entry == null) { + entry = com.google.firestore.v1.Value.newBuilder(); + builderMap.put(key, entry); + } + if (entry instanceof com.google.firestore.v1.Value) { + entry = ((com.google.firestore.v1.Value) entry).toBuilder(); + builderMap.put(key, entry); + } + return (com.google.firestore.v1.Value.Builder) entry; + } + + @java.lang.Override + public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + // @@protoc_insertion_point(builder_scope:google.firestore.v1.StructuredPipeline) + } + + // @@protoc_insertion_point(class_scope:google.firestore.v1.StructuredPipeline) + private static final com.google.firestore.v1.StructuredPipeline DEFAULT_INSTANCE; + + static { + DEFAULT_INSTANCE = new com.google.firestore.v1.StructuredPipeline(); + } + + public static com.google.firestore.v1.StructuredPipeline getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + @java.lang.Override + public StructuredPipeline parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.google.firestore.v1.StructuredPipeline getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipelineOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipelineOrBuilder.java new file mode 100644 index 000000000..b6e1c59c1 --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/StructuredPipelineOrBuilder.java @@ -0,0 +1,139 @@ +/* + * Copyright 2024 Google LLC + * + * 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 + * + * https://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. + */ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/pipeline.proto + +// Protobuf Java Version: 3.25.2 +package com.google.firestore.v1; + +public interface StructuredPipelineOrBuilder + extends + // @@protoc_insertion_point(interface_extends:google.firestore.v1.StructuredPipeline) + com.google.protobuf.MessageOrBuilder { + + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return Whether the pipeline field is set. + */ + boolean hasPipeline(); + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + * + * @return The pipeline. + */ + com.google.firestore.v1.Pipeline getPipeline(); + /** + * + * + *
+   * The pipeline query to execute.
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline = 1; + */ + com.google.firestore.v1.PipelineOrBuilder getPipelineOrBuilder(); + + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + int getOptionsCount(); + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + boolean containsOptions(java.lang.String key); + /** Use {@link #getOptionsMap()} instead. */ + @java.lang.Deprecated + java.util.Map getOptions(); + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + java.util.Map getOptionsMap(); + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + /* nullable */ + com.google.firestore.v1.Value getOptionsOrDefault( + java.lang.String key, + /* nullable */ + com.google.firestore.v1.Value defaultValue); + /** + * + * + *
+   * Optional query-level arguments.
+   *
+   * (-- Think query statement hints. --)
+   *
+   * (-- TODO(batchik): define the api contract of using an unsupported hint --)
+   * 
+ * + * map<string, .google.firestore.v1.Value> options = 2; + */ + com.google.firestore.v1.Value getOptionsOrThrow(java.lang.String key); +} diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Value.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Value.java index 378e89748..1e7f93b7b 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Value.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/Value.java @@ -80,6 +80,9 @@ public enum ValueTypeCase GEO_POINT_VALUE(8), ARRAY_VALUE(9), MAP_VALUE(6), + FIELD_REFERENCE_VALUE(19), + FUNCTION_VALUE(20), + PIPELINE_VALUE(21), VALUETYPE_NOT_SET(0); private final int value; @@ -120,6 +123,12 @@ public static ValueTypeCase forNumber(int value) { return ARRAY_VALUE; case 6: return MAP_VALUE; + case 19: + return FIELD_REFERENCE_VALUE; + case 20: + return FUNCTION_VALUE; + case 21: + return PIPELINE_VALUE; case 0: return VALUETYPE_NOT_SET; default: @@ -711,6 +720,280 @@ public com.google.firestore.v1.MapValueOrBuilder getMapValueOrBuilder() { return com.google.firestore.v1.MapValue.getDefaultInstance(); } + public static final int FIELD_REFERENCE_VALUE_FIELD_NUMBER = 19; + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return Whether the fieldReferenceValue field is set. + */ + public boolean hasFieldReferenceValue() { + return valueTypeCase_ == 19; + } + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return The fieldReferenceValue. + */ + public java.lang.String getFieldReferenceValue() { + java.lang.Object ref = ""; + if (valueTypeCase_ == 19) { + ref = valueType_; + } + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (valueTypeCase_ == 19) { + valueType_ = s; + } + return s; + } + } + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return The bytes for fieldReferenceValue. + */ + public com.google.protobuf.ByteString getFieldReferenceValueBytes() { + java.lang.Object ref = ""; + if (valueTypeCase_ == 19) { + ref = valueType_; + } + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + if (valueTypeCase_ == 19) { + valueType_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int FUNCTION_VALUE_FIELD_NUMBER = 20; + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return Whether the functionValue field is set. + */ + @java.lang.Override + public boolean hasFunctionValue() { + return valueTypeCase_ == 20; + } + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return The functionValue. + */ + @java.lang.Override + public com.google.firestore.v1.Function getFunctionValue() { + if (valueTypeCase_ == 20) { + return (com.google.firestore.v1.Function) valueType_; + } + return com.google.firestore.v1.Function.getDefaultInstance(); + } + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + @java.lang.Override + public com.google.firestore.v1.FunctionOrBuilder getFunctionValueOrBuilder() { + if (valueTypeCase_ == 20) { + return (com.google.firestore.v1.Function) valueType_; + } + return com.google.firestore.v1.Function.getDefaultInstance(); + } + + public static final int PIPELINE_VALUE_FIELD_NUMBER = 21; + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return Whether the pipelineValue field is set. + */ + @java.lang.Override + public boolean hasPipelineValue() { + return valueTypeCase_ == 21; + } + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return The pipelineValue. + */ + @java.lang.Override + public com.google.firestore.v1.Pipeline getPipelineValue() { + if (valueTypeCase_ == 21) { + return (com.google.firestore.v1.Pipeline) valueType_; + } + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + @java.lang.Override + public com.google.firestore.v1.PipelineOrBuilder getPipelineValueOrBuilder() { + if (valueTypeCase_ == 21) { + return (com.google.firestore.v1.Pipeline) valueType_; + } + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; @java.lang.Override @@ -758,6 +1041,15 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io if (valueTypeCase_ == 18) { output.writeBytes(18, (com.google.protobuf.ByteString) valueType_); } + if (valueTypeCase_ == 19) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 19, valueType_); + } + if (valueTypeCase_ == 20) { + output.writeMessage(20, (com.google.firestore.v1.Function) valueType_); + } + if (valueTypeCase_ == 21) { + output.writeMessage(21, (com.google.firestore.v1.Pipeline) valueType_); + } getUnknownFields().writeTo(output); } @@ -818,6 +1110,19 @@ public int getSerializedSize() { com.google.protobuf.CodedOutputStream.computeBytesSize( 18, (com.google.protobuf.ByteString) valueType_); } + if (valueTypeCase_ == 19) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(19, valueType_); + } + if (valueTypeCase_ == 20) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 20, (com.google.firestore.v1.Function) valueType_); + } + if (valueTypeCase_ == 21) { + size += + com.google.protobuf.CodedOutputStream.computeMessageSize( + 21, (com.google.firestore.v1.Pipeline) valueType_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -869,6 +1174,15 @@ public boolean equals(final java.lang.Object obj) { case 6: if (!getMapValue().equals(other.getMapValue())) return false; break; + case 19: + if (!getFieldReferenceValue().equals(other.getFieldReferenceValue())) return false; + break; + case 20: + if (!getFunctionValue().equals(other.getFunctionValue())) return false; + break; + case 21: + if (!getPipelineValue().equals(other.getPipelineValue())) return false; + break; case 0: default: } @@ -931,6 +1245,18 @@ public int hashCode() { hash = (37 * hash) + MAP_VALUE_FIELD_NUMBER; hash = (53 * hash) + getMapValue().hashCode(); break; + case 19: + hash = (37 * hash) + FIELD_REFERENCE_VALUE_FIELD_NUMBER; + hash = (53 * hash) + getFieldReferenceValue().hashCode(); + break; + case 20: + hash = (37 * hash) + FUNCTION_VALUE_FIELD_NUMBER; + hash = (53 * hash) + getFunctionValue().hashCode(); + break; + case 21: + hash = (37 * hash) + PIPELINE_VALUE_FIELD_NUMBER; + hash = (53 * hash) + getPipelineValue().hashCode(); + break; case 0: default: } @@ -1083,6 +1409,12 @@ public Builder clear() { if (mapValueBuilder_ != null) { mapValueBuilder_.clear(); } + if (functionValueBuilder_ != null) { + functionValueBuilder_.clear(); + } + if (pipelineValueBuilder_ != null) { + pipelineValueBuilder_.clear(); + } valueTypeCase_ = 0; valueType_ = null; return this; @@ -1138,6 +1470,12 @@ private void buildPartialOneofs(com.google.firestore.v1.Value result) { if (valueTypeCase_ == 6 && mapValueBuilder_ != null) { result.valueType_ = mapValueBuilder_.build(); } + if (valueTypeCase_ == 20 && functionValueBuilder_ != null) { + result.valueType_ = functionValueBuilder_.build(); + } + if (valueTypeCase_ == 21 && pipelineValueBuilder_ != null) { + result.valueType_ = pipelineValueBuilder_.build(); + } } @java.lang.Override @@ -1245,6 +1583,23 @@ public Builder mergeFrom(com.google.firestore.v1.Value other) { mergeMapValue(other.getMapValue()); break; } + case FIELD_REFERENCE_VALUE: + { + valueTypeCase_ = 19; + valueType_ = other.valueType_; + onChanged(); + break; + } + case FUNCTION_VALUE: + { + mergeFunctionValue(other.getFunctionValue()); + break; + } + case PIPELINE_VALUE: + { + mergePipelineValue(other.getPipelineValue()); + break; + } case VALUETYPE_NOT_SET: { break; @@ -1345,6 +1700,25 @@ public Builder mergeFrom( valueTypeCase_ = 18; break; } // case 146 + case 154: + { + java.lang.String s = input.readStringRequireUtf8(); + valueTypeCase_ = 19; + valueType_ = s; + break; + } // case 154 + case 162: + { + input.readMessage(getFunctionValueFieldBuilder().getBuilder(), extensionRegistry); + valueTypeCase_ = 20; + break; + } // case 162 + case 170: + { + input.readMessage(getPipelineValueFieldBuilder().getBuilder(), extensionRegistry); + valueTypeCase_ = 21; + break; + } // case 170 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { @@ -2953,6 +3327,822 @@ public com.google.firestore.v1.MapValueOrBuilder getMapValueOrBuilder() { return mapValueBuilder_; } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @return Whether the fieldReferenceValue field is set. + */ + @java.lang.Override + public boolean hasFieldReferenceValue() { + return valueTypeCase_ == 19; + } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @return The fieldReferenceValue. + */ + @java.lang.Override + public java.lang.String getFieldReferenceValue() { + java.lang.Object ref = ""; + if (valueTypeCase_ == 19) { + ref = valueType_; + } + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (valueTypeCase_ == 19) { + valueType_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @return The bytes for fieldReferenceValue. + */ + @java.lang.Override + public com.google.protobuf.ByteString getFieldReferenceValueBytes() { + java.lang.Object ref = ""; + if (valueTypeCase_ == 19) { + ref = valueType_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref); + if (valueTypeCase_ == 19) { + valueType_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @param value The fieldReferenceValue to set. + * @return This builder for chaining. + */ + public Builder setFieldReferenceValue(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + valueTypeCase_ = 19; + valueType_ = value; + onChanged(); + return this; + } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @return This builder for chaining. + */ + public Builder clearFieldReferenceValue() { + if (valueTypeCase_ == 19) { + valueTypeCase_ = 0; + valueType_ = null; + onChanged(); + } + return this; + } + /** + * + * + *
+     * Value which references a field.
+     *
+     * This is considered relative (vs absolute) since it only refers to a field
+     * and not a field within a particular document.
+     *
+     * **Requires:**
+     *
+     * * Must follow [field reference][FieldReference.field_path] limitations.
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): long term, there is no reason this type should not be
+     *     allowed to be used on the write path. --)
+     * 
+ * + * string field_reference_value = 19; + * + * @param value The bytes for fieldReferenceValue to set. + * @return This builder for chaining. + */ + public Builder setFieldReferenceValueBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + valueTypeCase_ = 19; + valueType_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Function, + com.google.firestore.v1.Function.Builder, + com.google.firestore.v1.FunctionOrBuilder> + functionValueBuilder_; + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return Whether the functionValue field is set. + */ + @java.lang.Override + public boolean hasFunctionValue() { + return valueTypeCase_ == 20; + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return The functionValue. + */ + @java.lang.Override + public com.google.firestore.v1.Function getFunctionValue() { + if (functionValueBuilder_ == null) { + if (valueTypeCase_ == 20) { + return (com.google.firestore.v1.Function) valueType_; + } + return com.google.firestore.v1.Function.getDefaultInstance(); + } else { + if (valueTypeCase_ == 20) { + return functionValueBuilder_.getMessage(); + } + return com.google.firestore.v1.Function.getDefaultInstance(); + } + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + public Builder setFunctionValue(com.google.firestore.v1.Function value) { + if (functionValueBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + valueType_ = value; + onChanged(); + } else { + functionValueBuilder_.setMessage(value); + } + valueTypeCase_ = 20; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + public Builder setFunctionValue(com.google.firestore.v1.Function.Builder builderForValue) { + if (functionValueBuilder_ == null) { + valueType_ = builderForValue.build(); + onChanged(); + } else { + functionValueBuilder_.setMessage(builderForValue.build()); + } + valueTypeCase_ = 20; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + public Builder mergeFunctionValue(com.google.firestore.v1.Function value) { + if (functionValueBuilder_ == null) { + if (valueTypeCase_ == 20 + && valueType_ != com.google.firestore.v1.Function.getDefaultInstance()) { + valueType_ = + com.google.firestore.v1.Function.newBuilder( + (com.google.firestore.v1.Function) valueType_) + .mergeFrom(value) + .buildPartial(); + } else { + valueType_ = value; + } + onChanged(); + } else { + if (valueTypeCase_ == 20) { + functionValueBuilder_.mergeFrom(value); + } else { + functionValueBuilder_.setMessage(value); + } + } + valueTypeCase_ = 20; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + public Builder clearFunctionValue() { + if (functionValueBuilder_ == null) { + if (valueTypeCase_ == 20) { + valueTypeCase_ = 0; + valueType_ = null; + onChanged(); + } + } else { + if (valueTypeCase_ == 20) { + valueTypeCase_ = 0; + valueType_ = null; + } + functionValueBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + public com.google.firestore.v1.Function.Builder getFunctionValueBuilder() { + return getFunctionValueFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + @java.lang.Override + public com.google.firestore.v1.FunctionOrBuilder getFunctionValueOrBuilder() { + if ((valueTypeCase_ == 20) && (functionValueBuilder_ != null)) { + return functionValueBuilder_.getMessageOrBuilder(); + } else { + if (valueTypeCase_ == 20) { + return (com.google.firestore.v1.Function) valueType_; + } + return com.google.firestore.v1.Function.getDefaultInstance(); + } + } + /** + * + * + *
+     * A value that represents an unevaluated expression.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Function, + com.google.firestore.v1.Function.Builder, + com.google.firestore.v1.FunctionOrBuilder> + getFunctionValueFieldBuilder() { + if (functionValueBuilder_ == null) { + if (!(valueTypeCase_ == 20)) { + valueType_ = com.google.firestore.v1.Function.getDefaultInstance(); + } + functionValueBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Function, + com.google.firestore.v1.Function.Builder, + com.google.firestore.v1.FunctionOrBuilder>( + (com.google.firestore.v1.Function) valueType_, getParentForChildren(), isClean()); + valueType_ = null; + } + valueTypeCase_ = 20; + onChanged(); + return functionValueBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder> + pipelineValueBuilder_; + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return Whether the pipelineValue field is set. + */ + @java.lang.Override + public boolean hasPipelineValue() { + return valueTypeCase_ == 21; + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return The pipelineValue. + */ + @java.lang.Override + public com.google.firestore.v1.Pipeline getPipelineValue() { + if (pipelineValueBuilder_ == null) { + if (valueTypeCase_ == 21) { + return (com.google.firestore.v1.Pipeline) valueType_; + } + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } else { + if (valueTypeCase_ == 21) { + return pipelineValueBuilder_.getMessage(); + } + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + public Builder setPipelineValue(com.google.firestore.v1.Pipeline value) { + if (pipelineValueBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + valueType_ = value; + onChanged(); + } else { + pipelineValueBuilder_.setMessage(value); + } + valueTypeCase_ = 21; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + public Builder setPipelineValue(com.google.firestore.v1.Pipeline.Builder builderForValue) { + if (pipelineValueBuilder_ == null) { + valueType_ = builderForValue.build(); + onChanged(); + } else { + pipelineValueBuilder_.setMessage(builderForValue.build()); + } + valueTypeCase_ = 21; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + public Builder mergePipelineValue(com.google.firestore.v1.Pipeline value) { + if (pipelineValueBuilder_ == null) { + if (valueTypeCase_ == 21 + && valueType_ != com.google.firestore.v1.Pipeline.getDefaultInstance()) { + valueType_ = + com.google.firestore.v1.Pipeline.newBuilder( + (com.google.firestore.v1.Pipeline) valueType_) + .mergeFrom(value) + .buildPartial(); + } else { + valueType_ = value; + } + onChanged(); + } else { + if (valueTypeCase_ == 21) { + pipelineValueBuilder_.mergeFrom(value); + } else { + pipelineValueBuilder_.setMessage(value); + } + } + valueTypeCase_ = 21; + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + public Builder clearPipelineValue() { + if (pipelineValueBuilder_ == null) { + if (valueTypeCase_ == 21) { + valueTypeCase_ = 0; + valueType_ = null; + onChanged(); + } + } else { + if (valueTypeCase_ == 21) { + valueTypeCase_ = 0; + valueType_ = null; + } + pipelineValueBuilder_.clear(); + } + return this; + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + public com.google.firestore.v1.Pipeline.Builder getPipelineValueBuilder() { + return getPipelineValueFieldBuilder().getBuilder(); + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + @java.lang.Override + public com.google.firestore.v1.PipelineOrBuilder getPipelineValueOrBuilder() { + if ((valueTypeCase_ == 21) && (pipelineValueBuilder_ != null)) { + return pipelineValueBuilder_.getMessageOrBuilder(); + } else { + if (valueTypeCase_ == 21) { + return (com.google.firestore.v1.Pipeline) valueType_; + } + return com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + } + /** + * + * + *
+     * A value that represents an unevaluated pipeline.
+     *
+     * **Requires:**
+     *
+     * * Not allowed to be used when writing documents.
+     *
+     * (-- NOTE(batchik): similar to above, there is no reason to not allow
+     *     storing expressions into the database, just no plan to support in
+     *     the near term.
+     *
+     *     This would actually be an interesting way to represent user-defined
+     *     functions or more expressive rules-based systems. --)
+     * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder> + getPipelineValueFieldBuilder() { + if (pipelineValueBuilder_ == null) { + if (!(valueTypeCase_ == 21)) { + valueType_ = com.google.firestore.v1.Pipeline.getDefaultInstance(); + } + pipelineValueBuilder_ = + new com.google.protobuf.SingleFieldBuilderV3< + com.google.firestore.v1.Pipeline, + com.google.firestore.v1.Pipeline.Builder, + com.google.firestore.v1.PipelineOrBuilder>( + (com.google.firestore.v1.Pipeline) valueType_, getParentForChildren(), isClean()); + valueType_ = null; + } + valueTypeCase_ = 21; + onChanged(); + return pipelineValueBuilder_; + } + @java.lang.Override public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) { return super.setUnknownFields(unknownFields); diff --git a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ValueOrBuilder.java b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ValueOrBuilder.java index 560bfba7c..7d492ab7d 100644 --- a/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ValueOrBuilder.java +++ b/proto-google-cloud-firestore-v1/src/main/java/com/google/firestore/v1/ValueOrBuilder.java @@ -414,5 +414,214 @@ public interface ValueOrBuilder */ com.google.firestore.v1.MapValueOrBuilder getMapValueOrBuilder(); + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return Whether the fieldReferenceValue field is set. + */ + boolean hasFieldReferenceValue(); + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return The fieldReferenceValue. + */ + java.lang.String getFieldReferenceValue(); + /** + * + * + *
+   * Value which references a field.
+   *
+   * This is considered relative (vs absolute) since it only refers to a field
+   * and not a field within a particular document.
+   *
+   * **Requires:**
+   *
+   * * Must follow [field reference][FieldReference.field_path] limitations.
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): long term, there is no reason this type should not be
+   *     allowed to be used on the write path. --)
+   * 
+ * + * string field_reference_value = 19; + * + * @return The bytes for fieldReferenceValue. + */ + com.google.protobuf.ByteString getFieldReferenceValueBytes(); + + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return Whether the functionValue field is set. + */ + boolean hasFunctionValue(); + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + * + * @return The functionValue. + */ + com.google.firestore.v1.Function getFunctionValue(); + /** + * + * + *
+   * A value that represents an unevaluated expression.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Function function_value = 20; + */ + com.google.firestore.v1.FunctionOrBuilder getFunctionValueOrBuilder(); + + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return Whether the pipelineValue field is set. + */ + boolean hasPipelineValue(); + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + * + * @return The pipelineValue. + */ + com.google.firestore.v1.Pipeline getPipelineValue(); + /** + * + * + *
+   * A value that represents an unevaluated pipeline.
+   *
+   * **Requires:**
+   *
+   * * Not allowed to be used when writing documents.
+   *
+   * (-- NOTE(batchik): similar to above, there is no reason to not allow
+   *     storing expressions into the database, just no plan to support in
+   *     the near term.
+   *
+   *     This would actually be an interesting way to represent user-defined
+   *     functions or more expressive rules-based systems. --)
+   * 
+ * + * .google.firestore.v1.Pipeline pipeline_value = 21; + */ + com.google.firestore.v1.PipelineOrBuilder getPipelineValueOrBuilder(); + com.google.firestore.v1.Value.ValueTypeCase getValueTypeCase(); } diff --git a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/document.proto b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/document.proto index 5ad6752aa..5348fe643 100644 --- a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/document.proto +++ b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/document.proto @@ -128,6 +128,50 @@ message Value { // A map value. MapValue map_value = 6; + + + // Value which references a field. + // + // This is considered relative (vs absolute) since it only refers to a field + // and not a field within a particular document. + // + // **Requires:** + // + // * Must follow [field reference][FieldReference.field_path] limitations. + // + // * Not allowed to be used when writing documents. + // + // (-- NOTE(batchik): long term, there is no reason this type should not be + // allowed to be used on the write path. --) + string field_reference_value = 19; + + // A value that represents an unevaluated expression. + // + // **Requires:** + // + // * Not allowed to be used when writing documents. + // + // (-- NOTE(batchik): similar to above, there is no reason to not allow + // storing expressions into the database, just no plan to support in + // the near term. + // + // This would actually be an interesting way to represent user-defined + // functions or more expressive rules-based systems. --) + Function function_value = 20; + + // A value that represents an unevaluated pipeline. + // + // **Requires:** + // + // * Not allowed to be used when writing documents. + // + // (-- NOTE(batchik): similar to above, there is no reason to not allow + // storing expressions into the database, just no plan to support in + // the near term. + // + // This would actually be an interesting way to represent user-defined + // functions or more expressive rules-based systems. --) + Pipeline pipeline_value = 21; } } @@ -147,3 +191,73 @@ message MapValue { // not exceed 1,500 bytes and cannot be empty. map fields = 1; } + +// Represents an unevaluated scalar expression. +// +// For example, the expression `like(user_name, "%alice%")` is represented as: +// +// ``` +// name: "like" +// args { field_reference: "user_name" } +// args { string_value: "%alice%" } +// ``` +// +// (-- api-linter: core::0123::resource-annotation=disabled +// aip.dev/not-precedent: this is not a One Platform API resource. --) +message Function { + // The name of the function to evaluate. + // + // **Requires:** + // + // * must be in snake case (lower case with underscore separator). + // + string name = 1; + + // Ordered list of arguments the given function expects. + repeated Value args = 2; + + // Optional named arguments that certain functions may support. + map options = 3; +} + +// A Firestore query represented as an ordered list of operations / stages. +message Pipeline { + // A single operation within a pipeline. + // + // A stage is made up of a unique name, and a list of arguments. The exact + // number of arguments & types is dependent on the stage type. + // + // To give an example, the stage `filter(state = "MD")` would be encoded as: + // + // ``` + // name: "filter" + // args { + // function_value { + // name: "eq" + // args { field_reference_value: "state" } + // args { string_value: "MD" } + // } + // } + // ``` + // + // See public documentation for the full list. + message Stage { + // The name of the stage to evaluate. + // + // **Requires:** + // + // * must be in snake case (lower case with underscore separator). + // + string name = 1; + + // Ordered list of arguments the given stage expects. + repeated Value args = 2; + + // Optional named arguments that certain functions may support. + map options = 3; + } + + // Ordered list of stages to evaluate. + repeated Stage stages = 1; +} + diff --git a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/firestore.proto b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/firestore.proto index 2ed6bf070..f8718bb67 100644 --- a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/firestore.proto +++ b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/firestore.proto @@ -22,6 +22,7 @@ import "google/api/field_behavior.proto"; import "google/firestore/v1/aggregation_result.proto"; import "google/firestore/v1/common.proto"; import "google/firestore/v1/document.proto"; +import "google/firestore/v1/pipeline.proto"; import "google/firestore/v1/query.proto"; import "google/firestore/v1/query_profile.proto"; import "google/firestore/v1/write.proto"; @@ -140,6 +141,15 @@ service Firestore { }; } + // Executes a pipeline query. + rpc ExecutePipeline(ExecutePipelineRequest) + returns (stream ExecutePipelineResponse) { + option (google.api.http) = { + post: "/v1beta1/{database=projects/*/databases/*}:executePipeline" + body: "*" + }; + } + // Runs an aggregation query. // // Rather than producing [Document][google.firestore.v1.Document] results like @@ -624,6 +634,82 @@ message RunQueryResponse { ExplainMetrics explain_metrics = 11; } +// The request for [Firestore.ExecutePipeline][]. +message ExecutePipelineRequest { + // Database identifier, in the form `projects/{project}/databases/{database}`. + string database = 1 [ + (google.api.field_behavior) = REQUIRED + ]; + + oneof pipeline_type { + // A pipelined operation. + StructuredPipeline structured_pipeline = 2; + } + + // Optional consistency arguments, defaults to strong consistency. + oneof consistency_selector { + // Run the query within an already active transaction. + // + // The value here is the opaque transaction ID to execute the query in. + bytes transaction = 5; + + // Execute the pipeline in a new transaction. + // + // The identifier of the newly created transaction will be returned in the + // first response on the stream. This defaults to a read-only transaction. + TransactionOptions new_transaction = 6; + + // Execute the pipeline in a snapshot transaction at the given time. + // + // This must be a microsecond precision timestamp within the past one hour, + // or if Point-in-Time Recovery is enabled, can additionally be a whole + // minute timestamp within the past 7 days. + google.protobuf.Timestamp read_time = 7; + } + + // Explain / analyze options for the pipeline. + // ExplainOptions explain_options = 8 [(google.api.field_behavior) = OPTIONAL]; +} + +// The response for [Firestore.Execute][]. +message ExecutePipelineResponse { + // Newly created transaction identifier. + // + // This field is only specified on the first response from the server when + // the request specified [ExecuteRequest.new_transaction][]. + bytes transaction = 1; + + // An ordered batch of results returned executing a pipeline. + // + // The batch size is variable, and can even be zero for when only a partial + // progress message is returned. + // + // The fields present in the returned documents are only those that were + // explicitly requested in the pipeline, this include those like + // [`__name__`][Document.name] & [`__update_time__`][Document.update_time]. + // This is explicitly a divergence from `Firestore.RunQuery` / + // `Firestore.GetDocument` RPCs which always return such fields even when they + // are not specified in the [`mask`][DocumentMask]. + repeated Document results = 2; + + // The time at which the document(s) were read. + // + // This may be monotonically increasing; in this case, the previous documents + // in the result stream are guaranteed not to have changed between their + // `execution_time` and this one. + // + // If the query returns no results, a response with `execution_time` and no + // `results` will be sent, and this represents the time at which the operation + // was run. + google.protobuf.Timestamp execution_time = 3; + + // Query explain metrics. + // + // Set on the last response when [ExecutePipelineRequest.explain_options][] + // was specified on the request. + // ExplainMetrics explain_metrics = 4; +} + // The request for // [Firestore.RunAggregationQuery][google.firestore.v1.Firestore.RunAggregationQuery]. message RunAggregationQueryRequest { diff --git a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/pipeline.proto b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/pipeline.proto new file mode 100644 index 000000000..0a198cd6e --- /dev/null +++ b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/pipeline.proto @@ -0,0 +1,27 @@ + +syntax = "proto3"; +package google.firestore.v1; +import "google/firestore/v1/document.proto"; +option csharp_namespace = "Google.Cloud.Firestore.V1"; +option php_namespace = "Google\\Cloud\\Firestore\\V1"; +option ruby_package = "Google::Cloud::Firestore::V1"; +option java_multiple_files = true; +option java_package = "com.google.firestore.v1"; +option java_outer_classname = "PipelineProto"; +option objc_class_prefix = "GCFS"; +// A Firestore query represented as an ordered list of operations / stages. +// +// This is considered the top-level function which plans & executes a query. +// It is logically equivalent to `query(stages, options)`, but prevents the +// client from having to build a function wrapper. +message StructuredPipeline { + // The pipeline query to execute. + Pipeline pipeline = 1; + // Optional query-level arguments. + // + // (-- Think query statement hints. --) + // + // (-- TODO(batchik): define the api contract of using an unsupported hint --) + map options = 2; +} + diff --git a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/query_profile.proto b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/query_profile.proto index de27144a0..931e083b0 100644 --- a/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/query_profile.proto +++ b/proto-google-cloud-firestore-v1/src/main/proto/google/firestore/v1/query_profile.proto @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License.