@@ -42,15 +42,19 @@ namespace {
42
42
43
43
using core::Query;
44
44
using model::Document;
45
+ using model::DocumentState;
46
+ using model::FieldValue;
45
47
using model::MaybeDocument;
46
48
using model::Mutation;
47
49
using model::MutationBatch;
48
50
using model::NoDocument;
51
+ using model::ObjectValue;
49
52
using model::SnapshotVersion;
50
53
using model::UnknownDocument;
51
54
using nanopb::ByteString;
52
55
using nanopb::CheckedSize;
53
56
using nanopb::Reader;
57
+ using nanopb::SafeReadBoolean;
54
58
using nanopb::Writer;
55
59
using remote::InvalidQuery;
56
60
using remote::MakeArray;
@@ -64,34 +68,34 @@ firestore_client_MaybeDocument LocalSerializer::EncodeMaybeDocument(
64
68
firestore_client_MaybeDocument result{};
65
69
66
70
switch (maybe_doc.type ()) {
67
- case MaybeDocument::Type::Document:
71
+ case MaybeDocument::Type::Document: {
68
72
result.which_document_type = firestore_client_MaybeDocument_document_tag;
69
- result.document = EncodeDocument (static_cast <const Document&>(maybe_doc));
70
- // TODO(rsgowman): heldwriteacks:
71
- // result.has_committed_mutations = existing_doc.HasCommittedMutations();
73
+ Document doc (maybe_doc);
74
+ // TODO(wuandy): Check if `doc` already has a proto and use that if yes.
75
+ result.document = EncodeDocument (doc);
76
+ result.has_committed_mutations = doc.has_committed_mutations ();
72
77
return result;
78
+ }
73
79
74
- case MaybeDocument::Type::NoDocument:
80
+ case MaybeDocument::Type::NoDocument: {
75
81
result.which_document_type =
76
82
firestore_client_MaybeDocument_no_document_tag;
77
- result.no_document =
78
- EncodeNoDocument (static_cast <const NoDocument&>(maybe_doc));
79
- // TODO(rsgowman): heldwriteacks:
80
- // result.has_committed_mutations = no_doc.HasCommittedMutations();
83
+ NoDocument no_doc (maybe_doc);
84
+ result.no_document = EncodeNoDocument (no_doc);
85
+ result.has_committed_mutations = no_doc.has_committed_mutations ();
81
86
return result;
87
+ }
82
88
83
89
case MaybeDocument::Type::UnknownDocument:
84
90
result.which_document_type =
85
91
firestore_client_MaybeDocument_unknown_document_tag;
86
92
result.unknown_document =
87
- EncodeUnknownDocument (static_cast <const UnknownDocument&>(maybe_doc));
88
- // TODO(rsgowman): heldwriteacks:
89
- // result.has_committed_mutations = true;
93
+ EncodeUnknownDocument (UnknownDocument (maybe_doc));
94
+ result.has_committed_mutations = true ;
90
95
return result;
91
96
92
97
case MaybeDocument::Type::Invalid:
93
- // TODO(rsgowman): Error handling
94
- abort ();
98
+ HARD_FAIL (" Unknown document type %s" , maybe_doc.type ());
95
99
}
96
100
97
101
UNREACHABLE ();
@@ -103,10 +107,12 @@ MaybeDocument LocalSerializer::DecodeMaybeDocument(
103
107
104
108
switch (proto.which_document_type ) {
105
109
case firestore_client_MaybeDocument_document_tag:
106
- return rpc_serializer_.DecodeDocument (reader, proto.document );
110
+ return DecodeDocument (reader, proto.document ,
111
+ SafeReadBoolean (proto.has_committed_mutations ));
107
112
108
113
case firestore_client_MaybeDocument_no_document_tag:
109
- return DecodeNoDocument (reader, proto.no_document );
114
+ return DecodeNoDocument (reader, proto.no_document ,
115
+ SafeReadBoolean (proto.has_committed_mutations ));
110
116
111
117
case firestore_client_MaybeDocument_unknown_document_tag:
112
118
return DecodeUnknownDocument (reader, proto.unknown_document );
@@ -148,6 +154,23 @@ google_firestore_v1_Document LocalSerializer::EncodeDocument(
148
154
return result;
149
155
}
150
156
157
+ Document LocalSerializer::DecodeDocument (
158
+ Reader* reader,
159
+ const google_firestore_v1_Document& proto,
160
+ bool has_committed_mutations) const {
161
+ ObjectValue fields =
162
+ rpc_serializer_.DecodeFields (reader, proto.fields_count , proto.fields );
163
+ SnapshotVersion version =
164
+ rpc_serializer_.DecodeVersion (reader, proto.update_time );
165
+
166
+ DocumentState state = has_committed_mutations
167
+ ? DocumentState::kCommittedMutations
168
+ : DocumentState::kSynced ;
169
+ return Document (std::move (fields),
170
+ rpc_serializer_.DecodeKey (reader, proto.name ), version,
171
+ state);
172
+ }
173
+
151
174
firestore_client_NoDocument LocalSerializer::EncodeNoDocument (
152
175
const NoDocument& no_doc) const {
153
176
firestore_client_NoDocument result{};
@@ -159,15 +182,14 @@ firestore_client_NoDocument LocalSerializer::EncodeNoDocument(
159
182
}
160
183
161
184
NoDocument LocalSerializer::DecodeNoDocument (
162
- Reader* reader, const firestore_client_NoDocument& proto) const {
185
+ Reader* reader,
186
+ const firestore_client_NoDocument& proto,
187
+ bool has_committed_mutations) const {
163
188
SnapshotVersion version =
164
189
rpc_serializer_.DecodeVersion (reader, proto.read_time );
165
190
166
- // TODO(rsgowman): Fix hardcoding of has_committed_mutations.
167
- // Instead, we should grab this from the proto (see other ports). However,
168
- // we'll defer until the nanopb-master gets merged to master.
169
191
return NoDocument (rpc_serializer_.DecodeKey (reader, proto.name ), version,
170
- /* has_committed_mutations= */ false );
192
+ has_committed_mutations);
171
193
}
172
194
173
195
firestore_client_UnknownDocument LocalSerializer::EncodeUnknownDocument (
@@ -203,13 +225,8 @@ firestore_client_Target LocalSerializer::EncodeQueryData(
203
225
204
226
const Query& query = query_data.query ();
205
227
if (query.IsDocumentQuery ()) {
206
- // TODO(rsgowman): Implement. Probably like this (once EncodeDocumentsTarget
207
- // exists):
208
- /*
209
- result.which_target_type = firestore_client_Target_document_tag;
228
+ result.which_target_type = firestore_client_Target_documents_tag;
210
229
result.documents = rpc_serializer_.EncodeDocumentsTarget (query);
211
- */
212
- abort ();
213
230
} else {
214
231
result.which_target_type = firestore_client_Target_query_tag;
215
232
result.query = rpc_serializer_.EncodeQueryTarget (query);
@@ -223,7 +240,6 @@ QueryData LocalSerializer::DecodeQueryData(
223
240
if (!reader->status ().ok ()) return QueryData::Invalid ();
224
241
225
242
model::TargetId target_id = proto.target_id ;
226
- // TODO(rgowman): How to handle truncation of integer types?
227
243
model::ListenSequenceNumber sequence_number =
228
244
static_cast <model::ListenSequenceNumber>(
229
245
proto.last_listen_sequence_number );
@@ -238,8 +254,8 @@ QueryData LocalSerializer::DecodeQueryData(
238
254
break ;
239
255
240
256
case firestore_client_Target_documents_tag:
241
- // TODO(rsgowman): Implement.
242
- abort () ;
257
+ query = rpc_serializer_. DecodeDocumentsTarget (reader, proto. documents );
258
+ break ;
243
259
244
260
default :
245
261
reader->Fail (
@@ -303,6 +319,16 @@ MutationBatch LocalSerializer::DecodeMutationBatch(
303
319
std::move (mutations));
304
320
}
305
321
322
+ google_protobuf_Timestamp LocalSerializer::EncodeVersion (
323
+ const model::SnapshotVersion& version) const {
324
+ return rpc_serializer_.EncodeVersion (version);
325
+ }
326
+
327
+ model::SnapshotVersion LocalSerializer::DecodeVersion (
328
+ nanopb::Reader* reader, const google_protobuf_Timestamp& proto) const {
329
+ return rpc_serializer_.DecodeVersion (reader, proto);
330
+ }
331
+
306
332
} // namespace local
307
333
} // namespace firestore
308
334
} // namespace firebase
0 commit comments