8
8
#include " Firestore/core/src/model/database_id.h"
9
9
#include " Firestore/core/src/model/document_key.h"
10
10
#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"
12
12
#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"
13
15
#include " absl/memory/memory.h"
14
16
#include " firestore/src/common/macros.h"
15
17
#include " firestore/src/include/firebase/firestore.h"
@@ -20,8 +22,13 @@ namespace firebase {
20
22
namespace firestore {
21
23
22
24
using ServerTimestampBehavior = DocumentSnapshot::ServerTimestampBehavior;
23
- using Type = model::FieldValue::Type ;
25
+ using model::DatabaseId ;
24
26
using model::DocumentKey;
27
+ using model::GetLocalWriteTime;
28
+ using model::GetPreviousValue;
29
+ using model::IsServerTimestamp;
30
+ using nanopb::MakeString;
31
+ using nanopb::Message;
25
32
26
33
DocumentSnapshotInternal::DocumentSnapshotInternal (
27
34
api::DocumentSnapshot&& snapshot)
@@ -56,12 +63,11 @@ bool DocumentSnapshotInternal::exists() const { return snapshot_.exists(); }
56
63
57
64
MapFieldValue DocumentSnapshotInternal::GetData (
58
65
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{};
60
69
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);
65
71
SIMPLE_HARD_ASSERT (result.type () == FieldValue::Type::kMap ,
66
72
" Expected snapshot data to parse to a map" );
67
73
return result.map_value ();
@@ -74,7 +80,8 @@ FieldValue DocumentSnapshotInternal::Get(const FieldPath& field,
74
80
75
81
FieldValue DocumentSnapshotInternal::GetValue (
76
82
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);
78
85
if (maybe_value) {
79
86
return ConvertAnyValue (std::move (maybe_value).value (), stb);
80
87
} else {
@@ -85,93 +92,107 @@ FieldValue DocumentSnapshotInternal::GetValue(
85
92
// FieldValue parsing
86
93
87
94
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);
94
101
default :
95
102
return ConvertScalar (input, stb);
96
103
}
97
104
}
98
105
99
106
FieldValue DocumentSnapshotInternal::ConvertObject (
100
- const model::FieldValue::Map& object, ServerTimestampBehavior stb) const {
107
+ const google_firestore_v1_MapValue& object,
108
+ ServerTimestampBehavior stb) const {
101
109
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);
104
114
}
105
115
106
116
return FieldValue::Map (std::move (result));
107
117
}
108
118
109
119
FieldValue DocumentSnapshotInternal::ConvertArray (
110
- const model::FieldValue::Array& array, ServerTimestampBehavior stb) const {
120
+ const google_firestore_v1_ArrayValue& array,
121
+ ServerTimestampBehavior stb) const {
111
122
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));
114
125
}
115
126
116
127
return FieldValue::Array (std::move (result));
117
128
}
118
129
119
130
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
+ }
123
138
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);
143
159
default : {
144
160
// TODO(b/147444199): use string formatting.
145
161
// 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" );
148
163
SIMPLE_HARD_FAIL (message);
149
164
}
150
165
}
151
166
}
152
167
153
168
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" );
158
176
159
- api::DocumentReference api_reference{reference. key () , snapshot_.firestore ()};
177
+ api::DocumentReference api_reference{key, snapshot_.firestore ()};
160
178
return FieldValue::Reference (MakePublic (std::move (api_reference)));
161
179
}
162
180
163
181
FieldValue DocumentSnapshotInternal::ConvertServerTimestamp (
164
- const model::FieldValue::ServerTimestamp & server_timestamp,
182
+ const google_firestore_v1_Value & server_timestamp,
165
183
ServerTimestampBehavior stb) const {
166
184
switch (stb) {
167
185
case ServerTimestampBehavior::kNone :
168
186
return FieldValue::Null ();
169
187
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 ));
171
191
}
172
192
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);
175
196
}
176
197
return FieldValue::Null ();
177
198
}
0 commit comments