Skip to content

Commit 6cd4f44

Browse files
authored
Create ObjectValue as a wrapper around a FieldValue which contains a map (#2527)
1 parent fd8947c commit 6cd4f44

File tree

16 files changed

+222
-231
lines changed

16 files changed

+222
-231
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ using model::MaybeDocument;
4242
using model::Mutation;
4343
using model::MutationBatch;
4444
using model::NoDocument;
45-
using model::ObjectValue;
4645
using model::SnapshotVersion;
4746
using model::UnknownDocument;
4847
using nanopb::Reader;
@@ -124,13 +123,13 @@ google_firestore_v1_Document LocalSerializer::EncodeDocument(
124123
rpc_serializer_.EncodeString(rpc_serializer_.EncodeKey(doc.key()));
125124

126125
// Encode Document.fields (unless it's empty)
127-
size_t count = doc.data().object_value().internal_value.size();
126+
size_t count = doc.data().GetInternalValue().size();
128127
HARD_ASSERT(count <= std::numeric_limits<pb_size_t>::max(),
129128
"Unable to encode specified document. Too many fields.");
130129
result.fields_count = static_cast<pb_size_t>(count);
131130
result.fields = MakeArray<google_firestore_v1_Document_FieldsEntry>(count);
132131
int i = 0;
133-
for (const auto& kv : doc.data().object_value().internal_value) {
132+
for (const auto& kv : doc.data().GetInternalValue()) {
134133
result.fields[i].key = rpc_serializer_.EncodeString(kv.first);
135134
result.fields[i].value = rpc_serializer_.EncodeFieldValue(kv.second);
136135
i++;

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,14 @@ namespace firebase {
2424
namespace firestore {
2525
namespace model {
2626

27-
Document::Document(FieldValue&& data,
27+
Document::Document(ObjectValue&& data,
2828
DocumentKey key,
2929
SnapshotVersion version,
3030
DocumentState document_state)
3131
: MaybeDocument(std::move(key), std::move(version)),
3232
data_(std::move(data)),
3333
document_state_(document_state) {
3434
set_type(Type::Document);
35-
HARD_ASSERT(FieldValue::Type::Object == data.type());
3635
}
3736

3837
bool Document::Equals(const MaybeDocument& other) const {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ enum class DocumentState {
5050
class Document : public MaybeDocument {
5151
public:
5252
/**
53-
* Construct a document. FieldValue must be passed by rvalue.
53+
* Construct a document. ObjectValue must be passed by rvalue.
5454
*/
55-
Document(FieldValue&& data,
55+
Document(ObjectValue&& data,
5656
DocumentKey key,
5757
SnapshotVersion version,
5858
DocumentState document_state);
5959

60-
const FieldValue& data() const {
60+
const ObjectValue& data() const {
6161
return data_;
6262
}
6363

@@ -81,7 +81,7 @@ class Document : public MaybeDocument {
8181
bool Equals(const MaybeDocument& other) const override;
8282

8383
private:
84-
FieldValue data_; // This is of type Object.
84+
ObjectValue data_;
8585
DocumentState document_state_;
8686
};
8787

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

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <utility>
2424
#include <vector>
2525

26+
#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h"
2627
#include "Firestore/core/src/firebase/firestore/util/comparison.h"
2728
#include "Firestore/core/src/firebase/firestore/util/hard_assert.h"
2829
#include "absl/memory/memory.h"
@@ -91,8 +92,8 @@ FieldValue& FieldValue::operator=(const FieldValue& value) {
9192
}
9293
case Type::Object: {
9394
// copy-and-swap
94-
ObjectValue::Map tmp = value.object_value_->internal_value;
95-
std::swap(object_value_->internal_value, tmp);
95+
Map tmp = *value.object_value_;
96+
std::swap(*object_value_, tmp);
9697
break;
9798
}
9899
default:
@@ -143,45 +144,41 @@ bool FieldValue::Comparable(Type lhs, Type rhs) {
143144
}
144145
}
145146

146-
FieldValue FieldValue::Set(const FieldPath& field_path,
147-
const FieldValue& value) const {
148-
HARD_ASSERT(type() == Type::Object,
149-
"Cannot set field for non-object FieldValue");
147+
// TODO(rsgowman): Reorder this file to match its header.
148+
ObjectValue ObjectValue::Set(const FieldPath& field_path,
149+
const FieldValue& value) const {
150150
HARD_ASSERT(!field_path.empty(),
151151
"Cannot set field for empty path on FieldValue");
152152
// Set the value by recursively calling on child object.
153153
const std::string& child_name = field_path.first_segment();
154-
const ObjectValue::Map& object_map = object_value_->internal_value;
155154
if (field_path.size() == 1) {
156155
return SetChild(child_name, value);
157156
} else {
158-
FieldValue child;
159-
const auto iter = object_map.find(child_name);
160-
if (iter != object_map.end() && iter->second.type() == Type::Object) {
161-
child = iter->second;
162-
} else {
163-
child = EmptyObject();
157+
ObjectValue child = ObjectValue::Empty();
158+
const auto iter = fv_.object_value_->find(child_name);
159+
if (iter != fv_.object_value_->end() &&
160+
iter->second.type() == Type::Object) {
161+
child = ObjectValue(iter->second);
164162
}
165-
FieldValue new_child = child.Set(field_path.PopFirst(), value);
166-
return SetChild(child_name, new_child);
163+
ObjectValue new_child = child.Set(field_path.PopFirst(), value);
164+
return SetChild(child_name, new_child.fv_);
167165
}
168166
}
169167

170-
FieldValue FieldValue::Delete(const FieldPath& field_path) const {
171-
HARD_ASSERT(type() == Type::Object,
172-
"Cannot delete field for non-object FieldValue");
168+
ObjectValue ObjectValue::Delete(const FieldPath& field_path) const {
173169
HARD_ASSERT(!field_path.empty(),
174170
"Cannot delete field for empty path on FieldValue");
175171
// Delete the value by recursively calling on child object.
176172
const std::string& child_name = field_path.first_segment();
177-
const ObjectValue::Map& object_map = object_value_->internal_value;
178173
if (field_path.size() == 1) {
179-
return FieldValue::FromMap(object_map.erase(child_name));
174+
return ObjectValue::FromMap(fv_.object_value_->erase(child_name));
180175
} else {
181-
const auto iter = object_map.find(child_name);
182-
if (iter != object_map.end() && iter->second.type() == Type::Object) {
183-
FieldValue new_child = iter->second.Delete(field_path.PopFirst());
184-
return SetChild(child_name, new_child);
176+
const auto iter = fv_.object_value_->find(child_name);
177+
if (iter != fv_.object_value_->end() &&
178+
iter->second.type() == Type::Object) {
179+
ObjectValue new_child =
180+
ObjectValue(iter->second).Delete(field_path.PopFirst());
181+
return SetChild(child_name, new_child.fv_);
185182
} else {
186183
// If the found value isn't an object, it cannot contain the remaining
187184
// segments of the path. We don't actually change a primitive value to
@@ -191,17 +188,14 @@ FieldValue FieldValue::Delete(const FieldPath& field_path) const {
191188
}
192189
}
193190

194-
absl::optional<FieldValue> FieldValue::Get(const FieldPath& field_path) const {
195-
HARD_ASSERT(type() == Type::Object,
196-
"Cannot get field for non-object FieldValue");
197-
const FieldValue* current = this;
191+
absl::optional<FieldValue> ObjectValue::Get(const FieldPath& field_path) const {
192+
const FieldValue* current = &this->fv_;
198193
for (const auto& path : field_path) {
199194
if (current->type() != Type::Object) {
200195
return absl::nullopt;
201196
}
202-
const ObjectValue::Map& object_map = current->object_value_->internal_value;
203-
const auto iter = object_map.find(path);
204-
if (iter == object_map.end()) {
197+
const auto iter = current->object_value_->find(path);
198+
if (iter == current->object_value_->end()) {
205199
return absl::nullopt;
206200
} else {
207201
current = &iter->second;
@@ -210,12 +204,9 @@ absl::optional<FieldValue> FieldValue::Get(const FieldPath& field_path) const {
210204
return *current;
211205
}
212206

213-
FieldValue FieldValue::SetChild(const std::string& child_name,
214-
const FieldValue& value) const {
215-
HARD_ASSERT(type() == Type::Object,
216-
"Cannot set child for non-object FieldValue");
217-
return FieldValue::FromMap(
218-
object_value_->internal_value.insert(child_name, value));
207+
ObjectValue ObjectValue::SetChild(const std::string& child_name,
208+
const FieldValue& value) const {
209+
return ObjectValue::FromMap(fv_.object_value_->insert(child_name, value));
219210
}
220211

221212
FieldValue FieldValue::Null() {
@@ -239,7 +230,7 @@ FieldValue FieldValue::Nan() {
239230
}
240231

241232
FieldValue FieldValue::EmptyObject() {
242-
return FieldValue::FromMap(ObjectValue::Empty());
233+
return FieldValue::FromMap(FieldValue::Map());
243234
}
244235

245236
FieldValue FieldValue::FromInteger(int64_t value) {
@@ -344,19 +335,19 @@ FieldValue FieldValue::FromArray(std::vector<FieldValue>&& value) {
344335
return result;
345336
}
346337

347-
FieldValue FieldValue::FromMap(const ObjectValue::Map& value) {
348-
ObjectValue::Map copy(value);
338+
FieldValue FieldValue::FromMap(const FieldValue::Map& value) {
339+
FieldValue::Map copy(value);
349340
return FromMap(std::move(copy));
350341
}
351342

352-
FieldValue FieldValue::FromMap(ObjectValue::Map&& value) {
343+
FieldValue FieldValue::FromMap(FieldValue::Map&& value) {
353344
FieldValue result;
354345
result.SwitchTo(Type::Object);
355-
std::swap(result.object_value_->internal_value, value);
346+
std::swap(*result.object_value_, value);
356347
return result;
357348
}
358349

359-
bool operator<(const ObjectValue::Map& lhs, const ObjectValue::Map& rhs) {
350+
bool operator<(const FieldValue::Map& lhs, const FieldValue::Map& rhs) {
360351
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
361352
rhs.end());
362353
}
@@ -454,7 +445,7 @@ void FieldValue::SwitchTo(const Type type) {
454445
array_value_.~unique_ptr<std::vector<FieldValue>>();
455446
break;
456447
case Type::Object:
457-
object_value_.~unique_ptr<ObjectValue>();
448+
object_value_.~unique_ptr<Map>();
458449
break;
459450
default: {} // The other types where there is nothing to worry about.
460451
}
@@ -491,13 +482,20 @@ void FieldValue::SwitchTo(const Type type) {
491482
absl::make_unique<std::vector<FieldValue>>());
492483
break;
493484
case Type::Object:
494-
new (&object_value_)
495-
std::unique_ptr<ObjectValue>(absl::make_unique<ObjectValue>());
485+
new (&object_value_) std::unique_ptr<Map>(absl::make_unique<Map>());
496486
break;
497487
default: {} // The other types where there is nothing to worry about.
498488
}
499489
}
500490

491+
ObjectValue ObjectValue::FromMap(const FieldValue::Map& value) {
492+
return ObjectValue(FieldValue::FromMap(value));
493+
}
494+
495+
ObjectValue ObjectValue::FromMap(FieldValue::Map&& value) {
496+
return ObjectValue(FieldValue::FromMap(std::move(value)));
497+
}
498+
501499
} // namespace model
502500
} // namespace firestore
503501
} // namespace firebase

0 commit comments

Comments
 (0)