Skip to content

Commit 37bb620

Browse files
ckennellycopybara-github
authored andcommitted
Add nodiscard to generated APIs.
This covers two types of failures: * Methods that are logically const and failure to consume the result indicates a bug (an unnecessary call, etc.) * Methods that return significant errors (failure to parse, etc.) that should not be unintentionally ignored. PiperOrigin-RevId: 845512987
1 parent b05fef4 commit 37bb620

File tree

10 files changed

+1282
-1084
lines changed

10 files changed

+1282
-1084
lines changed

src/google/protobuf/compiler/cpp/enum.cc

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ absl::flat_hash_map<absl::string_view, std::string> EnumVars(
6161
.enum_name_uses_string_view()
6262
? "::absl::string_view"
6363
: "const ::std::string&"},
64+
// TODO: Enable this everywhere.
65+
{"nodiscard", options.opensource_runtime ? "[[nodiscard]]" : ""},
6466
};
6567
}
6668

@@ -204,16 +206,16 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
204206

205207
if (has_reflection_) {
206208
p->Emit(R"cc(
207-
$dllexport_decl $const $pb$::EnumDescriptor* $nonnull$
209+
$nodiscard $$dllexport_decl $const $pb$::EnumDescriptor* $nonnull$
208210
$Msg_Enum$_descriptor();
209211
//~ ADL Hook
210-
inline auto ProtobufInternalGetEnumDescriptor($Msg_Enum$) {
212+
$nodiscard $inline auto ProtobufInternalGetEnumDescriptor($Msg_Enum$) {
211213
return $Msg_Enum$_descriptor();
212214
}
213215
)cc");
214216
} else {
215217
p->Emit(R"cc(
216-
$return_type$ $Msg_Enum$_Name($Msg_Enum$ value);
218+
$nodiscard $$return_type$ $Msg_Enum$_Name($Msg_Enum$ value);
217219
)cc");
218220
}
219221

@@ -235,7 +237,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
235237
if (should_cache_ || !has_reflection_) {
236238
p->Emit({{"static_assert", write_assert}}, R"cc(
237239
template <typename T>
238-
$return_type$ $Msg_Enum$_Name(T value) {
240+
$nodiscard $$return_type$ $Msg_Enum$_Name(T value) {
239241
$static_assert$;
240242
return $Msg_Enum$_Name(static_cast<$Msg_Enum$>(value));
241243
}
@@ -247,7 +249,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
247249
// pointers, so if the enum values are sparse, it's not worth it.
248250
p->Emit(R"cc(
249251
template <>
250-
inline $return_type$ $Msg_Enum$_Name($Msg_Enum$ value) {
252+
$nodiscard $inline $return_type$ $Msg_Enum$_Name($Msg_Enum$ value) {
251253
return $pbi$::NameOfDenseEnum<$Msg_Enum$_descriptor, $kMin$, $kMax$>(
252254
static_cast<int>(value));
253255
}
@@ -256,7 +258,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
256258
} else {
257259
p->Emit({{"static_assert", write_assert}}, R"cc(
258260
template <typename T>
259-
$return_type$ $Msg_Enum$_Name(T value) {
261+
$nodiscard $$return_type$ $Msg_Enum$_Name(T value) {
260262
$static_assert$;
261263
return $pbi$::NameOfEnum($Msg_Enum$_descriptor(), value);
262264
}
@@ -265,7 +267,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
265267

266268
if (has_reflection_) {
267269
p->Emit(R"cc(
268-
inline bool $Msg_Enum$_Parse(
270+
$nodiscard $inline bool $Msg_Enum$_Parse(
269271
//~
270272
::absl::string_view name, $Msg_Enum$* $nonnull$ value) {
271273
return $pbi$::ParseNamedEnum<$Msg_Enum$>($Msg_Enum$_descriptor(), name,
@@ -274,7 +276,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* p) {
274276
)cc");
275277
} else {
276278
p->Emit(R"cc(
277-
bool $Msg_Enum$_Parse(
279+
$nodiscard $bool $Msg_Enum$_Parse(
278280
//~
279281
::absl::string_view name, $Msg_Enum$* $nonnull$ value);
280282
)cc");
@@ -328,7 +330,7 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* p) const {
328330
.AnnotatedAs(enum_),
329331
},
330332
R"cc(
331-
static inline bool $Enum$_IsValid(int value) {
333+
$nodiscard $static inline bool $Enum$_IsValid(int value) {
332334
return $Msg_Enum$_IsValid(value);
333335
}
334336
static constexpr $Enum_$ $Enum_MIN$ = $Msg_Enum$_$Enum$_MIN;
@@ -356,10 +358,10 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* p) const {
356358

357359
p->Emit(R"cc(
358360
template <typename T>
359-
static inline $return_type$ $Enum$_Name(T value) {
361+
$nodiscard $static inline $return_type$ $Enum$_Name(T value) {
360362
return $Msg_Enum$_Name(value);
361363
}
362-
static inline bool $Enum$_Parse(
364+
$nodiscard $static inline bool $Enum$_Parse(
363365
//~
364366
::absl::string_view name, $Enum_$* $nonnull$ value) {
365367
return $Msg_Enum$_Parse(name, value);
@@ -381,7 +383,7 @@ void EnumGenerator::GenerateIsValid(io::Printer* p) const {
381383
p->Emit({{"min", sorted_unique_values_.front()},
382384
{"max", sorted_unique_values_.back()}},
383385
R"cc(
384-
inline bool $Msg_Enum$_IsValid(int value) {
386+
$nodiscard $inline bool $Msg_Enum$_IsValid(int value) {
385387
return $min$ <= value && value <= $max$;
386388
}
387389
)cc");
@@ -394,15 +396,15 @@ void EnumGenerator::GenerateIsValid(io::Printer* p) const {
394396
}
395397
p->Emit({{"bitmap", bitmap}, {"max", sorted_unique_values_.back()}},
396398
R"cc(
397-
inline bool $Msg_Enum$_IsValid(int value) {
399+
$nodiscard $inline bool $Msg_Enum$_IsValid(int value) {
398400
return 0 <= value && value <= $max$ && (($bitmap$u >> value) & 1) != 0;
399401
}
400402
)cc");
401403
} else {
402404
// More complex struct. Use enum data structure for lookup.
403405
p->Emit(
404406
R"cc(
405-
inline bool $Msg_Enum$_IsValid(int value) {
407+
$nodiscard $inline bool $Msg_Enum$_IsValid(int value) {
406408
return $pbi$::ValidateEnum(value, $Msg_Enum$_internal_data_);
407409
}
408410
)cc");
@@ -414,7 +416,8 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* p) {
414416

415417
if (has_reflection_) {
416418
p->Emit({{"idx", idx}}, R"cc(
417-
const $pb$::EnumDescriptor* $nonnull$ $Msg_Enum$_descriptor() {
419+
$nodiscard $const $pb$::EnumDescriptor* $nonnull$
420+
$Msg_Enum$_descriptor() {
418421
$pbi$::AssignDescriptors(&$desc_table$);
419422
return $file_level_enum_descriptors$[$idx$];
420423
}
@@ -546,7 +549,7 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* p) {
546549
$entries_by_number$,
547550
};
548551
549-
$return_type$ $Msg_Enum$_Name($Msg_Enum$ value) {
552+
$nodiscard $$return_type$ $Msg_Enum$_Name($Msg_Enum$ value) {
550553
static const bool kDummy = $pbi$::InitializeEnumStrings(
551554
$Msg_Enum$_entries, $Msg_Enum$_entries_by_number, $num_unique$,
552555
$Msg_Enum$_strings);
@@ -558,7 +561,8 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* p) {
558561
return idx == -1 ? $pbi$::GetEmptyString() : $Msg_Enum$_strings[idx].get();
559562
}
560563
561-
bool $Msg_Enum$_Parse(::absl::string_view name, $Msg_Enum$* $nonnull$ value) {
564+
$nodiscard $bool $Msg_Enum$_Parse(::absl::string_view name,
565+
$Msg_Enum$* $nonnull$ value) {
562566
int int_value;
563567
bool success = $pbi$::LookUpEnumValue(
564568
$Msg_Enum$_entries, $num_declared$, name, &int_value);

0 commit comments

Comments
 (0)