Skip to content

Commit f2f4c17

Browse files
committed
Remove optional<> from serializer return values
1 parent ec318ba commit f2f4c17

File tree

6 files changed

+74
-101
lines changed

6 files changed

+74
-101
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,13 @@ std::unique_ptr<NoDocument> LocalSerializer::DecodeNoDocument(
141141
Reader* reader, const firestore_client_NoDocument& proto) const {
142142
if (!reader->status().ok()) return nullptr;
143143

144-
absl::optional<SnapshotVersion> version =
144+
SnapshotVersion version =
145145
rpc_serializer_.DecodeSnapshotVersion(reader, proto.read_time);
146146

147147
if (!reader->status().ok()) return nullptr;
148148
return absl::make_unique<NoDocument>(
149149
rpc_serializer_.DecodeKey(rpc_serializer_.DecodeString(proto.name)),
150-
*std::move(version));
150+
std::move(version));
151151
}
152152

153153
firestore_client_Target LocalSerializer::EncodeQueryData(
@@ -176,16 +176,16 @@ firestore_client_Target LocalSerializer::EncodeQueryData(
176176
return result;
177177
}
178178

179-
absl::optional<QueryData> LocalSerializer::DecodeQueryData(
179+
QueryData LocalSerializer::DecodeQueryData(
180180
Reader* reader, const firestore_client_Target& proto) const {
181-
if (!reader->status().ok()) return absl::nullopt;
181+
if (!reader->status().ok()) return QueryData::Invalid();
182182

183183
model::TargetId target_id = proto.target_id;
184-
absl::optional<SnapshotVersion> version =
184+
SnapshotVersion version =
185185
rpc_serializer_.DecodeSnapshotVersion(reader, proto.snapshot_version);
186186
std::vector<uint8_t> resume_token =
187187
rpc_serializer_.DecodeBytes(proto.resume_token);
188-
absl::optional<Query> query = Query::Invalid();
188+
Query query = Query::Invalid();
189189

190190
switch (proto.which_target_type) {
191191
case firestore_client_Target_query_tag:
@@ -201,9 +201,9 @@ absl::optional<QueryData> LocalSerializer::DecodeQueryData(
201201
StringFormat("Unknown target_type: %s", proto.which_target_type));
202202
}
203203

204-
if (!reader->status().ok()) return absl::nullopt;
205-
return QueryData(*std::move(query), target_id, QueryPurpose::kListen,
206-
*std::move(version), std::move(resume_token));
204+
if (!reader->status().ok()) return QueryData::Invalid();
205+
return QueryData(std::move(query), target_id, QueryPurpose::kListen,
206+
std::move(version), std::move(resume_token));
207207
}
208208

209209
} // namespace local

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "Firestore/core/src/firebase/firestore/nanopb/writer.h"
3232
#include "Firestore/core/src/firebase/firestore/remote/serializer.h"
3333
#include "Firestore/core/src/firebase/firestore/util/status.h"
34-
#include "absl/types/optional.h"
3534

3635
namespace firebase {
3736
namespace firestore {
@@ -99,13 +98,11 @@ class LocalSerializer {
9998
* Check reader->status() to determine if an error occurred while decoding.
10099
*
101100
* @param reader The Reader object. Used only for error handling.
102-
* @return The QueryData equivalent of the bytes or nullopt if an error
103-
* occurred.
104-
* @post (reader->status().ok() && result.has_value()) ||
105-
* (!reader->status().ok() && !result.has_value())
101+
* @return The QueryData equivalent of the bytes. On error, the return value
102+
* is unspecified.
106103
*/
107-
absl::optional<QueryData> DecodeQueryData(
108-
nanopb::Reader* reader, const firestore_client_Target& proto) const;
104+
QueryData DecodeQueryData(nanopb::Reader* reader,
105+
const firestore_client_Target& proto) const;
109106

110107
private:
111108
/**

Firestore/core/src/firebase/firestore/remote/serializer.cc

Lines changed: 44 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -103,45 +103,35 @@ std::vector<uint8_t> Serializer::DecodeBytes(const pb_bytes_array_t* bytes) {
103103

104104
namespace {
105105

106-
absl::optional<ObjectValue::Map> DecodeMapValue(
106+
ObjectValue::Map DecodeMapValue(
107107
Reader* reader, const google_firestore_v1beta1_MapValue& map_value);
108108

109-
absl::optional<ObjectValue::Map::value_type> DecodeFieldsEntry(
109+
ObjectValue::Map::value_type DecodeFieldsEntry(
110110
Reader* reader,
111111
const google_firestore_v1beta1_Document_FieldsEntry& fields) {
112-
if (!reader->status().ok()) return absl::nullopt;
112+
if (!reader->status().ok()) return {};
113113

114114
std::string key = Serializer::DecodeString(fields.key);
115-
absl::optional<FieldValue> value =
116-
Serializer::DecodeFieldValue(reader, fields.value);
115+
FieldValue value = Serializer::DecodeFieldValue(reader, fields.value);
117116

118117
if (key.empty()) {
119118
reader->Fail(
120119
"Invalid message: Empty key while decoding a Map field value.");
121-
return absl::nullopt;
120+
return {};
122121
}
123122

124-
if (!value.has_value()) {
125-
reader->Fail(
126-
"Invalid message: Empty value while decoding a Map field value.");
127-
return absl::nullopt;
128-
}
129-
130-
return ObjectValue::Map::value_type{std::move(key), *std::move(value)};
123+
return ObjectValue::Map::value_type{std::move(key), std::move(value)};
131124
}
132125

133-
absl::optional<ObjectValue::Map> DecodeFields(
126+
ObjectValue::Map DecodeFields(
134127
Reader* reader,
135128
size_t count,
136129
const google_firestore_v1beta1_Document_FieldsEntry* fields) {
137-
if (!reader->status().ok()) return absl::nullopt;
130+
if (!reader->status().ok()) return {};
138131

139132
ObjectValue::Map result;
140133
for (size_t i = 0; i < count; i++) {
141-
absl::optional<ObjectValue::Map::value_type> kv =
142-
DecodeFieldsEntry(reader, fields[i]);
143-
if (!reader->status().ok()) return absl::nullopt;
144-
result.emplace(*kv);
134+
result.emplace(DecodeFieldsEntry(reader, fields[i]));
145135
}
146136

147137
return result;
@@ -170,18 +160,17 @@ google_firestore_v1beta1_MapValue EncodeMapValue(
170160
return result;
171161
}
172162

173-
absl::optional<ObjectValue::Map> DecodeMapValue(
163+
ObjectValue::Map DecodeMapValue(
174164
Reader* reader, const google_firestore_v1beta1_MapValue& map_value) {
175-
if (!reader->status().ok()) return absl::nullopt;
165+
if (!reader->status().ok()) return {};
176166
ObjectValue::Map result;
177167

178168
for (size_t i = 0; i < map_value.fields_count; i++) {
179169
std::string key = Serializer::DecodeString(map_value.fields[i].key);
180-
absl::optional<FieldValue> value =
170+
FieldValue value =
181171
Serializer::DecodeFieldValue(reader, map_value.fields[i].value);
182-
if (!reader->status().ok()) return absl::nullopt;
183172

184-
result[key] = *value;
173+
result[key] = value;
185174
}
186175

187176
return result;
@@ -305,9 +294,9 @@ google_firestore_v1beta1_Value Serializer::EncodeFieldValue(
305294
return result;
306295
}
307296

308-
absl::optional<FieldValue> Serializer::DecodeFieldValue(
297+
FieldValue Serializer::DecodeFieldValue(
309298
Reader* reader, const google_firestore_v1beta1_Value& msg) {
310-
if (!reader->status().ok()) return absl::nullopt;
299+
if (!reader->status().ok()) return FieldValue::Null();
311300

312301
switch (msg.which_value_type) {
313302
case google_firestore_v1beta1_Value_null_value_tag:
@@ -317,6 +306,11 @@ absl::optional<FieldValue> Serializer::DecodeFieldValue(
317306
return FieldValue::Null();
318307

319308
case google_firestore_v1beta1_Value_boolean_value_tag:
309+
// TODO(rsgowman): Due to the nanopb implementation, msg.boolean_value
310+
// could be an integer other than 0 or 1, (such as 2). This leads to
311+
// undefined behaviour when it's read as a boolean. eg. on at least gcc,
312+
// the value is treated as both true *and* false. We need to decide if we
313+
// care enough to do anything about this.
320314
return FieldValue::FromBoolean(msg.boolean_value);
321315

322316
case google_firestore_v1beta1_Value_integer_value_tag:
@@ -326,17 +320,12 @@ absl::optional<FieldValue> Serializer::DecodeFieldValue(
326320
return FieldValue::FromString(DecodeString(msg.string_value));
327321

328322
case google_firestore_v1beta1_Value_timestamp_value_tag: {
329-
absl::optional<Timestamp> timestamp =
330-
DecodeTimestamp(reader, msg.timestamp_value);
331-
if (!reader->status().ok()) return absl::nullopt;
332-
return FieldValue::FromTimestamp(*timestamp);
323+
return FieldValue::FromTimestamp(
324+
DecodeTimestamp(reader, msg.timestamp_value));
333325
}
334326

335327
case google_firestore_v1beta1_Value_map_value_tag: {
336-
absl::optional<ObjectValue::Map> optional_map =
337-
DecodeMapValue(reader, msg.map_value);
338-
if (!reader->status().ok()) return absl::nullopt;
339-
return FieldValue::FromMap(*optional_map);
328+
return FieldValue::FromMap(DecodeMapValue(reader, msg.map_value));
340329
}
341330

342331
case google_firestore_v1beta1_Value_double_value_tag:
@@ -352,7 +341,7 @@ absl::optional<FieldValue> Serializer::DecodeFieldValue(
352341
// Unspecified type.
353342
reader->Fail(StringFormat("Invalid type while decoding FieldValue: %s",
354343
msg.which_value_type));
355-
return absl::nullopt;
344+
return FieldValue::Null();
356345
}
357346

358347
UNREACHABLE();
@@ -428,17 +417,17 @@ std::unique_ptr<model::Document> Serializer::DecodeFoundDocument(
428417
"Tried to deserialize a found document from a missing document.");
429418

430419
DocumentKey key = DecodeKey(DecodeString(response.found.name));
431-
absl::optional<ObjectValue::Map> value =
420+
ObjectValue::Map value =
432421
DecodeFields(reader, response.found.fields_count, response.found.fields);
433-
absl::optional<SnapshotVersion> version =
422+
SnapshotVersion version =
434423
DecodeSnapshotVersion(reader, response.found.update_time);
435424
if (!reader->status().ok()) return nullptr;
436425

437-
HARD_ASSERT(*version != SnapshotVersion::None(),
426+
HARD_ASSERT(version != SnapshotVersion::None(),
438427
"Got a document response with no snapshot version");
439428

440-
return absl::make_unique<Document>(FieldValue::FromMap(*std::move(value)),
441-
std::move(key), *std::move(version),
429+
return absl::make_unique<Document>(FieldValue::FromMap(std::move(value)),
430+
std::move(key), std::move(version),
442431
/*has_local_modifications=*/false);
443432
}
444433

@@ -452,32 +441,30 @@ std::unique_ptr<model::NoDocument> Serializer::DecodeMissingDocument(
452441
"Tried to deserialize a missing document from a found document.");
453442

454443
DocumentKey key = DecodeKey(DecodeString(response.missing));
455-
absl::optional<SnapshotVersion> version =
456-
DecodeSnapshotVersion(reader, response.read_time);
444+
SnapshotVersion version = DecodeSnapshotVersion(reader, response.read_time);
457445
if (!reader->status().ok()) return nullptr;
458446

459-
if (*version == SnapshotVersion::None()) {
447+
if (version == SnapshotVersion::None()) {
460448
reader->Fail("Got a no document response with no snapshot version");
461449
return nullptr;
462450
}
463451

464-
return absl::make_unique<NoDocument>(std::move(key), *std::move(version));
452+
return absl::make_unique<NoDocument>(std::move(key), std::move(version));
465453
}
466454

467455
std::unique_ptr<Document> Serializer::DecodeDocument(
468456
Reader* reader, const google_firestore_v1beta1_Document& proto) const {
469457
if (!reader->status().ok()) return nullptr;
470458

471-
absl::optional<ObjectValue::Map> fields_internal =
459+
ObjectValue::Map fields_internal =
472460
DecodeFields(reader, proto.fields_count, proto.fields);
473-
absl::optional<SnapshotVersion> version =
474-
DecodeSnapshotVersion(reader, proto.update_time);
461+
SnapshotVersion version = DecodeSnapshotVersion(reader, proto.update_time);
475462

476463
if (!reader->status().ok()) return nullptr;
477-
return absl::make_unique<Document>(FieldValue::FromMap(*fields_internal),
478-
DecodeKey(DecodeString(proto.name)),
479-
*version,
480-
/*has_local_modifications=*/false);
464+
return absl::make_unique<Document>(
465+
FieldValue::FromMap(std::move(fields_internal)),
466+
DecodeKey(DecodeString(proto.name)), std::move(version),
467+
/*has_local_modifications=*/false);
481468
}
482469

483470
google_firestore_v1beta1_Target_QueryTarget Serializer::EncodeQueryTarget(
@@ -541,7 +528,7 @@ ResourcePath DecodeQueryPath(absl::string_view name) {
541528
}
542529
}
543530

544-
absl::optional<Query> Serializer::DecodeQueryTarget(
531+
Query Serializer::DecodeQueryTarget(
545532
nanopb::Reader* reader,
546533
const google_firestore_v1beta1_Target_QueryTarget& proto) {
547534
if (!reader->status().ok()) return Query::Invalid();
@@ -551,7 +538,7 @@ absl::optional<Query> Serializer::DecodeQueryTarget(
551538
google_firestore_v1beta1_Target_QueryTarget_structured_query_tag) {
552539
reader->Fail(
553540
StringFormat("Unknown query_type: %s", proto.which_query_type));
554-
return absl::nullopt;
541+
return Query::Invalid();
555542
}
556543

557544
ResourcePath path = DecodeQueryPath(DecodeString(proto.parent));
@@ -596,14 +583,12 @@ google_protobuf_Timestamp Serializer::EncodeTimestamp(
596583
return result;
597584
}
598585

599-
absl::optional<SnapshotVersion> Serializer::DecodeSnapshotVersion(
586+
SnapshotVersion Serializer::DecodeSnapshotVersion(
600587
nanopb::Reader* reader, const google_protobuf_Timestamp& proto) {
601-
absl::optional<Timestamp> version = DecodeTimestamp(reader, proto);
602-
if (!reader->status().ok()) return absl::nullopt;
603-
return SnapshotVersion{*version};
588+
return SnapshotVersion{DecodeTimestamp(reader, proto)};
604589
}
605590

606-
absl::optional<Timestamp> Serializer::DecodeTimestamp(
591+
Timestamp Serializer::DecodeTimestamp(
607592
nanopb::Reader* reader, const google_protobuf_Timestamp& timestamp_proto) {
608593
// The Timestamp ctor will assert if we provide values outside the valid
609594
// range. However, since we're decoding, a single corrupt byte could cause
@@ -619,7 +604,7 @@ absl::optional<Timestamp> Serializer::DecodeTimestamp(
619604
"Invalid message: timestamp nanos must be between 0 and 999999999");
620605
}
621606

622-
if (!reader->status().ok()) return absl::nullopt;
607+
if (!reader->status().ok()) return Timestamp();
623608
return Timestamp{timestamp_proto.seconds, timestamp_proto.nanos};
624609
}
625610

Firestore/core/src/firebase/firestore/remote/serializer.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include "Firestore/core/src/firebase/firestore/util/status.h"
4040
#include "absl/base/attributes.h"
4141
#include "absl/strings/string_view.h"
42-
#include "absl/types/optional.h"
4342

4443
namespace firebase {
4544
namespace firestore {
@@ -126,15 +125,14 @@ class Serializer {
126125
* @brief Converts from nanopb proto to the model FieldValue format.
127126
*
128127
* @param reader The Reader object. Used only for error handling.
129-
* @return The model equivalent of the bytes or nullopt if an error occurred.
130-
* @post (reader->status().ok() && result) ||
131-
* (!reader->status().ok() && !result)
128+
* @return The model equivalent of the bytes. On error, the return value is
129+
* unspecified.
132130
*/
133131
// TODO(rsgowman): Once the proto is read, the only thing the reader object is
134132
// used for is error handling. This seems questionable. We probably need to
135133
// rework error handling. Again. But we'll defer that for now and continue
136134
// just passing the reader object.
137-
static absl::optional<model::FieldValue> DecodeFieldValue(
135+
static model::FieldValue DecodeFieldValue(
138136
nanopb::Reader* reader, const google_firestore_v1beta1_Value& proto);
139137

140138
/**
@@ -194,13 +192,13 @@ class Serializer {
194192
static google_protobuf_Timestamp EncodeTimestamp(
195193
const Timestamp& timestamp_value);
196194

197-
static absl::optional<model::SnapshotVersion> DecodeSnapshotVersion(
195+
static model::SnapshotVersion DecodeSnapshotVersion(
198196
nanopb::Reader* reader, const google_protobuf_Timestamp& proto);
199197

200-
static absl::optional<Timestamp> DecodeTimestamp(
198+
static Timestamp DecodeTimestamp(
201199
nanopb::Reader* reader, const google_protobuf_Timestamp& timestamp_proto);
202200

203-
static absl::optional<core::Query> DecodeQueryTarget(
201+
static core::Query DecodeQueryTarget(
204202
nanopb::Reader* reader,
205203
const google_firestore_v1beta1_Target_QueryTarget& proto);
206204

Firestore/core/test/firebase/firestore/local/local_serializer_test.cc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,11 @@ class LocalSerializerTest : public ::testing::Test {
141141
firestore_client_MaybeDocument_init_zero;
142142
reader.ReadNanopbMessage(firestore_client_MaybeDocument_fields,
143143
&nanopb_proto);
144-
absl::optional<std::unique_ptr<MaybeDocument>> actual_model_optional =
144+
std::unique_ptr<MaybeDocument> actual_model =
145145
serializer.DecodeMaybeDocument(&reader, nanopb_proto);
146146
reader.FreeNanopbMessage(firestore_client_MaybeDocument_fields,
147147
&nanopb_proto);
148148
EXPECT_OK(reader.status());
149-
std::unique_ptr<MaybeDocument> actual_model =
150-
std::move(actual_model_optional).value();
151149
EXPECT_EQ(type, actual_model->type());
152150
EXPECT_EQ(model, *actual_model);
153151
}
@@ -184,13 +182,11 @@ class LocalSerializerTest : public ::testing::Test {
184182

185183
firestore_client_Target nanopb_proto = firestore_client_Target_init_zero;
186184
reader.ReadNanopbMessage(firestore_client_Target_fields, &nanopb_proto);
187-
absl::optional<QueryData> actual_query_data_optional =
185+
QueryData actual_query_data =
188186
serializer.DecodeQueryData(&reader, nanopb_proto);
189187
reader.FreeNanopbMessage(firestore_client_Target_fields, &nanopb_proto);
190188

191189
EXPECT_OK(reader.status());
192-
QueryData actual_query_data = std::move(actual_query_data_optional).value();
193-
194190
EXPECT_EQ(query_data, actual_query_data);
195191
}
196192

0 commit comments

Comments
 (0)