Loading apex/appsearch/framework/java/android/app/appsearch/AppSearch.java +60 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CurrentTimeMillisLong; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.appsearch.AppSearchSchema.PropertyConfig; import android.os.Bundle; import android.util.Log; Loading Loading @@ -574,10 +575,6 @@ public final class AppSearch { * @hide */ public static class Email extends Document { /** The name of the schema type for {@link Email} documents.*/ public static final String SCHEMA_TYPE = "builtin:Email"; private static final String KEY_FROM = "from"; private static final String KEY_TO = "to"; private static final String KEY_CC = "cc"; Loading @@ -585,14 +582,53 @@ public final class AppSearch { private static final String KEY_SUBJECT = "subject"; private static final String KEY_BODY = "body"; /** * Creates a new {@link Email} from the contents of an existing {@link Document}. * * @param document The {@link Document} containing the email content. */ public Email(@NonNull Document document) { super(document); } /** The name of the schema type for {@link Email} documents.*/ public static final String SCHEMA_TYPE = "builtin:Email"; public static final AppSearchSchema SCHEMA = AppSearchSchema.newBuilder(SCHEMA_TYPE) .addProperty(AppSearchSchema.newPropertyBuilder(KEY_FROM) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_TO) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_CC) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BCC) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_SUBJECT) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BODY) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).build(); /** * Creates a new {@link Email.Builder}. Loading @@ -603,6 +639,15 @@ public final class AppSearch { return new Builder(uri); } /** * Creates a new {@link Email} from the contents of an existing {@link Document}. * * @param document The {@link Document} containing the email content. */ public Email(@NonNull Document document) { super(document); } /** * Get the from address of {@link Email}. * Loading @@ -615,10 +660,10 @@ public final class AppSearch { } /** * Get the destination address of {@link Email}. * Get the destination addresses of {@link Email}. * * @return Returns the destination address of {@link Email} or {@code null} if it's not been * set yet. * @return Returns the destination addresses of {@link Email} or {@code null} if it's not * been set yet. * @hide */ @Nullable Loading apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +12 −12 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class AppSearchManager { } /** * Sets the schema being used by documents provided to the #put method. * Sets the schema being used by documents provided to the {@link #putDocuments} method. * * <p>The schema provided here is compared to the stored copy of the schema previously supplied * to {@link #setSchema}, if any, to determine how to treat existing documents. The following Loading Loading @@ -106,13 +106,12 @@ public class AppSearchManager { * * @hide */ // TODO(b/143789408): linkify #put after that API is created public void setSchema(@NonNull AppSearchSchema... schemas) { setSchema(Arrays.asList(schemas), /*forceOverride=*/false); } /** * Sets the schema being used by documents provided to the #put method. * Sets the schema being used by documents provided to the {@link #putDocuments} method. * * <p>This method is similar to {@link #setSchema(AppSearchSchema...)}, except for the * {@code forceOverride} parameter. If a backwards-incompatible schema is specified but the Loading @@ -129,7 +128,6 @@ public class AppSearchManager { * * @hide */ // TODO(b/143789408): linkify #put after that API is created public void setSchema(@NonNull List<AppSearchSchema> schemas, boolean forceOverride) { // Prepare the merged schema for transmission. SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder(); Loading @@ -151,26 +149,28 @@ public class AppSearchManager { } /** * Index {@link Document} to AppSearch * Index {@link android.app.appsearch.AppSearch.Document Documents} into AppSearch. * * <p>You should not call this method directly; instead, use the {@code AppSearch#put()} API * provided by JetPack. * <p>You should not call this method directly; instead, use the * {@code AppSearch#putDocuments()} API provided by JetPack. * * <p>The schema should be set via {@link #setSchema} method. * <p>Each {@link AppSearch.Document Document's} {@code schemaType} field must be set to the * name of a schema type previously registered via the {@link #setSchema} method. * * @param documents {@link Document Documents} that need to be indexed. * @param executor Executor on which to invoke the callback. * @param callback Callback to receive errors resulting from setting the schema. If the * operation succeeds, the callback will be invoked with {@code null}. * @param callback Callback to receive errors. On success, it will be called with {@code null}. * On failure, it will be called with a {@link Throwable} describing the failure. */ public void put(@NonNull List<Document> documents, public void putDocuments( @NonNull List<Document> documents, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<? super Throwable> callback) { AndroidFuture<Void> future = new AndroidFuture<>(); for (Document document : documents) { // TODO(b/146386470) batching Document protos try { mService.put(document.getProto().toByteArray(), future); mService.putDocument(document.getProto().toByteArray(), future); } catch (RemoteException e) { future.completeExceptionally(e); break; Loading apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +13 −3 Original line number Diff line number Diff line Loading @@ -22,15 +22,25 @@ interface IAppSearchManager { /** * Sets the schema. * * @param schemaProto Serialized SchemaProto. * @param schemaBytes Serialized SchemaProto. * @param forceOverride Whether to apply the new schema even if it is incompatible. All * incompatible documents will be deleted. * @param callback {@link AndroidFuture}<{@link Void}>. Will be completed with * {@code null} upon successful completion of the setSchema call, or completed * exceptionally if setSchema fails. */ void setSchema(in byte[] schemaProto, boolean forceOverride, in AndroidFuture callback); void put(in byte[] documentBytes, in AndroidFuture callback); void setSchema(in byte[] schemaBytes, boolean forceOverride, in AndroidFuture callback); /** * Inserts a document into the index. * * @param documentBytes serialized DocumentProto * @param callback {@link AndroidFuture}<{@link Void}>. Will be completed with * {@code null} upon successful completion of the put call, or completed exceptionally if * put fails. */ void putDocument(in byte[] documentBytes, in AndroidFuture callback); /** * Searches a document based on a given query string. * Loading apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +13 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import com.android.server.appsearch.impl.AppSearchImpl; import com.android.server.appsearch.impl.FakeIcing; import com.android.server.appsearch.impl.ImplInstanceManager; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; Loading Loading @@ -71,11 +72,21 @@ public class AppSearchManagerService extends SystemService { } @Override public void put(byte[] documentBytes, AndroidFuture callback) { public void putDocument(byte[] documentBytes, AndroidFuture callback) { Preconditions.checkNotNull(documentBytes); Preconditions.checkNotNull(callback); int callingUid = Binder.getCallingUidOrThrow(); int callingUserId = UserHandle.getUserId(callingUid); long callingIdentity = Binder.clearCallingIdentity(); try { throw new UnsupportedOperationException("Put document not yet implemented"); DocumentProto document = DocumentProto.parseFrom(documentBytes); AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); impl.putDocument(callingUid, document); callback.complete(null); } catch (Throwable t) { callback.completeExceptionally(t); } finally { Binder.restoreCallingIdentity(callingIdentity); } } // TODO(sidchhabra):Init FakeIcing properly. Loading apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +56 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import android.content.Context; import com.android.internal.annotations.VisibleForTesting; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.PropertyConfigProto; import com.google.android.icing.proto.PropertyProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SchemaTypeConfigProto; Loading Loading @@ -94,6 +96,60 @@ public final class AppSearchImpl { } } /** * Adds a document to the AppSearch index. * * @param callingUid The uid of the app calling AppSearch. * @param origDocument The document to index. */ public void putDocument(int callingUid, @NonNull DocumentProto origDocument) { // Rewrite the type names to include the app's prefix String typePrefix = getTypePrefix(callingUid); DocumentProto.Builder documentBuilder = origDocument.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder); mFakeIcing.put(documentBuilder.build()); } /** * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend * {@code typePrefix}. * * @param typePrefix The prefix to add * @param documentBuilder The document to mutate */ @VisibleForTesting void rewriteDocumentTypes( @NonNull String typePrefix, @NonNull DocumentProto.Builder documentBuilder) { // Rewrite the type name to include the app's prefix String newSchema = typePrefix + documentBuilder.getSchema(); documentBuilder.setSchema(newSchema); // Add namespace. If we ever allow users to set their own namespaces, this will have // to change to prepend the prefix instead of setting the whole namespace. We will also have // to store the namespaces in a map similar to the type map so we can rewrite queries with // empty namespaces. documentBuilder.setNamespace(typePrefix); // Recurse into derived documents for (int propertyIdx = 0; propertyIdx < documentBuilder.getPropertiesCount(); propertyIdx++) { int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount(); if (documentCount > 0) { PropertyProto.Builder propertyBuilder = documentBuilder.getProperties(propertyIdx).toBuilder(); for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) { DocumentProto.Builder derivedDocumentBuilder = propertyBuilder.getDocumentValues(documentIdx).toBuilder(); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder); propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder); } documentBuilder.setProperties(propertyIdx, propertyBuilder); } } } /** * Returns a type prefix in a format like {@code com.example.package@1000/} or * {@code com.example.sharedname:5678@1000/}. Loading Loading
apex/appsearch/framework/java/android/app/appsearch/AppSearch.java +60 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CurrentTimeMillisLong; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.appsearch.AppSearchSchema.PropertyConfig; import android.os.Bundle; import android.util.Log; Loading Loading @@ -574,10 +575,6 @@ public final class AppSearch { * @hide */ public static class Email extends Document { /** The name of the schema type for {@link Email} documents.*/ public static final String SCHEMA_TYPE = "builtin:Email"; private static final String KEY_FROM = "from"; private static final String KEY_TO = "to"; private static final String KEY_CC = "cc"; Loading @@ -585,14 +582,53 @@ public final class AppSearch { private static final String KEY_SUBJECT = "subject"; private static final String KEY_BODY = "body"; /** * Creates a new {@link Email} from the contents of an existing {@link Document}. * * @param document The {@link Document} containing the email content. */ public Email(@NonNull Document document) { super(document); } /** The name of the schema type for {@link Email} documents.*/ public static final String SCHEMA_TYPE = "builtin:Email"; public static final AppSearchSchema SCHEMA = AppSearchSchema.newBuilder(SCHEMA_TYPE) .addProperty(AppSearchSchema.newPropertyBuilder(KEY_FROM) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_TO) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_CC) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BCC) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_REPEATED) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_SUBJECT) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BODY) .setDataType(PropertyConfig.DATA_TYPE_STRING) .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) .build() ).build(); /** * Creates a new {@link Email.Builder}. Loading @@ -603,6 +639,15 @@ public final class AppSearch { return new Builder(uri); } /** * Creates a new {@link Email} from the contents of an existing {@link Document}. * * @param document The {@link Document} containing the email content. */ public Email(@NonNull Document document) { super(document); } /** * Get the from address of {@link Email}. * Loading @@ -615,10 +660,10 @@ public final class AppSearch { } /** * Get the destination address of {@link Email}. * Get the destination addresses of {@link Email}. * * @return Returns the destination address of {@link Email} or {@code null} if it's not been * set yet. * @return Returns the destination addresses of {@link Email} or {@code null} if it's not * been set yet. * @hide */ @Nullable Loading
apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +12 −12 Original line number Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class AppSearchManager { } /** * Sets the schema being used by documents provided to the #put method. * Sets the schema being used by documents provided to the {@link #putDocuments} method. * * <p>The schema provided here is compared to the stored copy of the schema previously supplied * to {@link #setSchema}, if any, to determine how to treat existing documents. The following Loading Loading @@ -106,13 +106,12 @@ public class AppSearchManager { * * @hide */ // TODO(b/143789408): linkify #put after that API is created public void setSchema(@NonNull AppSearchSchema... schemas) { setSchema(Arrays.asList(schemas), /*forceOverride=*/false); } /** * Sets the schema being used by documents provided to the #put method. * Sets the schema being used by documents provided to the {@link #putDocuments} method. * * <p>This method is similar to {@link #setSchema(AppSearchSchema...)}, except for the * {@code forceOverride} parameter. If a backwards-incompatible schema is specified but the Loading @@ -129,7 +128,6 @@ public class AppSearchManager { * * @hide */ // TODO(b/143789408): linkify #put after that API is created public void setSchema(@NonNull List<AppSearchSchema> schemas, boolean forceOverride) { // Prepare the merged schema for transmission. SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder(); Loading @@ -151,26 +149,28 @@ public class AppSearchManager { } /** * Index {@link Document} to AppSearch * Index {@link android.app.appsearch.AppSearch.Document Documents} into AppSearch. * * <p>You should not call this method directly; instead, use the {@code AppSearch#put()} API * provided by JetPack. * <p>You should not call this method directly; instead, use the * {@code AppSearch#putDocuments()} API provided by JetPack. * * <p>The schema should be set via {@link #setSchema} method. * <p>Each {@link AppSearch.Document Document's} {@code schemaType} field must be set to the * name of a schema type previously registered via the {@link #setSchema} method. * * @param documents {@link Document Documents} that need to be indexed. * @param executor Executor on which to invoke the callback. * @param callback Callback to receive errors resulting from setting the schema. If the * operation succeeds, the callback will be invoked with {@code null}. * @param callback Callback to receive errors. On success, it will be called with {@code null}. * On failure, it will be called with a {@link Throwable} describing the failure. */ public void put(@NonNull List<Document> documents, public void putDocuments( @NonNull List<Document> documents, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<? super Throwable> callback) { AndroidFuture<Void> future = new AndroidFuture<>(); for (Document document : documents) { // TODO(b/146386470) batching Document protos try { mService.put(document.getProto().toByteArray(), future); mService.putDocument(document.getProto().toByteArray(), future); } catch (RemoteException e) { future.completeExceptionally(e); break; Loading
apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +13 −3 Original line number Diff line number Diff line Loading @@ -22,15 +22,25 @@ interface IAppSearchManager { /** * Sets the schema. * * @param schemaProto Serialized SchemaProto. * @param schemaBytes Serialized SchemaProto. * @param forceOverride Whether to apply the new schema even if it is incompatible. All * incompatible documents will be deleted. * @param callback {@link AndroidFuture}<{@link Void}>. Will be completed with * {@code null} upon successful completion of the setSchema call, or completed * exceptionally if setSchema fails. */ void setSchema(in byte[] schemaProto, boolean forceOverride, in AndroidFuture callback); void put(in byte[] documentBytes, in AndroidFuture callback); void setSchema(in byte[] schemaBytes, boolean forceOverride, in AndroidFuture callback); /** * Inserts a document into the index. * * @param documentBytes serialized DocumentProto * @param callback {@link AndroidFuture}<{@link Void}>. Will be completed with * {@code null} upon successful completion of the put call, or completed exceptionally if * put fails. */ void putDocument(in byte[] documentBytes, in AndroidFuture callback); /** * Searches a document based on a given query string. * Loading
apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +13 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import com.android.server.appsearch.impl.AppSearchImpl; import com.android.server.appsearch.impl.FakeIcing; import com.android.server.appsearch.impl.ImplInstanceManager; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; Loading Loading @@ -71,11 +72,21 @@ public class AppSearchManagerService extends SystemService { } @Override public void put(byte[] documentBytes, AndroidFuture callback) { public void putDocument(byte[] documentBytes, AndroidFuture callback) { Preconditions.checkNotNull(documentBytes); Preconditions.checkNotNull(callback); int callingUid = Binder.getCallingUidOrThrow(); int callingUserId = UserHandle.getUserId(callingUid); long callingIdentity = Binder.clearCallingIdentity(); try { throw new UnsupportedOperationException("Put document not yet implemented"); DocumentProto document = DocumentProto.parseFrom(documentBytes); AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); impl.putDocument(callingUid, document); callback.complete(null); } catch (Throwable t) { callback.completeExceptionally(t); } finally { Binder.restoreCallingIdentity(callingIdentity); } } // TODO(sidchhabra):Init FakeIcing properly. Loading
apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +56 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ import android.content.Context; import com.android.internal.annotations.VisibleForTesting; import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.PropertyConfigProto; import com.google.android.icing.proto.PropertyProto; import com.google.android.icing.proto.SchemaProto; import com.google.android.icing.proto.SchemaTypeConfigProto; Loading Loading @@ -94,6 +96,60 @@ public final class AppSearchImpl { } } /** * Adds a document to the AppSearch index. * * @param callingUid The uid of the app calling AppSearch. * @param origDocument The document to index. */ public void putDocument(int callingUid, @NonNull DocumentProto origDocument) { // Rewrite the type names to include the app's prefix String typePrefix = getTypePrefix(callingUid); DocumentProto.Builder documentBuilder = origDocument.toBuilder(); rewriteDocumentTypes(typePrefix, documentBuilder); mFakeIcing.put(documentBuilder.build()); } /** * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend * {@code typePrefix}. * * @param typePrefix The prefix to add * @param documentBuilder The document to mutate */ @VisibleForTesting void rewriteDocumentTypes( @NonNull String typePrefix, @NonNull DocumentProto.Builder documentBuilder) { // Rewrite the type name to include the app's prefix String newSchema = typePrefix + documentBuilder.getSchema(); documentBuilder.setSchema(newSchema); // Add namespace. If we ever allow users to set their own namespaces, this will have // to change to prepend the prefix instead of setting the whole namespace. We will also have // to store the namespaces in a map similar to the type map so we can rewrite queries with // empty namespaces. documentBuilder.setNamespace(typePrefix); // Recurse into derived documents for (int propertyIdx = 0; propertyIdx < documentBuilder.getPropertiesCount(); propertyIdx++) { int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount(); if (documentCount > 0) { PropertyProto.Builder propertyBuilder = documentBuilder.getProperties(propertyIdx).toBuilder(); for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) { DocumentProto.Builder derivedDocumentBuilder = propertyBuilder.getDocumentValues(documentIdx).toBuilder(); rewriteDocumentTypes(typePrefix, derivedDocumentBuilder); propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder); } documentBuilder.setProperties(propertyIdx, propertyBuilder); } } } /** * Returns a type prefix in a format like {@code com.example.package@1000/} or * {@code com.example.sharedname:5678@1000/}. Loading