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,7 +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;
26
+ using model::DocumentKey;
27
+ using model::GetLocalWriteTime;
28
+ using model::GetPreviousValue;
29
+ using model::IsServerTimestamp;
30
+ using nanopb::MakeString;
31
+ using nanopb::Message;
24
32
25
33
DocumentSnapshotInternal::DocumentSnapshotInternal (
26
34
api::DocumentSnapshot&& snapshot)
@@ -55,12 +63,11 @@ bool DocumentSnapshotInternal::exists() const { return snapshot_.exists(); }
55
63
56
64
MapFieldValue DocumentSnapshotInternal::GetData (
57
65
ServerTimestampBehavior stb) const {
58
- using Map = model::FieldValue::Map;
66
+ absl::optional<google_firestore_v1_Value> data =
67
+ snapshot_.GetValue (model::FieldPath::EmptyPath ());
68
+ if (!data) return MapFieldValue{};
59
69
60
- absl::optional<model::ObjectValue> maybe_object = snapshot_.GetData ();
61
- const Map& map =
62
- maybe_object ? maybe_object.value ().GetInternalValue () : Map{};
63
- FieldValue result = ConvertObject (map, stb);
70
+ FieldValue result = ConvertObject (data->map_value , stb);
64
71
SIMPLE_HARD_ASSERT (result.type () == FieldValue::Type::kMap ,
65
72
" Expected snapshot data to parse to a map" );
66
73
return result.map_value ();
@@ -73,7 +80,8 @@ FieldValue DocumentSnapshotInternal::Get(const FieldPath& field,
73
80
74
81
FieldValue DocumentSnapshotInternal::GetValue (
75
82
const model::FieldPath& path, ServerTimestampBehavior stb) const {
76
- absl::optional<model::FieldValue> maybe_value = snapshot_.GetValue (path);
83
+ absl::optional<google_firestore_v1_Value> maybe_value =
84
+ snapshot_.GetValue (path);
77
85
if (maybe_value) {
78
86
return ConvertAnyValue (std::move (maybe_value).value (), stb);
79
87
} else {
@@ -84,95 +92,111 @@ FieldValue DocumentSnapshotInternal::GetValue(
84
92
// FieldValue parsing
85
93
86
94
FieldValue DocumentSnapshotInternal::ConvertAnyValue (
87
- const model::FieldValue & input, ServerTimestampBehavior stb) const {
88
- switch (input.type () ) {
89
- case Type::Object :
90
- return ConvertObject (input.object_value () , stb);
91
- case Type::Array :
92
- 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);
93
101
default :
94
102
return ConvertScalar (input, stb);
95
103
}
96
104
}
97
105
98
106
FieldValue DocumentSnapshotInternal::ConvertObject (
99
- const model::FieldValue::Map& object, ServerTimestampBehavior stb) const {
107
+ const google_firestore_v1_MapValue& object,
108
+ ServerTimestampBehavior stb) const {
100
109
MapFieldValue result;
101
- for (const auto & kv : object) {
102
- 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);
103
114
}
104
115
105
116
return FieldValue::Map (std::move (result));
106
117
}
107
118
108
119
FieldValue DocumentSnapshotInternal::ConvertArray (
109
- const model::FieldValue::Array& array, ServerTimestampBehavior stb) const {
120
+ const google_firestore_v1_ArrayValue& array,
121
+ ServerTimestampBehavior stb) const {
110
122
std::vector<FieldValue> result;
111
- for (const auto & value : array) {
112
- 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));
113
125
}
114
126
115
127
return FieldValue::Array (std::move (result));
116
128
}
117
129
118
130
FieldValue DocumentSnapshotInternal::ConvertScalar (
119
- const model::FieldValue& scalar, ServerTimestampBehavior stb) const {
120
- switch (scalar.type ()) {
121
- 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
+ }
122
138
return FieldValue::Null ();
123
- case Type::Boolean:
124
- return FieldValue::Boolean (scalar.boolean_value ());
125
- case Type::Integer:
126
- return FieldValue::Integer (scalar.integer_value ());
127
- case Type::Double:
128
- return FieldValue::Double (scalar.double_value ());
129
- case Type::String:
130
- return FieldValue::String (scalar.string_value ());
131
- case Type::Timestamp:
132
- return FieldValue::Timestamp (scalar.timestamp_value ());
133
- case Type::GeoPoint:
134
- return FieldValue::GeoPoint (scalar.geo_point_value ());
135
- case Type::Blob:
136
- return FieldValue::Blob (scalar.blob_value ().data (),
137
- scalar.blob_value ().size ());
138
- case Type::Reference:
139
- return ConvertReference (scalar.reference_value ());
140
- case Type::ServerTimestamp:
141
- 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 (scalar.bytes_value ->bytes ,
155
+ scalar.bytes_value ->size )
156
+ : FieldValue::Blob (nullptr , 0 );
157
+ case google_firestore_v1_Value_reference_value_tag:
158
+ return ConvertReference (scalar);
142
159
default : {
143
160
// TODO(b/147444199): use string formatting.
144
161
// HARD_FAIL("Unexpected kind of FieldValue: '%s'", scalar.type());
145
- auto message = std::string (" Unexpected kind of FieldValue: '" ) +
146
- std::to_string (static_cast <int >(scalar.type ())) + " '" ;
162
+ auto message = std::string (" Unexpected kind of FieldValue" );
147
163
SIMPLE_HARD_FAIL (message);
148
164
}
149
165
}
150
166
}
151
167
152
168
FieldValue DocumentSnapshotInternal::ConvertReference (
153
- const model::FieldValue::Reference& reference) const {
154
- SIMPLE_HARD_ASSERT (
155
- reference.database_id () == firestore_internal ()->database_id (),
156
- " 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" );
157
176
158
- api::DocumentReference api_reference{reference. key () , snapshot_.firestore ()};
177
+ api::DocumentReference api_reference{key, snapshot_.firestore ()};
159
178
return FieldValue::Reference (MakePublic (std::move (api_reference)));
160
179
}
161
180
162
181
FieldValue DocumentSnapshotInternal::ConvertServerTimestamp (
163
- const model::FieldValue::ServerTimestamp & server_timestamp,
182
+ const google_firestore_v1_Value & server_timestamp,
164
183
ServerTimestampBehavior stb) const {
165
184
switch (stb) {
166
185
case ServerTimestampBehavior::kNone :
167
186
return FieldValue::Null ();
168
187
case ServerTimestampBehavior::kEstimate : {
169
- return FieldValue::Timestamp (server_timestamp.local_write_time ());
188
+ google_protobuf_Timestamp timestamp = GetLocalWriteTime (server_timestamp);
189
+ return FieldValue::Timestamp (
190
+ Timestamp (timestamp.seconds , timestamp.nanos ));
170
191
}
171
- case ServerTimestampBehavior::kPrevious :
172
- if (server_timestamp.previous_value ()) {
173
- return ConvertScalar (server_timestamp.previous_value ().value (), stb);
192
+ case ServerTimestampBehavior::kPrevious : {
193
+ absl::optional<google_firestore_v1_Value> previous_value =
194
+ GetPreviousValue (server_timestamp);
195
+ if (previous_value) {
196
+ return ConvertScalar (*previous_value, stb);
174
197
}
175
198
return FieldValue::Null ();
199
+ }
176
200
}
177
201
FIRESTORE_UNREACHABLE ();
178
202
}
0 commit comments