Skip to content

Commit 9ced69b

Browse files
authored
Make Serializer fully support converting FieldValues (#3659)
This involved support for reference values and taking server timestamps into account (by crashing, because they are not supposed to ever be serialized). The biggest change is from making every function that decodes a `FieldValue` a member function (as well as any function called by those functions). That is because decoding a reference requires comparing database IDs, and the database ID of this Firestore instance is stored on the `Serializer`.
1 parent 01f49c3 commit 9ced69b

File tree

11 files changed

+390
-203
lines changed

11 files changed

+390
-203
lines changed

Firestore/Source/Remote/FSTSerializerBeta.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ - (FieldValue)decodedReferenceValue:(NSString *)resourceName {
390390
const DocumentKey key{[self localResourcePathForQualifiedResourcePath:path]};
391391

392392
const DatabaseId database_id(project, database);
393-
HARD_ASSERT(database_id == _databaseID, "Database %s:%s cannot encode reference from %s:%s",
393+
HARD_ASSERT(database_id == _databaseID, "Database %s:%s cannot decode reference from %s:%s",
394394
_databaseID.project_id(), _databaseID.database_id(), database_id.project_id(),
395395
database_id.database_id());
396396
return FieldValue::FromReference(_databaseID, key);

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ google_firestore_v1_Document LocalSerializer::EncodeDocument(
123123
const Document& doc) const {
124124
google_firestore_v1_Document result{};
125125

126-
result.name =
127-
rpc_serializer_.EncodeString(rpc_serializer_.EncodeKey(doc.key()));
126+
result.name = rpc_serializer_.EncodeKey(doc.key());
128127

129128
// Encode Document.fields (unless it's empty)
130129
pb_size_t count = CheckedSize(doc.data().GetInternalValue().size());
@@ -148,8 +147,7 @@ firestore_client_NoDocument LocalSerializer::EncodeNoDocument(
148147
const NoDocument& no_doc) const {
149148
firestore_client_NoDocument result{};
150149

151-
result.name =
152-
rpc_serializer_.EncodeString(rpc_serializer_.EncodeKey(no_doc.key()));
150+
result.name = rpc_serializer_.EncodeKey(no_doc.key());
153151
result.read_time = rpc_serializer_.EncodeVersion(no_doc.version());
154152

155153
return result;
@@ -163,18 +161,15 @@ NoDocument LocalSerializer::DecodeNoDocument(
163161
// TODO(rsgowman): Fix hardcoding of has_committed_mutations.
164162
// Instead, we should grab this from the proto (see other ports). However,
165163
// we'll defer until the nanopb-master gets merged to master.
166-
return NoDocument(rpc_serializer_.DecodeKey(
167-
reader, rpc_serializer_.DecodeString(proto.name)),
168-
version,
164+
return NoDocument(rpc_serializer_.DecodeKey(reader, proto.name), version,
169165
/*has_committed_mutations=*/false);
170166
}
171167

172168
firestore_client_UnknownDocument LocalSerializer::EncodeUnknownDocument(
173169
const UnknownDocument& unknown_doc) const {
174170
firestore_client_UnknownDocument result{};
175171

176-
result.name = rpc_serializer_.EncodeString(
177-
rpc_serializer_.EncodeKey(unknown_doc.key()));
172+
result.name = rpc_serializer_.EncodeKey(unknown_doc.key());
178173
result.version = rpc_serializer_.EncodeVersion(unknown_doc.version());
179174

180175
return result;
@@ -185,8 +180,7 @@ UnknownDocument LocalSerializer::DecodeUnknownDocument(
185180
SnapshotVersion version =
186181
rpc_serializer_.DecodeSnapshotVersion(reader, proto.version);
187182

188-
return UnknownDocument(rpc_serializer_.DecodeKey(
189-
reader, rpc_serializer_.DecodeString(proto.name)),
183+
return UnknownDocument(rpc_serializer_.DecodeKey(reader, proto.name),
190184
version);
191185
}
192186

Firestore/core/src/firebase/firestore/model/database_id.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#include "Firestore/core/src/firebase/firestore/model/database_id.h"
1818

19+
#include <ostream>
20+
1921
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
2022
#include "Firestore/core/src/firebase/firestore/util/hashing.h"
2123

@@ -40,6 +42,14 @@ util::ComparisonResult DatabaseId::CompareTo(
4042
return util::Compare(database_id(), rhs.database_id());
4143
}
4244

45+
std::string DatabaseId::ToString() const {
46+
return absl::StrCat("DatabaseId(", project_id(), ":", database_id(), ")");
47+
}
48+
49+
std::ostream& operator<<(std::ostream& out, const DatabaseId& database_id) {
50+
return out << database_id.ToString();
51+
}
52+
4353
size_t DatabaseId::Hash() const {
4454
return util::Hash(project_id(), database_id());
4555
}

Firestore/core/src/firebase/firestore/model/database_id.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DATABASE_ID_H_
1818
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DATABASE_ID_H_
1919

20+
#include <iosfwd>
2021
#include <memory>
2122
#include <string>
2223
#include <utility>
@@ -60,6 +61,10 @@ class DatabaseId : public util::Comparable<DatabaseId> {
6061

6162
util::ComparisonResult CompareTo(const DatabaseId& rhs) const;
6263

64+
std::string ToString() const;
65+
friend std::ostream& operator<<(std::ostream& out,
66+
const DatabaseId& database_id);
67+
6368
size_t Hash() const;
6469

6570
private:

Firestore/core/src/firebase/firestore/nanopb/byte_string.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
#include "Firestore/core/src/firebase/firestore/nanopb/byte_string.h"
1818

19+
#include <cctype>
1920
#include <cstdlib>
2021
#include <cstring>
22+
#include <iomanip>
2123
#include <ostream>
24+
#include <sstream>
2225

2326
#include "Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h"
2427
#include "Firestore/core/src/firebase/firestore/util/hashing.h"
@@ -87,14 +90,18 @@ size_t ByteString::Hash() const {
8790
}
8891

8992
std::string ByteString::ToString() const {
90-
std::string hex = absl::BytesToHexString(MakeStringView(*this));
91-
return absl::StrCat("<", hex, ">");
93+
return absl::CEscape(MakeStringView(*this));
9294
}
9395

9496
std::ostream& operator<<(std::ostream& out, const ByteString& str) {
9597
return out << str.ToString();
9698
}
9799

100+
std::string ByteString::ToHexString() const {
101+
std::string hex = absl::BytesToHexString(MakeStringView(*this));
102+
return absl::StrCat("<", hex, ">");
103+
}
104+
98105
} // namespace nanopb
99106
} // namespace firestore
100107
} // namespace firebase

Firestore/core/src/firebase/firestore/nanopb/byte_string.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,14 @@ class ByteString : public util::Comparable<ByteString> {
147147

148148
size_t Hash() const;
149149

150+
// Interprets the value as an ASCII string; the way control characters are
151+
// represented is implementation-defined.
150152
std::string ToString() const;
151153
friend std::ostream& operator<<(std::ostream& out, const ByteString& str);
152154

155+
// Represents the value as hexademical values.
156+
std::string ToHexString() const;
157+
153158
private:
154159
/**
155160
* Private constructor directly assigns to bytes_. The extra integer tag

0 commit comments

Comments
 (0)