diff options
| author | nechda <[email protected]> | 2024-08-29 23:50:27 +0300 |
|---|---|---|
| committer | nechda <[email protected]> | 2024-08-30 00:05:25 +0300 |
| commit | e10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch) | |
| tree | 571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc | |
| parent | e79b38f2bbbf78d295d1901d2a79f898022d5224 (diff) | |
Update cpp-protobuf to 22.5
Привет!\
Этот PR переключат cpp & python библиотеки protobuf на версию 22.5
Если у вас возникли проблемы после влития этого PR:
1. Если начали падать канон тесты, то проведите их переканонизацию
2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями
3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT)
7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc')
| -rw-r--r-- | contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc | 522 |
1 files changed, 192 insertions, 330 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc index d5359b6d247..361c039cc52 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/cpp/field.cc @@ -32,276 +32,89 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include <google/protobuf/compiler/cpp/field.h> +#include "google/protobuf/compiler/cpp/field.h" #include <cstdint> #include <memory> #include <string> - -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/compiler/cpp/helpers.h> -#include <google/protobuf/compiler/cpp/primitive_field.h> -#include <google/protobuf/compiler/cpp/string_field.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/compiler/cpp/enum_field.h> -#include <google/protobuf/compiler/cpp/map_field.h> -#include <google/protobuf/compiler/cpp/message_field.h> -#include <google/protobuf/descriptor.pb.h> +#include <vector> + +#include "y_absl/container/flat_hash_map.h" +#include "y_absl/log/absl_check.h" +#include "y_absl/strings/str_format.h" +#include "y_absl/strings/string_view.h" +#include "y_absl/types/optional.h" +#include "google/protobuf/compiler/cpp/field_generators/generators.h" +#include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" +#include "google/protobuf/compiler/cpp/tracker.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/wire_format.h" namespace google { namespace protobuf { namespace compiler { namespace cpp { - -using internal::WireFormat; - -namespace { - -void MaySetAnnotationVariable(const Options& options, - StringPiece annotation_name, - StringPiece substitute_template_prefix, - StringPiece prepared_template, - int field_index, StringPiece access_type, - std::map<TProtoStringType, TProtoStringType>* variables) { - if (options.field_listener_options.forbidden_field_listener_events.count( - TProtoStringType(annotation_name))) - return; - (*variables)[StrCat("annotate_", annotation_name)] = strings::Substitute( - StrCat(substitute_template_prefix, prepared_template, ");\n"), - field_index, access_type); -} - -TProtoStringType GenerateTemplateForOneofString(const FieldDescriptor* descriptor, - StringPiece proto_ns, - StringPiece field_member) { - TProtoStringType field_name = google::protobuf::compiler::cpp::FieldName(descriptor); - TProtoStringType field_pointer = - descriptor->options().ctype() == google::protobuf::FieldOptions::STRING - ? "$0.UnsafeGetPointer()" - : "$0"; - - if (descriptor->default_value_string().empty()) { - return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ", - field_pointer, ": nullptr"), - field_member); - } - - if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING_PIECE) { - return strings::Substitute(StrCat("_internal_has_", field_name, "() ? ", - field_pointer, ": nullptr"), - field_member); - } - - TProtoStringType default_value_pointer = - descriptor->options().ctype() == google::protobuf::FieldOptions::STRING - ? "&$1.get()" - : "&$1"; - return strings::Substitute( - StrCat("_internal_has_", field_name, "() ? ", field_pointer, " : ", - default_value_pointer), - field_member, MakeDefaultFieldName(descriptor)); -} - -TProtoStringType GenerateTemplateForSingleString(const FieldDescriptor* descriptor, - StringPiece field_member) { - if (descriptor->default_value_string().empty()) { - return StrCat("&", field_member); - } - - if (descriptor->options().ctype() == google::protobuf::FieldOptions::STRING) { - return strings::Substitute( - "$0.IsDefault() ? &$1.get() : $0.UnsafeGetPointer()", field_member, - MakeDefaultFieldName(descriptor)); - } - - return StrCat("&", field_member); -} - -} // namespace - -void AddAccessorAnnotations(const FieldDescriptor* descriptor, - const Options& options, - std::map<TProtoStringType, TProtoStringType>* variables) { - // Can be expanded to include more specific calls, for example, for arena or - // clear calls. - static constexpr const char* kAccessorsAnnotations[] = { - "annotate_add", "annotate_get", "annotate_has", - "annotate_list", "annotate_mutable", "annotate_mutable_list", - "annotate_release", "annotate_set", "annotate_size", - "annotate_clear", "annotate_add_mutable", +using ::google::protobuf::internal::WireFormat; +using Sub = ::google::protobuf::io::Printer::Sub; + +std::vector<Sub> FieldVars(const FieldDescriptor* field, const Options& opts) { + bool split = ShouldSplit(field, opts); + std::vector<Sub> vars = { + // This will eventually be renamed to "field", once the existing "field" + // variable is replaced with "field_" everywhere. + {"name", FieldName(field)}, + + {"index", field->index()}, + {"number", field->number()}, + {"pkg.Msg.field", field->full_name()}, + + {"field_", FieldMemberName(field, split)}, + {"DeclaredType", DeclaredTypeMethodName(field->type())}, + {"kTagBytes", WireFormat::TagSize(field->number(), field->type())}, + Sub("PrepareSplitMessageForWrite", + split ? "PrepareSplitMessageForWrite();" : "") + .WithSuffix(";"), + Sub("DEPRECATED", DeprecatedAttribute(opts, field)).WithSuffix(" "), + + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables + // would be ambiguous or impossible). They should never be set to anything + // but the empty string. + {"{", ""}, + {"}", ""}, + + // Old-style names. + {"field", FieldMemberName(field, split)}, + {"maybe_prepare_split_message", + split ? "PrepareSplitMessageForWrite();" : ""}, + {"declared_type", DeclaredTypeMethodName(field->type())}, + {"classname", ClassName(FieldScope(field), false)}, + {"ns", Namespace(field, opts)}, + {"tag_size", WireFormat::TagSize(field->number(), field->type())}, + {"deprecated_attr", DeprecatedAttribute(opts, field)}, }; - for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) { - (*variables)[kAccessorsAnnotations[i]] = ""; - } - if (options.annotate_accessor) { - for (size_t i = 0; i < GOOGLE_ARRAYSIZE(kAccessorsAnnotations); ++i) { - (*variables)[kAccessorsAnnotations[i]] = StrCat( - " ", FieldName(descriptor), "_AccessedNoStrip = true;\n"); - } - } - if (!options.field_listener_options.inject_field_listener_events) { - return; - } - if (descriptor->file()->options().optimize_for() == - google::protobuf::FileOptions::LITE_RUNTIME) { - return; - } - TProtoStringType field_member = (*variables)["field"]; - const google::protobuf::OneofDescriptor* oneof_member = - descriptor->real_containing_oneof(); - const TProtoStringType proto_ns = (*variables)["proto_ns"]; - const TProtoStringType substitute_template_prefix = - StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, "); - TProtoStringType prepared_template; - - // Flat template is needed if the prepared one is introspecting the values - // inside the returned values, for example, for repeated fields and maps. - TProtoStringType prepared_flat_template; - TProtoStringType prepared_add_template; - // TODO(b/190614678): Support fields with type Message or Map. - if (descriptor->is_repeated() && !descriptor->is_map()) { - if (descriptor->type() != FieldDescriptor::TYPE_MESSAGE && - descriptor->type() != FieldDescriptor::TYPE_GROUP) { - prepared_template = strings::Substitute("&$0.Get(index)", field_member); - prepared_add_template = - strings::Substitute("&$0.Get($0.size() - 1)", field_member); - } else { - prepared_template = "nullptr"; - prepared_add_template = "nullptr"; - } - } else if (descriptor->is_map()) { - prepared_template = "nullptr"; - } else if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE && - !IsExplicitLazy(descriptor)) { - prepared_template = "nullptr"; - } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - if (oneof_member) { - prepared_template = GenerateTemplateForOneofString( - descriptor, (*variables)["proto_ns"], field_member); - } else { - prepared_template = - GenerateTemplateForSingleString(descriptor, field_member); - } - } else { - prepared_template = StrCat("&", field_member); - } - if (descriptor->is_repeated() && !descriptor->is_map() && - descriptor->type() != FieldDescriptor::TYPE_MESSAGE && - descriptor->type() != FieldDescriptor::TYPE_GROUP) { - prepared_flat_template = StrCat("&", field_member); - } else { - prepared_flat_template = prepared_template; - } - MaySetAnnotationVariable(options, "get", substitute_template_prefix, - prepared_template, descriptor->index(), "OnGet", - variables); - MaySetAnnotationVariable(options, "set", substitute_template_prefix, - prepared_template, descriptor->index(), "OnSet", - variables); - MaySetAnnotationVariable(options, "has", substitute_template_prefix, - prepared_template, descriptor->index(), "OnHas", - variables); - MaySetAnnotationVariable(options, "mutable", substitute_template_prefix, - prepared_template, descriptor->index(), "OnMutable", - variables); - MaySetAnnotationVariable(options, "release", substitute_template_prefix, - prepared_template, descriptor->index(), "OnRelease", - variables); - MaySetAnnotationVariable(options, "clear", substitute_template_prefix, - prepared_flat_template, descriptor->index(), - "OnClear", variables); - MaySetAnnotationVariable(options, "size", substitute_template_prefix, - prepared_flat_template, descriptor->index(), - "OnSize", variables); - MaySetAnnotationVariable(options, "list", substitute_template_prefix, - prepared_flat_template, descriptor->index(), - "OnList", variables); - MaySetAnnotationVariable(options, "mutable_list", substitute_template_prefix, - prepared_flat_template, descriptor->index(), - "OnMutableList", variables); - MaySetAnnotationVariable(options, "add", substitute_template_prefix, - prepared_add_template, descriptor->index(), "OnAdd", - variables); - MaySetAnnotationVariable(options, "add_mutable", substitute_template_prefix, - prepared_add_template, descriptor->index(), - "OnAddMutable", variables); -} - -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables, - const Options& options) { - SetCommonVars(options, variables); - SetCommonMessageDataVariables(descriptor->containing_type(), variables); - - (*variables)["ns"] = Namespace(descriptor, options); - (*variables)["name"] = FieldName(descriptor); - (*variables)["index"] = StrCat(descriptor->index()); - (*variables)["number"] = StrCat(descriptor->number()); - (*variables)["classname"] = ClassName(FieldScope(descriptor), false); - (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - bool split = ShouldSplit(descriptor, options); - (*variables)["field"] = FieldMemberName(descriptor, split); - - (*variables)["tag_size"] = StrCat( - WireFormat::TagSize(descriptor->number(), descriptor->type())); - (*variables)["deprecated_attr"] = DeprecatedAttribute(options, descriptor); - - (*variables)["set_hasbit"] = ""; - (*variables)["clear_hasbit"] = ""; - (*variables)["maybe_prepare_split_message"] = - split ? " PrepareSplitMessageForWrite();\n" : ""; - - AddAccessorAnnotations(descriptor, options, variables); - - // These variables are placeholders to pick out the beginning and ends of - // identifiers for annotations (when doing so with existing variables would - // be ambiguous or impossible). They should never be set to anything but the - // empty string. - (*variables)["{"] = ""; - (*variables)["}"] = ""; -} - -void FieldGenerator::SetHasBitIndex(arc_i32 has_bit_index) { - if (!HasHasbit(descriptor_)) { - GOOGLE_CHECK_EQ(has_bit_index, -1); - return; + if (const auto* oneof = field->containing_oneof()) { + auto field_name = UnderscoresToCamelCase(field->name(), true); + + vars.push_back({"oneof_name", oneof->name()}); + vars.push_back({"field_name", field_name}); + vars.push_back({"oneof_index", oneof->index()}); + vars.push_back({"has_field", y_absl::StrFormat("%s_case() == k%s", + oneof->name(), field_name)}); + vars.push_back( + {"not_has_field", + y_absl::StrFormat("%s_case() != k%s", oneof->name(), field_name)}); } - variables_["set_hasbit"] = StrCat( - variables_["has_bits"], "[", has_bit_index / 32, "] |= 0x", - strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); - variables_["clear_hasbit"] = StrCat( - variables_["has_bits"], "[", has_bit_index / 32, "] &= ~0x", - strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); -} -void FieldGenerator::SetInlinedStringIndex(arc_i32 inlined_string_index) { - if (!IsStringInlined(descriptor_, options_)) { - GOOGLE_CHECK_EQ(inlined_string_index, -1); - return; - } - // The first bit is the tracking bit for on demand registering ArenaDtor. - GOOGLE_CHECK_GT(inlined_string_index, 0) - << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; - variables_["inlined_string_donated"] = StrCat( - "(", variables_["inlined_string_donated_array"], "[", - inlined_string_index / 32, "] & 0x", - strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), - "u) != 0;"); - variables_["donating_states_word"] = - StrCat(variables_["inlined_string_donated_array"], "[", - inlined_string_index / 32, "]"); - variables_["mask_for_undonate"] = StrCat( - "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), - "u"); + return vars; } -void FieldGenerator::GenerateAggregateInitializer(io::Printer* printer) const { - Formatter format(printer, variables_); +void FieldGeneratorBase::GenerateAggregateInitializer(io::Printer* p) const { + Formatter format(p, variables_); if (ShouldSplit(descriptor_, options_)) { format("decltype(Impl_::Split::$name$_){arena}"); return; @@ -309,110 +122,159 @@ void FieldGenerator::GenerateAggregateInitializer(io::Printer* printer) const { format("decltype($field$){arena}"); } -void FieldGenerator::GenerateConstexprAggregateInitializer( - io::Printer* printer) const { - Formatter format(printer, variables_); +void FieldGeneratorBase::GenerateConstexprAggregateInitializer( + io::Printer* p) const { + Formatter format(p, variables_); format("/*decltype($field$)*/{}"); } -void FieldGenerator::GenerateCopyAggregateInitializer( - io::Printer* printer) const { - Formatter format(printer, variables_); +void FieldGeneratorBase::GenerateCopyAggregateInitializer( + io::Printer* p) const { + Formatter format(p, variables_); format("decltype($field$){from.$field$}"); } -void FieldGenerator::GenerateCopyConstructorCode(io::Printer* printer) const { +void FieldGeneratorBase::GenerateCopyConstructorCode(io::Printer* p) const { if (ShouldSplit(descriptor_, options_)) { // There is no copy constructor for the `Split` struct, so we need to copy // the value here. - Formatter format(printer, variables_); + Formatter format(p, variables_); format("$field$ = from.$field$;\n"); } } -void SetCommonOneofFieldVariables( - const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables) { - const TProtoStringType prefix = descriptor->containing_oneof()->name() + "_."; - (*variables)["oneof_name"] = descriptor->containing_oneof()->name(); -} - -FieldGenerator::~FieldGenerator() {} +void FieldGeneratorBase::GenerateIfHasField(io::Printer* p) const { + Y_ABSL_CHECK(internal::cpp::HasHasbit(descriptor_)); -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options, - MessageSCCAnalyzer* scc_analyzer) - : descriptor_(descriptor), field_generators_(descriptor->field_count()) { - // Construct all the FieldGenerators. - for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset( - MakeGenerator(descriptor->field(i), options, scc_analyzer)); - } + Formatter format(p); + format("if (($has_hasbit$) != 0) {\n"); } -FieldGenerator* FieldGeneratorMap::MakeGoogleInternalGenerator( - const FieldDescriptor* field, const Options& options, - MessageSCCAnalyzer* scc_analyzer) { - - return nullptr; -} +namespace { +std::unique_ptr<FieldGeneratorBase> MakeGenerator(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc) { -FieldGenerator* FieldGeneratorMap::MakeGenerator( - const FieldDescriptor* field, const Options& options, - MessageSCCAnalyzer* scc_analyzer) { - FieldGenerator* generator = - MakeGoogleInternalGenerator(field, options, scc_analyzer); - if (generator) { - return generator; + if (field->is_map()) { + return MakeMapGenerator(field, options, scc); } - if (field->is_repeated()) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: - if (field->is_map()) { - return new MapFieldGenerator(field, options, scc_analyzer); - } else { - return new RepeatedMessageFieldGenerator(field, options, - scc_analyzer); - } - case FieldDescriptor::CPPTYPE_STRING: - return new RepeatedStringFieldGenerator(field, options); - case FieldDescriptor::CPPTYPE_ENUM: - return new RepeatedEnumFieldGenerator(field, options); - default: - return new RepeatedPrimitiveFieldGenerator(field, options); - } - } else if (field->real_containing_oneof()) { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_MESSAGE: - return new MessageOneofFieldGenerator(field, options, scc_analyzer); - case FieldDescriptor::CPPTYPE_STRING: - return new StringOneofFieldGenerator(field, options); - case FieldDescriptor::CPPTYPE_ENUM: - return new EnumOneofFieldGenerator(field, options); - default: - return new PrimitiveOneofFieldGenerator(field, options); - } - } else { - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_MESSAGE: - return new MessageFieldGenerator(field, options, scc_analyzer); + return MakeRepeatedMessageGenerator(field, options, scc); case FieldDescriptor::CPPTYPE_STRING: - return new StringFieldGenerator(field, options); + return MakeRepeatedStringGenerator(field, options, scc); case FieldDescriptor::CPPTYPE_ENUM: - return new EnumFieldGenerator(field, options); + return MakeRepeatedEnumGenerator(field, options, scc); default: - return new PrimitiveFieldGenerator(field, options); + return MakeRepeatedPrimitiveGenerator(field, options, scc); } } + + if (field->real_containing_oneof() && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + return MakeOneofMessageGenerator(field, options, scc); + } + + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_MESSAGE: + return MakeSinguarMessageGenerator(field, options, scc); + case FieldDescriptor::CPPTYPE_STRING: + return MakeSinguarStringGenerator(field, options, scc); + case FieldDescriptor::CPPTYPE_ENUM: + return MakeSinguarEnumGenerator(field, options, scc); + default: + return MakeSinguarPrimitiveGenerator(field, options, scc); + } } -FieldGeneratorMap::~FieldGeneratorMap() {} +void HasBitVars(const FieldDescriptor* field, const Options& opts, + y_absl::optional<arc_ui32> idx, std::vector<Sub>& vars) { + if (!idx.has_value()) { + vars.emplace_back("set_hasbit", ""); + vars.emplace_back("clear_hasbit", ""); + return; + } + + Y_ABSL_CHECK(internal::cpp::HasHasbit(field)); + + arc_i32 index = *idx / 32; + TProtoStringType mask = y_absl::StrFormat("0x%08xu", 1u << (*idx % 32)); -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); - return *field_generators_[field->index()]; + y_absl::string_view has_bits = IsMapEntryMessage(field->containing_type()) + ? "_has_bits_" + : "_impl_._has_bits_"; + + auto has = y_absl::StrFormat("%s[%d] & %s", has_bits, index, mask); + auto set = y_absl::StrFormat("%s[%d] |= %s;", has_bits, index, mask); + auto clr = y_absl::StrFormat("%s[%d] &= ~%s;", has_bits, index, mask); + + vars.emplace_back("has_hasbit", has); + vars.emplace_back(Sub("set_hasbit", set).WithSuffix(";")); + vars.emplace_back(Sub("clear_hasbit", clr).WithSuffix(";")); +} + +void InlinedStringVars(const FieldDescriptor* field, const Options& opts, + y_absl::optional<arc_ui32> idx, std::vector<Sub>& vars) { + if (!IsStringInlined(field, opts)) { + Y_ABSL_CHECK(!idx.has_value()); + return; + } + + // The first bit is the tracking bit for on demand registering ArenaDtor. + Y_ABSL_CHECK_GT(*idx, 0) + << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; + + arc_i32 index = *idx / 32; + TProtoStringType mask = y_absl::StrFormat("0x%08xu", 1u << (*idx % 32)); + + y_absl::string_view array = IsMapEntryMessage(field->containing_type()) + ? "_inlined_string_donated_" + : "_impl_._inlined_string_donated_"; + + vars.emplace_back("inlined_string_donated", + y_absl::StrFormat("(%s[%d] & %s) != 0;", array, index, mask)); + vars.emplace_back("donating_states_word", + y_absl::StrFormat("%s[%d]", array, index)); + vars.emplace_back("mask_for_undonate", y_absl::StrFormat("~%s", mask)); +} +} // namespace + +FieldGenerator::FieldGenerator(const FieldDescriptor* field, + const Options& options, + MessageSCCAnalyzer* scc_analyzer, + y_absl::optional<arc_ui32> hasbit_index, + y_absl::optional<arc_ui32> inlined_string_index) + : impl_(MakeGenerator(field, options, scc_analyzer)), + field_vars_(FieldVars(field, options)), + tracker_vars_(MakeTrackerCalls(field, options)), + per_generator_vars_(impl_->MakeVars()) { + HasBitVars(field, options, hasbit_index, field_vars_); + InlinedStringVars(field, options, inlined_string_index, field_vars_); +} + +void FieldGeneratorTable::Build( + const Options& options, MessageSCCAnalyzer* scc, + y_absl::Span<const arc_i32> has_bit_indices, + y_absl::Span<const arc_i32> inlined_string_indices) { + // Construct all the FieldGenerators. + fields_.reserve(descriptor_->field_count()); + for (const auto* field : internal::FieldRange(descriptor_)) { + y_absl::optional<arc_ui32> has_bit_index; + if (!has_bit_indices.empty() && has_bit_indices[field->index()] >= 0) { + has_bit_index = static_cast<arc_ui32>(has_bit_indices[field->index()]); + } + + y_absl::optional<arc_ui32> inlined_string_index; + if (!inlined_string_indices.empty() && + inlined_string_indices[field->index()] >= 0) { + inlined_string_index = + static_cast<arc_ui32>(inlined_string_indices[field->index()]); + } + + fields_.push_back(FieldGenerator(field, options, scc, has_bit_index, + inlined_string_index)); + } } } // namespace cpp |
