[ObjC] Move the has bits computation to the ctor.

This lets the source generation method become const since it doesn't have to
update any internal state.

PiperOrigin-RevId: 491354897
pull/11059/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 2221a0111d
commit e8a9dcb0df
  1. 52
      src/google/protobuf/compiler/objectivec/message.cc
  2. 4
      src/google/protobuf/compiler/objectivec/message.h

@ -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(
@ -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;
}
@ -367,29 +392,6 @@ 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"
@ -397,7 +399,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" 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])

@ -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>
@ -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,
@ -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

Loading…
Cancel
Save