@@ -547,29 +547,28 @@ google_firestore_v1_Write Serializer::EncodeMutation(
547
547
result.which_operation = google_firestore_v1_Write_update_tag;
548
548
auto patch_mutation = static_cast <const PatchMutation&>(mutation);
549
549
result.update = EncodeDocument (mutation.key (), patch_mutation.value ());
550
- result.update_mask = EncodeDocumentMask (patch_mutation.mask ());
550
+ result.update_mask = EncodeFieldMask (patch_mutation.mask ());
551
551
return result;
552
552
}
553
553
554
554
case Mutation::Type::Transform: {
555
- // TODO(rsgowman): Implement transform mutations. Probably like this:
556
- abort ();
557
- /*
558
- result.which_operation = google_firestore_v1_Write_transform_tag;
559
- auto transform = static_cast<const TransformMutation&>(mutation);
560
- result.transform.document = EncodeKey(transform.key());
561
-
562
- size_t count = transform.field_transforms.size();
563
- result.transform.field_transforms_count = count;
564
- result.transform.field_transforms =
565
- MakeArray<google_firestore_v1_DocumentTransform_FieldTransform>(count);
566
- int i = 0;
567
- for (const FieldTransform& field_transform :
568
- transform.field_transforms()) { result.transform.field_transforms[i] =
569
- EncodeFieldTransform(field_transform); i++;
570
- }
571
- return result;
572
- */
555
+ result.which_operation = google_firestore_v1_Write_transform_tag;
556
+ auto transform = static_cast <const TransformMutation&>(mutation);
557
+ result.transform .document = EncodeString (EncodeKey (transform.key ()));
558
+
559
+ pb_size_t count = CheckedSize (transform.field_transforms ().size ());
560
+ result.transform .field_transforms_count = count;
561
+ result.transform .field_transforms =
562
+ MakeArray<google_firestore_v1_DocumentTransform_FieldTransform>(
563
+ count);
564
+ int i = 0 ;
565
+ for (const FieldTransform& field_transform :
566
+ transform.field_transforms ()) {
567
+ result.transform .field_transforms [i] =
568
+ EncodeFieldTransform (field_transform);
569
+ i++;
570
+ }
571
+ return result;
573
572
}
574
573
575
574
case Mutation::Type::Delete: {
@@ -592,7 +591,7 @@ Mutation Serializer::DecodeMutation(
592
591
DocumentKey key = DecodeKey (reader, DecodeString (mutation.update .name ));
593
592
ObjectValue value = ObjectValue::FromMap (DecodeFields (
594
593
reader, mutation.update .fields_count , mutation.update .fields ));
595
- FieldMask mask = DecodeDocumentMask (mutation.update_mask );
594
+ FieldMask mask = DecodeFieldMask (mutation.update_mask );
596
595
if (mask.size () > 0 ) {
597
596
return PatchMutation (std::move (key), std::move (value), std::move (mask),
598
597
std::move (precondition));
@@ -606,22 +605,21 @@ Mutation Serializer::DecodeMutation(
606
605
return DeleteMutation (DecodeKey (reader, DecodeString (mutation.delete_ )),
607
606
std::move (precondition));
608
607
609
- // TODO(rsgowman): Implement transform. Probably like this:
610
- /*
611
- case google_firestore_v1_Write_transform_tag:
612
- std::vector<FieldTransform> field_transforms;
613
- for (size_t i = 0; i<mutation.transform.field_transforms_count; i++) {
614
- field_transforms.push_back(DecodeFieldTransform(mutation.transform.field_transforms[i]));
615
- }
608
+ case google_firestore_v1_Write_transform_tag: {
609
+ std::vector<FieldTransform> field_transforms;
610
+ for (size_t i = 0 ; i < mutation.transform .field_transforms_count ; i++) {
611
+ field_transforms.push_back (DecodeFieldTransform (
612
+ reader, mutation.transform .field_transforms [i]));
613
+ }
616
614
617
- HARD_ASSERT(precondition.type() == Precondition::Type::Exists &&
618
- precondition.exists(), "Transforms only support precondition \"exists ==
619
- true\"");
615
+ HARD_ASSERT (precondition.type () == Precondition::Type::Exists &&
616
+ precondition. exists (),
617
+ " Transforms only support precondition \" exists == true\" " );
620
618
621
- return absl::make_unique< TransformMutation> (
622
- DecodeKey(reader, mutation.transform.document),
623
- field_transforms);
624
- */
619
+ return TransformMutation (
620
+ DecodeKey (reader, MakeStringView ( mutation.transform .document ) ),
621
+ field_transforms);
622
+ }
625
623
626
624
default :
627
625
reader->Fail (StringFormat (" Unknown mutation operation: %s" ,
@@ -687,7 +685,7 @@ Precondition Serializer::DecodePrecondition(
687
685
}
688
686
689
687
/* static */
690
- google_firestore_v1_DocumentMask Serializer::EncodeDocumentMask (
688
+ google_firestore_v1_DocumentMask Serializer::EncodeFieldMask (
691
689
const FieldMask& mask) {
692
690
google_firestore_v1_DocumentMask result{};
693
691
@@ -697,22 +695,114 @@ google_firestore_v1_DocumentMask Serializer::EncodeDocumentMask(
697
695
698
696
int i = 0 ;
699
697
for (const FieldPath& path : mask) {
700
- result.field_paths [i] = EncodeString (path. CanonicalString () );
698
+ result.field_paths [i] = EncodeFieldPath (path);
701
699
i++;
702
700
}
703
701
704
702
return result;
705
703
}
706
704
707
705
/* static */
708
- model:: FieldMask Serializer::DecodeDocumentMask (
706
+ FieldMask Serializer::DecodeFieldMask (
709
707
const google_firestore_v1_DocumentMask& mask) {
710
708
std::set<FieldPath> fields;
711
709
for (size_t i = 0 ; i < mask.field_paths_count ; i++) {
712
- auto path = DecodeString (mask.field_paths [i]);
713
- fields.insert (FieldPath::FromServerFormat (path));
710
+ fields.insert (DecodeFieldPath (mask.field_paths [i]));
711
+ }
712
+ return FieldMask (std::move (fields));
713
+ }
714
+
715
+ /* static */
716
+ google_firestore_v1_DocumentTransform_FieldTransform
717
+ Serializer::EncodeFieldTransform (const FieldTransform& field_transform) {
718
+ using Type = TransformOperation::Type;
719
+
720
+ google_firestore_v1_DocumentTransform_FieldTransform proto{};
721
+ proto.field_path = EncodeFieldPath (field_transform.path ());
722
+
723
+ switch (field_transform.transformation ().type ()) {
724
+ case Type::ServerTimestamp:
725
+ proto.which_transform_type =
726
+ google_firestore_v1_DocumentTransform_FieldTransform_set_to_server_value_tag; // NOLINT
727
+ proto.set_to_server_value =
728
+ google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME; // NOLINT
729
+ return proto;
730
+
731
+ case Type::ArrayUnion:
732
+ proto.which_transform_type =
733
+ google_firestore_v1_DocumentTransform_FieldTransform_append_missing_elements_tag; // NOLINT
734
+ proto.append_missing_elements = EncodeArray (
735
+ ArrayTransform (field_transform.transformation ()).elements ());
736
+ return proto;
737
+
738
+ case Type::ArrayRemove:
739
+ proto.which_transform_type =
740
+ google_firestore_v1_DocumentTransform_FieldTransform_remove_all_from_array_tag; // NOLINT
741
+ proto.remove_all_from_array = EncodeArray (
742
+ ArrayTransform (field_transform.transformation ()).elements ());
743
+ return proto;
744
+
745
+ case Type::Increment: {
746
+ const auto & increment = static_cast <const NumericIncrementTransform&>(
747
+ field_transform.transformation ());
748
+ proto.increment = EncodeFieldValue (increment.operand ());
749
+ return proto;
750
+ }
714
751
}
715
- return model::FieldMask (std::move (fields));
752
+
753
+ UNREACHABLE ();
754
+ }
755
+
756
+ /* static */ FieldTransform Serializer::DecodeFieldTransform (
757
+ nanopb::Reader* reader,
758
+ const google_firestore_v1_DocumentTransform_FieldTransform& proto) {
759
+ switch (proto.which_transform_type ) {
760
+ case google_firestore_v1_DocumentTransform_FieldTransform_set_to_server_value_tag: { // NOLINT
761
+ HARD_ASSERT (
762
+ proto.set_to_server_value ==
763
+ google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME, // NOLINT
764
+ " Unknown transform setToServerValue: %s" , proto.set_to_server_value );
765
+
766
+ return FieldTransform (DecodeFieldPath (proto.field_path ),
767
+ ServerTimestampTransform ());
768
+ }
769
+
770
+ case google_firestore_v1_DocumentTransform_FieldTransform_append_missing_elements_tag: { // NOLINT
771
+ std::vector<FieldValue> elements =
772
+ DecodeArray (reader, proto.append_missing_elements );
773
+ return FieldTransform (DecodeFieldPath (proto.field_path ),
774
+ ArrayTransform (TransformOperation::Type::ArrayUnion,
775
+ std::move (elements)));
776
+ }
777
+
778
+ case google_firestore_v1_DocumentTransform_FieldTransform_remove_all_from_array_tag: { // NOLINT
779
+ std::vector<FieldValue> elements =
780
+ DecodeArray (reader, proto.remove_all_from_array );
781
+ return FieldTransform (
782
+ DecodeFieldPath (proto.field_path ),
783
+ ArrayTransform (TransformOperation::Type::ArrayRemove,
784
+ std::move (elements)));
785
+ }
786
+
787
+ case google_firestore_v1_DocumentTransform_FieldTransform_increment_tag: {
788
+ FieldValue operand = DecodeFieldValue (reader, proto.increment );
789
+ return FieldTransform (DecodeFieldPath (proto.field_path ),
790
+ NumericIncrementTransform (std::move (operand)));
791
+ }
792
+ }
793
+
794
+ UNREACHABLE ();
795
+ }
796
+
797
+ /* static */
798
+ pb_bytes_array_t * Serializer::EncodeFieldPath (const FieldPath& field_path) {
799
+ return EncodeString (field_path.CanonicalString ());
800
+ }
801
+
802
+ /* static */
803
+ FieldPath Serializer::DecodeFieldPath (const pb_bytes_array_t * field_path) {
804
+ absl::string_view str = MakeStringView (field_path);
805
+ return FieldPath::FromServerFormat (str);
716
806
}
717
807
718
808
google_firestore_v1_Target_QueryTarget Serializer::EncodeQueryTarget (
0 commit comments