17
17
#include " Firestore/core/src/firebase/firestore/local/local_serializer.h"
18
18
19
19
#include < cstdlib>
20
+ #include < string>
20
21
#include < utility>
21
22
22
23
#include " Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h"
23
24
#include " Firestore/Protos/nanopb/google/firestore/v1beta1/document.nanopb.h"
24
25
#include " Firestore/core/src/firebase/firestore/model/field_value.h"
25
26
#include " Firestore/core/src/firebase/firestore/model/no_document.h"
27
+ #include " Firestore/core/src/firebase/firestore/model/snapshot_version.h"
26
28
#include " Firestore/core/src/firebase/firestore/nanopb/tag.h"
27
29
#include " Firestore/core/src/firebase/firestore/util/hard_assert.h"
28
30
@@ -31,6 +33,7 @@ namespace firestore {
31
33
namespace local {
32
34
33
35
using firebase::firestore::model::ObjectValue;
36
+ using firebase::firestore::model::SnapshotVersion;
34
37
using firebase::firestore::nanopb::Reader;
35
38
using firebase::firestore::nanopb::Tag;
36
39
using firebase::firestore::nanopb::Writer;
@@ -56,8 +59,13 @@ void LocalSerializer::EncodeMaybeDocument(
56
59
return ;
57
60
58
61
case model::MaybeDocument::Type::NoDocument:
59
- // TODO(rsgowman)
60
- abort ();
62
+ writer->WriteTag (
63
+ {PB_WT_STRING, firestore_client_MaybeDocument_no_document_tag});
64
+ writer->WriteNestedMessage ([&](Writer* writer) {
65
+ EncodeNoDocument (writer,
66
+ static_cast <const model::NoDocument&>(maybe_doc));
67
+ });
68
+ return ;
61
69
62
70
case model::MaybeDocument::Type::Unknown:
63
71
// TODO(rsgowman)
@@ -90,7 +98,7 @@ std::unique_ptr<model::MaybeDocument> LocalSerializer::DecodeMaybeDocument(
90
98
// claim that if both are set on the wire, the last one wins.
91
99
no_document = nullptr ;
92
100
93
- // TODO(rsgowman): If multiple '_document ' values are found, we should
101
+ // TODO(rsgowman): If multiple 'document ' values are found, we should
94
102
// merge them (rather than using the last one.)
95
103
document = reader->ReadNestedMessage <std::unique_ptr<model::Document>>(
96
104
[&](Reader* reader) -> std::unique_ptr<model::Document> {
@@ -106,8 +114,12 @@ std::unique_ptr<model::MaybeDocument> LocalSerializer::DecodeMaybeDocument(
106
114
// claim that if both are set on the wire, the last one wins.
107
115
document = nullptr ;
108
116
109
- // TODO(rsgowman): Parse the no_document field.
110
- abort ();
117
+ // TODO(rsgowman): If multiple 'no_document' values are found, we should
118
+ // merge them (rather than using the last one.)
119
+ no_document =
120
+ reader->ReadNestedMessage <std::unique_ptr<model::NoDocument>>(
121
+ [&](Reader* reader) { return DecodeNoDocument (reader); });
122
+ break ;
111
123
112
124
break ;
113
125
@@ -155,6 +167,19 @@ void LocalSerializer::EncodeDocument(Writer* writer,
155
167
// Ignore Document.create_time. (We don't use this in our on-disk protos.)
156
168
}
157
169
170
+ void LocalSerializer::EncodeNoDocument (Writer* writer,
171
+ const model::NoDocument& no_doc) const {
172
+ // Encode NoDocument.name
173
+ writer->WriteTag ({PB_WT_STRING, firestore_client_NoDocument_name_tag});
174
+ writer->WriteString (rpc_serializer_.EncodeKey (no_doc.key ()));
175
+
176
+ // Encode NoDocument.read_time
177
+ writer->WriteTag ({PB_WT_STRING, firestore_client_NoDocument_read_time_tag});
178
+ writer->WriteNestedMessage ([&](Writer* writer) {
179
+ rpc_serializer_.EncodeVersion (writer, no_doc.version ());
180
+ });
181
+ }
182
+
158
183
util::StatusOr<std::unique_ptr<model::MaybeDocument>>
159
184
LocalSerializer::DecodeMaybeDocument (const uint8_t * bytes,
160
185
size_t length) const {
@@ -168,6 +193,41 @@ LocalSerializer::DecodeMaybeDocument(const uint8_t* bytes,
168
193
}
169
194
}
170
195
196
+ std::unique_ptr<model::NoDocument> LocalSerializer::DecodeNoDocument (
197
+ Reader* reader) const {
198
+ if (!reader->status ().ok ()) return nullptr ;
199
+
200
+ std::string name;
201
+ SnapshotVersion version = SnapshotVersion::None ();
202
+
203
+ while (reader->bytes_left ()) {
204
+ Tag tag = reader->ReadTag ();
205
+ if (!reader->status ().ok ()) return nullptr ;
206
+
207
+ // Ensure the tag matches the wire type
208
+ switch (tag.field_number ) {
209
+ case firestore_client_NoDocument_name_tag:
210
+ if (!reader->RequireWireType (PB_WT_STRING, tag)) return nullptr ;
211
+ name = reader->ReadString ();
212
+ break ;
213
+
214
+ case firestore_client_NoDocument_read_time_tag:
215
+ if (!reader->RequireWireType (PB_WT_STRING, tag)) return nullptr ;
216
+ version = SnapshotVersion{reader->ReadNestedMessage <Timestamp>(
217
+ rpc_serializer_.DecodeTimestamp )};
218
+ break ;
219
+
220
+ default :
221
+ // Unknown tag. According to the proto spec, we need to ignore these.
222
+ reader->SkipField (tag);
223
+ break ;
224
+ }
225
+ }
226
+
227
+ return absl::make_unique<model::NoDocument>(rpc_serializer_.DecodeKey (name),
228
+ version);
229
+ }
230
+
171
231
} // namespace local
172
232
} // namespace firestore
173
233
} // namespace firebase
0 commit comments