Skip to content

Commit

Permalink
[ObjC] Move the has bits computation to the ctor.
Browse files Browse the repository at this point in the history
This lets the source generation method become const since it doesn't have to
update any internal state.

PiperOrigin-RevId: 491354897
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Nov 28, 2022
1 parent 2221a01 commit e8a9dcb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 26 deletions.
52 changes: 27 additions & 25 deletions src/google/protobuf/compiler/objectivec/message.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,31 @@ MessageGenerator::MessageGenerator(const std::string& root_classname,
oneof_generators_.push_back(
std::make_unique<OneofGenerator>(descriptor_->oneof_decl(i)));
}

// Assign has bits:
// 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
// who needs has bits and assigning them.
// 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
// index that groups all the elements in the oneof.
size_t num_has_bits = field_generators_.CalculateHasBits();
size_t sizeof_has_storage = (num_has_bits + 31) / 32;
if (sizeof_has_storage == 0) {
// In the case where no field needs has bits, don't let the _has_storage_
// end up as zero length (zero length arrays are sort of a grey area
// since it has to be at the start of the struct). This also ensures a
// field with only oneofs keeps the required negative indices they need.
sizeof_has_storage = 1;
}
// Tell all the fields the oneof base.
for (const auto& generator : oneof_generators_) {
generator->SetOneofIndexBase(sizeof_has_storage);
}
field_generators_.SetOneofIndexBase(sizeof_has_storage);
// sizeof_has_storage needs enough bits for the single fields that aren't in
// any oneof, and then one int32 for each oneof (to store the field number).
sizeof_has_storage += oneof_generators_.size();

sizeof_has_storage_ = sizeof_has_storage;
}

void MessageGenerator::AddExtensionGenerators(
Expand Down Expand Up @@ -321,7 +346,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const {
}
}

void MessageGenerator::GenerateSource(io::Printer* printer) {
void MessageGenerator::GenerateSource(io::Printer* printer) const {
if (IsMapEntryMessage(descriptor_)) {
return;
}
Expand Down Expand Up @@ -367,37 +392,14 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
std::sort(sorted_extensions.begin(), sorted_extensions.end(),
ExtensionRangeOrdering());

// Assign has bits:
// 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
// who needs has bits and assigning them.
// 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
// index that groups all the elements in the oneof.
size_t num_has_bits = field_generators_.CalculateHasBits();
size_t sizeof_has_storage = (num_has_bits + 31) / 32;
if (sizeof_has_storage == 0) {
// In the case where no field needs has bits, don't let the _has_storage_
// end up as zero length (zero length arrays are sort of a grey area
// since it has to be at the start of the struct). This also ensures a
// field with only oneofs keeps the required negative indices they need.
sizeof_has_storage = 1;
}
// Tell all the fields the oneof base.
for (const auto& generator : oneof_generators_) {
generator->SetOneofIndexBase(sizeof_has_storage);
}
field_generators_.SetOneofIndexBase(sizeof_has_storage);
// sizeof_has_storage needs enough bits for the single fields that aren't in
// any oneof, and then one int32 for each oneof (to store the field number).
sizeof_has_storage += oneof_generators_.size();

printer->Print(
// clang-format off
"\n"
"typedef struct $classname$__storage_ {\n"
" uint32_t _has_storage_[$sizeof_has_storage$];\n",
// clang-format on
"classname", class_name_, "sizeof_has_storage",
absl::StrCat(sizeof_has_storage));
absl::StrCat(sizeof_has_storage_));
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(size_order_fields[i])
Expand Down
4 changes: 3 additions & 1 deletion src/google/protobuf/compiler/objectivec/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__

#include <cstddef>
#include <memory>
#include <string>
#include <vector>
Expand Down Expand Up @@ -61,7 +62,7 @@ class MessageGenerator {
std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);

void GenerateMessageHeader(io::Printer* printer) const;
void GenerateSource(io::Printer* printer);
void GenerateSource(io::Printer* printer) const;
void DetermineObjectiveCClassDefinitions(
absl::btree_set<std::string>* fwd_decls) const;
void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
Expand All @@ -78,6 +79,7 @@ class MessageGenerator {
const std::string deprecated_attribute_;
std::vector<const ExtensionGenerator*> extension_generators_;
std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_;
size_t sizeof_has_storage_;
};

} // namespace objectivec
Expand Down

0 comments on commit e8a9dcb

Please sign in to comment.