Skip to content

Commit c04693f

Browse files
Migrate CPP SDK from FieldValue to Protobuf
1 parent ba9d52e commit c04693f

9 files changed

+389
-254
lines changed

firestore/src/main/document_snapshot_main.cc

Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
#include "Firestore/core/src/model/database_id.h"
99
#include "Firestore/core/src/model/document_key.h"
1010
#include "Firestore/core/src/model/field_path.h"
11-
#include "Firestore/core/src/model/field_value_options.h"
11+
#include "Firestore/core/src/model/server_timestamp_util.h"
1212
#include "Firestore/core/src/nanopb/byte_string.h"
13+
#include "Firestore/core/src/nanopb/message.h"
14+
#include "Firestore/core/src/nanopb/nanopb_util.h"
1315
#include "absl/memory/memory.h"
1416
#include "firestore/src/common/macros.h"
1517
#include "firestore/src/include/firebase/firestore.h"
@@ -20,8 +22,13 @@ namespace firebase {
2022
namespace firestore {
2123

2224
using ServerTimestampBehavior = DocumentSnapshot::ServerTimestampBehavior;
23-
using Type = model::FieldValue::Type;
25+
using model::DatabaseId;
2426
using model::DocumentKey;
27+
using model::GetLocalWriteTime;
28+
using model::GetPreviousValue;
29+
using model::IsServerTimestamp;
30+
using nanopb::MakeString;
31+
using nanopb::Message;
2532

2633
DocumentSnapshotInternal::DocumentSnapshotInternal(
2734
api::DocumentSnapshot&& snapshot)
@@ -56,12 +63,11 @@ bool DocumentSnapshotInternal::exists() const { return snapshot_.exists(); }
5663

5764
MapFieldValue DocumentSnapshotInternal::GetData(
5865
ServerTimestampBehavior stb) const {
59-
using Map = model::FieldValue::Map;
66+
absl::optional<google_firestore_v1_Value> data =
67+
snapshot_.GetValue(model::FieldPath::EmptyPath());
68+
if (!data) return MapFieldValue{};
6069

61-
absl::optional<model::ObjectValue> maybe_object = snapshot_.GetData();
62-
const Map& map =
63-
maybe_object ? maybe_object.value().GetInternalValue() : Map{};
64-
FieldValue result = ConvertObject(map, stb);
70+
FieldValue result = ConvertObject(data->map_value, stb);
6571
SIMPLE_HARD_ASSERT(result.type() == FieldValue::Type::kMap,
6672
"Expected snapshot data to parse to a map");
6773
return result.map_value();
@@ -74,7 +80,8 @@ FieldValue DocumentSnapshotInternal::Get(const FieldPath& field,
7480

7581
FieldValue DocumentSnapshotInternal::GetValue(
7682
const model::FieldPath& path, ServerTimestampBehavior stb) const {
77-
absl::optional<model::FieldValue> maybe_value = snapshot_.GetValue(path);
83+
absl::optional<google_firestore_v1_Value> maybe_value =
84+
snapshot_.GetValue(path);
7885
if (maybe_value) {
7986
return ConvertAnyValue(std::move(maybe_value).value(), stb);
8087
} else {
@@ -85,93 +92,107 @@ FieldValue DocumentSnapshotInternal::GetValue(
8592
// FieldValue parsing
8693

8794
FieldValue DocumentSnapshotInternal::ConvertAnyValue(
88-
const model::FieldValue& input, ServerTimestampBehavior stb) const {
89-
switch (input.type()) {
90-
case Type::Object:
91-
return ConvertObject(input.object_value(), stb);
92-
case Type::Array:
93-
return ConvertArray(input.array_value(), stb);
95+
const google_firestore_v1_Value& input, ServerTimestampBehavior stb) const {
96+
switch (input.which_value_type) {
97+
case google_firestore_v1_Value_map_value_tag:
98+
return ConvertObject(input.map_value, stb);
99+
case google_firestore_v1_Value_array_value_tag:
100+
return ConvertArray(input.array_value, stb);
94101
default:
95102
return ConvertScalar(input, stb);
96103
}
97104
}
98105

99106
FieldValue DocumentSnapshotInternal::ConvertObject(
100-
const model::FieldValue::Map& object, ServerTimestampBehavior stb) const {
107+
const google_firestore_v1_MapValue& object,
108+
ServerTimestampBehavior stb) const {
101109
MapFieldValue result;
102-
for (const auto& kv : object) {
103-
result[kv.first] = ConvertAnyValue(kv.second, stb);
110+
for (pb_size_t i = 0; i < object.fields_count; ++i) {
111+
std::string key = MakeString(object.fields[i].key);
112+
const google_firestore_v1_Value& value = object.fields[i].value;
113+
result[key] = ConvertAnyValue(value, stb);
104114
}
105115

106116
return FieldValue::Map(std::move(result));
107117
}
108118

109119
FieldValue DocumentSnapshotInternal::ConvertArray(
110-
const model::FieldValue::Array& array, ServerTimestampBehavior stb) const {
120+
const google_firestore_v1_ArrayValue& array,
121+
ServerTimestampBehavior stb) const {
111122
std::vector<FieldValue> result;
112-
for (const auto& value : array) {
113-
result.push_back(ConvertAnyValue(value, stb));
123+
for (pb_size_t i = 0; i < array.values_count; ++i) {
124+
result.push_back(ConvertAnyValue(array.values[i], stb));
114125
}
115126

116127
return FieldValue::Array(std::move(result));
117128
}
118129

119130
FieldValue DocumentSnapshotInternal::ConvertScalar(
120-
const model::FieldValue& scalar, ServerTimestampBehavior stb) const {
121-
switch (scalar.type()) {
122-
case Type::Null:
131+
const google_firestore_v1_Value& scalar,
132+
ServerTimestampBehavior stb) const {
133+
switch (scalar.which_value_type) {
134+
case google_firestore_v1_Value_map_value_tag:
135+
if (IsServerTimestamp(scalar)) {
136+
return ConvertServerTimestamp(scalar, stb);
137+
}
123138
return FieldValue::Null();
124-
case Type::Boolean:
125-
return FieldValue::Boolean(scalar.boolean_value());
126-
case Type::Integer:
127-
return FieldValue::Integer(scalar.integer_value());
128-
case Type::Double:
129-
return FieldValue::Double(scalar.double_value());
130-
case Type::String:
131-
return FieldValue::String(scalar.string_value());
132-
case Type::Timestamp:
133-
return FieldValue::Timestamp(scalar.timestamp_value());
134-
case Type::GeoPoint:
135-
return FieldValue::GeoPoint(scalar.geo_point_value());
136-
case Type::Blob:
137-
return FieldValue::Blob(scalar.blob_value().data(),
138-
scalar.blob_value().size());
139-
case Type::Reference:
140-
return ConvertReference(scalar.reference_value());
141-
case Type::ServerTimestamp:
142-
return ConvertServerTimestamp(scalar.server_timestamp_value(), stb);
139+
case google_firestore_v1_Value_boolean_value_tag:
140+
return FieldValue::Boolean(scalar.boolean_value);
141+
case google_firestore_v1_Value_integer_value_tag:
142+
return FieldValue::Integer(scalar.integer_value);
143+
case google_firestore_v1_Value_double_value_tag:
144+
return FieldValue::Double(scalar.double_value);
145+
case google_firestore_v1_Value_string_value_tag:
146+
return FieldValue::String(MakeString(scalar.string_value));
147+
case google_firestore_v1_Value_timestamp_value_tag:
148+
return FieldValue::Timestamp(Timestamp(scalar.timestamp_value.seconds,
149+
scalar.timestamp_value.nanos));
150+
case google_firestore_v1_Value_geo_point_value_tag:
151+
return FieldValue::GeoPoint(GeoPoint(scalar.geo_point_value.latitude,
152+
scalar.geo_point_value.longitude));
153+
case google_firestore_v1_Value_bytes_value_tag:
154+
return scalar.bytes_value ? FieldValue::Blob(nullptr, 0)
155+
: FieldValue::Blob(scalar.bytes_value->bytes,
156+
scalar.bytes_value->size);
157+
case google_firestore_v1_Value_reference_value_tag:
158+
return ConvertReference(scalar);
143159
default: {
144160
// TODO(b/147444199): use string formatting.
145161
// HARD_FAIL("Unexpected kind of FieldValue: '%s'", scalar.type());
146-
auto message = std::string("Unexpected kind of FieldValue: '") +
147-
std::to_string(static_cast<int>(scalar.type())) + "'";
162+
auto message = std::string("Unexpected kind of FieldValue");
148163
SIMPLE_HARD_FAIL(message);
149164
}
150165
}
151166
}
152167

153168
FieldValue DocumentSnapshotInternal::ConvertReference(
154-
const model::FieldValue::Reference& reference) const {
155-
SIMPLE_HARD_ASSERT(
156-
reference.database_id() == firestore_internal()->database_id(),
157-
"Converted reference is from another database");
169+
const google_firestore_v1_Value& reference) const {
170+
std::string ref = MakeString(reference.reference_value);
171+
DatabaseId database_id = DatabaseId::FromName(ref);
172+
DocumentKey key = DocumentKey::FromName(ref);
173+
174+
SIMPLE_HARD_ASSERT(database_id == firestore_internal()->database_id(),
175+
"Converted reference is from another database");
158176

159-
api::DocumentReference api_reference{reference.key(), snapshot_.firestore()};
177+
api::DocumentReference api_reference{key, snapshot_.firestore()};
160178
return FieldValue::Reference(MakePublic(std::move(api_reference)));
161179
}
162180

163181
FieldValue DocumentSnapshotInternal::ConvertServerTimestamp(
164-
const model::FieldValue::ServerTimestamp& server_timestamp,
182+
const google_firestore_v1_Value& server_timestamp,
165183
ServerTimestampBehavior stb) const {
166184
switch (stb) {
167185
case ServerTimestampBehavior::kNone:
168186
return FieldValue::Null();
169187
case ServerTimestampBehavior::kEstimate: {
170-
return FieldValue::Timestamp(server_timestamp.local_write_time());
188+
auto timestamp = GetLocalWriteTime(server_timestamp);
189+
return FieldValue::Timestamp(
190+
Timestamp(timestamp.seconds, timestamp.nanos));
171191
}
172192
case ServerTimestampBehavior::kPrevious:
173-
if (server_timestamp.previous_value()) {
174-
return ConvertScalar(server_timestamp.previous_value().value(), stb);
193+
auto previous_value = GetPreviousValue(server_timestamp);
194+
if (previous_value) {
195+
return ConvertScalar(*previous_value, stb);
175196
}
176197
return FieldValue::Null();
177198
}

firestore/src/main/document_snapshot_main.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#include <string>
88
#include <vector>
99

10+
#include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h"
1011
#include "Firestore/core/src/api/document_snapshot.h"
11-
#include "Firestore/core/src/model/field_value.h"
1212
#include "firestore/src/include/firebase/firestore/document_reference.h"
1313
#include "firestore/src/include/firebase/firestore/document_snapshot.h"
1414
#include "firestore/src/include/firebase/firestore/field_value.h"
@@ -53,18 +53,17 @@ class DocumentSnapshotInternal {
5353

5454
// Note: these are member functions only because access to `api::Firestore`
5555
// is needed to create a `DocumentReferenceInternal`.
56-
FieldValue ConvertAnyValue(const model::FieldValue& input,
56+
FieldValue ConvertAnyValue(const google_firestore_v1_Value& input,
5757
ServerTimestampBehavior stb) const;
58-
FieldValue ConvertObject(const model::FieldValue::Map& object,
58+
FieldValue ConvertObject(const google_firestore_v1_MapValue& object,
5959
ServerTimestampBehavior stb) const;
60-
FieldValue ConvertArray(const model::FieldValue::Array& array,
60+
FieldValue ConvertArray(const google_firestore_v1_ArrayValue& array,
6161
ServerTimestampBehavior stb) const;
62-
FieldValue ConvertReference(
63-
const model::FieldValue::Reference& reference) const;
62+
FieldValue ConvertReference(const google_firestore_v1_Value& reference) const;
6463
FieldValue ConvertServerTimestamp(
65-
const model::FieldValue::ServerTimestamp& server_timestamp,
64+
const google_firestore_v1_Value& server_timestamp,
6665
ServerTimestampBehavior stb) const;
67-
FieldValue ConvertScalar(const model::FieldValue& scalar,
66+
FieldValue ConvertScalar(const google_firestore_v1_Value& scalar,
6867
ServerTimestampBehavior stb) const;
6968

7069
api::DocumentSnapshot snapshot_;

0 commit comments

Comments
 (0)