Skip to content

Commit a3f792f

Browse files
authored
Add support for NoDocument in the local serializer (#1484)
1 parent 37edbc6 commit a3f792f

File tree

5 files changed

+202
-114
lines changed

5 files changed

+202
-114
lines changed

Firestore/core/src/firebase/firestore/local/local_serializer.cc

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
#include "Firestore/core/src/firebase/firestore/local/local_serializer.h"
1818

1919
#include <cstdlib>
20+
#include <string>
2021
#include <utility>
2122

2223
#include "Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h"
2324
#include "Firestore/Protos/nanopb/google/firestore/v1beta1/document.nanopb.h"
2425
#include "Firestore/core/src/firebase/firestore/model/field_value.h"
2526
#include "Firestore/core/src/firebase/firestore/model/no_document.h"
27+
#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h"
2628
#include "Firestore/core/src/firebase/firestore/nanopb/tag.h"
2729
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
2830

@@ -31,6 +33,7 @@ namespace firestore {
3133
namespace local {
3234

3335
using firebase::firestore::model::ObjectValue;
36+
using firebase::firestore::model::SnapshotVersion;
3437
using firebase::firestore::nanopb::Reader;
3538
using firebase::firestore::nanopb::Tag;
3639
using firebase::firestore::nanopb::Writer;
@@ -56,8 +59,13 @@ void LocalSerializer::EncodeMaybeDocument(
5659
return;
5760

5861
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;
6169

6270
case model::MaybeDocument::Type::Unknown:
6371
// TODO(rsgowman)
@@ -90,7 +98,7 @@ std::unique_ptr<model::MaybeDocument> LocalSerializer::DecodeMaybeDocument(
9098
// claim that if both are set on the wire, the last one wins.
9199
no_document = nullptr;
92100

93-
// TODO(rsgowman): If multiple '_document' values are found, we should
101+
// TODO(rsgowman): If multiple 'document' values are found, we should
94102
// merge them (rather than using the last one.)
95103
document = reader->ReadNestedMessage<std::unique_ptr<model::Document>>(
96104
[&](Reader* reader) -> std::unique_ptr<model::Document> {
@@ -106,8 +114,12 @@ std::unique_ptr<model::MaybeDocument> LocalSerializer::DecodeMaybeDocument(
106114
// claim that if both are set on the wire, the last one wins.
107115
document = nullptr;
108116

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;
111123

112124
break;
113125

@@ -155,6 +167,19 @@ void LocalSerializer::EncodeDocument(Writer* writer,
155167
// Ignore Document.create_time. (We don't use this in our on-disk protos.)
156168
}
157169

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+
158183
util::StatusOr<std::unique_ptr<model::MaybeDocument>>
159184
LocalSerializer::DecodeMaybeDocument(const uint8_t* bytes,
160185
size_t length) const {
@@ -168,6 +193,41 @@ LocalSerializer::DecodeMaybeDocument(const uint8_t* bytes,
168193
}
169194
}
170195

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+
171231
} // namespace local
172232
} // namespace firestore
173233
} // namespace firebase

Firestore/core/src/firebase/firestore/local/local_serializer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
#include <memory>
2121
#include <vector>
2222

23+
#include "Firestore/core/src/firebase/firestore/model/document.h"
2324
#include "Firestore/core/src/firebase/firestore/model/maybe_document.h"
25+
#include "Firestore/core/src/firebase/firestore/model/no_document.h"
2426
#include "Firestore/core/src/firebase/firestore/nanopb/reader.h"
2527
#include "Firestore/core/src/firebase/firestore/nanopb/writer.h"
2628
#include "Firestore/core/src/firebase/firestore/remote/serializer.h"
@@ -99,6 +101,12 @@ class LocalSerializer {
99101
*/
100102
void EncodeDocument(nanopb::Writer* writer, const model::Document& doc) const;
101103

104+
void EncodeNoDocument(nanopb::Writer* writer,
105+
const model::NoDocument& no_doc) const;
106+
107+
std::unique_ptr<model::NoDocument> DecodeNoDocument(
108+
nanopb::Reader* reader) const;
109+
102110
const remote::Serializer& rpc_serializer_;
103111
};
104112

0 commit comments

Comments
 (0)