1919import com .google .firestore .v1beta1 .DocumentTransform .FieldTransform ;
2020import com .google .firestore .v1beta1 .Write ;
2121import java .util .ArrayList ;
22+ import java .util .Collections ;
2223import java .util .List ;
2324import java .util .Map ;
25+ import java .util .Set ;
26+ import java .util .SortedMap ;
27+ import java .util .TreeMap ;
2428
2529/**
2630 * A DocumentTransform contains pending server-side transforms and their corresponding field paths.
2731 */
2832final class DocumentTransform {
2933
3034 private DocumentReference documentReference ;
31- private final List < FieldTransform > transforms ;
35+ private final SortedMap < FieldPath , FieldTransform > transforms ; // Sorted for testing.
3236
33- private DocumentTransform (DocumentReference documentReference , List <FieldTransform > transforms ) {
37+ private DocumentTransform (
38+ DocumentReference documentReference , SortedMap <FieldPath , FieldTransform > transforms ) {
3439 this .documentReference = documentReference ;
3540 this .transforms = transforms ;
3641 }
3742
3843 static DocumentTransform fromFieldPathMap (
3944 DocumentReference documentReference , Map <FieldPath , Object > values ) {
40- List < FieldTransform > transforms = new ArrayList <>();
45+ SortedMap < FieldPath , FieldTransform > transforms = new TreeMap <>();
4146
4247 for (Map .Entry <FieldPath , Object > entry : values .entrySet ()) {
4348 FieldPath path = entry .getKey ();
@@ -46,23 +51,23 @@ static DocumentTransform fromFieldPathMap(
4651 FieldTransform .Builder fieldTransform = FieldTransform .newBuilder ();
4752 fieldTransform .setFieldPath (path .getEncodedPath ());
4853 fieldTransform .setSetToServerValue (FieldTransform .ServerValue .REQUEST_TIME );
49- transforms .add ( fieldTransform .build ());
54+ transforms .put ( path , fieldTransform .build ());
5055 } else if (value instanceof Map ) {
51- transforms .addAll (
56+ transforms .putAll (
5257 extractFromMap ((Map <String , Object >) value , path , /* allowTransforms= */ true ));
5358 } else if (entry .getValue () instanceof List ) {
5459 // DocumentTransforms cannot be contained in Lists. We still process the List for
5560 // validation.
56- extractFromArray ((List <Object >) entry .getValue (), path );
61+ validateArray ((List <Object >) entry .getValue (), path );
5762 }
5863 }
5964
6065 return new DocumentTransform (documentReference , transforms );
6166 }
6267
63- private static List < FieldTransform > extractFromMap (
68+ private static SortedMap < FieldPath , FieldTransform > extractFromMap (
6469 Map <String , Object > values , FieldPath path , boolean allowTransforms ) {
65- List < FieldTransform > transforms = new ArrayList <>();
70+ SortedMap < FieldPath , FieldTransform > transforms = new TreeMap <>();
6671
6772 for (Map .Entry <String , Object > entry : values .entrySet ()) {
6873 Object value = entry .getValue ();
@@ -72,51 +77,51 @@ private static List<FieldTransform> extractFromMap(
7277 FieldTransform .Builder fieldTransform = FieldTransform .newBuilder ();
7378 fieldTransform .setFieldPath (path .getEncodedPath ());
7479 fieldTransform .setSetToServerValue (FieldTransform .ServerValue .REQUEST_TIME );
75- transforms .add ( fieldTransform .build ());
80+ transforms .put ( path , fieldTransform .build ());
7681 } else {
7782 throw FirestoreException .invalidState (
7883 "Server timestamps are not supported as Array values." );
7984 }
8085 } else if (value instanceof Map ) {
81- transforms .addAll (extractFromMap ((Map <String , Object >) value , path , allowTransforms ));
86+ transforms .putAll (extractFromMap ((Map <String , Object >) value , path , allowTransforms ));
8287 } else if (entry .getValue () instanceof List ) {
83- extractFromArray ((List <Object >) entry .getValue (), path );
88+ validateArray ((List <Object >) entry .getValue (), path );
8489 }
8590 path = path .getParent ();
8691 }
8792
8893 return transforms ;
8994 }
9095
91- private static List <FieldTransform > extractFromArray (List <Object > values , FieldPath path ) {
92- List <FieldTransform > transforms = new ArrayList <>();
93-
96+ private static void validateArray (List <Object > values , FieldPath path ) {
9497 for (int i = 0 ; i < values .size (); ++i ) {
9598 Object value = values .get (i );
9699 path = path .append (FieldPath .of (Integer .toString (i )));
97100 if (value == FieldValue .SERVER_TIMESTAMP_SENTINEL ) {
98101 throw FirestoreException .invalidState (
99102 "Server timestamps are not supported as Array values." );
100103 } else if (value instanceof Map ) {
101- transforms . addAll ( extractFromMap ((Map <String , Object >) value , path , false ) );
104+ extractFromMap ((Map <String , Object >) value , path , false );
102105 } else if (value instanceof List ) {
103- extractFromArray ((List <Object >) value , path );
106+ validateArray ((List <Object >) value , path );
104107 }
105108 path = path .getParent ();
106109 }
107-
108- return transforms ;
109110 }
110111
111112 boolean isEmpty () {
112113 return transforms .isEmpty ();
113114 }
114115
115- Write toPb () {
116+ Set <FieldPath > getFields () {
117+ return Collections .unmodifiableSet (transforms .keySet ());
118+ }
119+
120+ Write .Builder toPb () {
116121 Write .Builder write = Write .newBuilder ();
117122 com .google .firestore .v1beta1 .DocumentTransform .Builder transform = write .getTransformBuilder ();
118- transform .addAllFieldTransforms (transforms );
123+ transform .addAllFieldTransforms (transforms . values () );
119124 transform .setDocument (documentReference .getName ());
120- return write . build () ;
125+ return write ;
121126 }
122127}
0 commit comments