1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 // Author: kenton@google.com (Kenton Varda) 9 // Based on original Protocol Buffers design by 10 // Sanjay Ghemawat, Jeff Dean, and others. 11 12 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ 13 #define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <memory> 18 #include <string> 19 #include <vector> 20 21 #include "absl/container/flat_hash_map.h" 22 #include "absl/log/absl_check.h" 23 #include "absl/strings/string_view.h" 24 #include "absl/types/optional.h" 25 #include "absl/types/span.h" 26 #include "google/protobuf/compiler/cpp/helpers.h" 27 #include "google/protobuf/compiler/cpp/options.h" 28 #include "google/protobuf/descriptor.h" 29 #include "google/protobuf/io/printer.h" 30 31 namespace google { 32 namespace protobuf { 33 namespace compiler { 34 namespace cpp { 35 36 // Customization points for each field codegen type. See FieldGenerator to 37 // see how each of these functions is used. 38 // 39 // TODO: Make every function except the dtor in this generator 40 // non-pure-virtual. A generator with no implementation should be able to 41 // automatically not contribute any code to the message it is part of, as a 42 // matter of clean composability. 43 class FieldGeneratorBase { 44 public: 45 // `GeneratorFunction` defines a subset of generator functions that may have 46 // additional optimizations or requirements such as 'uses a local `arena` 47 // variable instead of calling GetArena()' 48 enum class GeneratorFunction { kMergeFrom }; 49 50 FieldGeneratorBase(const FieldDescriptor* field, const Options& options, 51 MessageSCCAnalyzer* scc_analyzer); 52 53 FieldGeneratorBase(const FieldGeneratorBase&) = delete; 54 FieldGeneratorBase& operator=(const FieldGeneratorBase&) = delete; 55 56 virtual ~FieldGeneratorBase() = 0; 57 58 // Returns true if this field should be placed in the cold 'Split' section. should_split()59 bool should_split() const { return should_split_; } 60 61 // Returns true if this field is trivial. (int, float, double, enum, bool) is_trivial()62 bool is_trivial() const { return is_trivial_; } 63 64 // Returns true if the field value itself is trivial, i.e., the field is 65 // trivial, or a (raw) pointer value to a singular, non lazy message. has_trivial_value()66 bool has_trivial_value() const { return has_trivial_value_; } 67 68 // Returns true if the provided field has a trivial zero default. 69 // I.e., the field can be initialized with `memset(&field, 0, sizeof(field))` has_trivial_zero_default()70 bool has_trivial_zero_default() const { return has_trivial_zero_default_; } 71 72 // Returns true if the provided field can be initialized with `= {}`. has_brace_default_assign()73 bool has_brace_default_assign() const { return has_brace_default_assign_; } 74 75 // Returns true if the field is a singular or repeated message. 76 // This includes group message types. To explicitly check if a message 77 // type is a group type, use the `is_group()` function, is_message()78 bool is_message() const { return is_message_; } 79 80 // Returns true if the field is a group message field (TYPE_GROUP). is_group()81 bool is_group() const { return is_group_; } 82 83 // Returns true if the field is a weak message is_weak()84 bool is_weak() const { return is_weak_; } 85 86 // Returns true if the field is a lazy message. is_lazy()87 bool is_lazy() const { return is_lazy_; } 88 89 // Returns true if the field is a foreign message field. is_foreign()90 bool is_foreign() const { return is_foreign_; } 91 92 // Returns true if the field is a string field. is_string()93 bool is_string() const { return is_string_; } 94 95 // Returns true if the field API uses bytes (void) instead of chars. is_bytes()96 bool is_bytes() const { return is_bytes_; } 97 98 // Returns true if this field is part of a oneof field. is_oneof()99 bool is_oneof() const { return is_oneof_; } 100 101 // Returns true if the field should be inlined instead of dynamically 102 // allocated. Applies to string and message value. is_inlined()103 bool is_inlined() const { return is_inlined_; } 104 105 // Returns true if this field has an appropriate default constexpr 106 // constructor. i.e., there is no need for an explicit initializer. has_default_constexpr_constructor()107 bool has_default_constexpr_constructor() const { 108 return has_default_constexpr_constructor_; 109 } 110 111 // Returns true if this generator requires an 'arena' parameter on the 112 // given generator function. RequiresArena(GeneratorFunction)113 virtual bool RequiresArena(GeneratorFunction) const { return false; } 114 MakeVars()115 virtual std::vector<io::Printer::Sub> MakeVars() const { return {}; } 116 117 virtual void GeneratePrivateMembers(io::Printer* p) const = 0; 118 GenerateStaticMembers(io::Printer * p)119 virtual void GenerateStaticMembers(io::Printer* p) const {} 120 121 virtual void GenerateAccessorDeclarations(io::Printer* p) const = 0; 122 123 virtual void GenerateInlineAccessorDefinitions(io::Printer* p) const = 0; 124 GenerateNonInlineAccessorDefinitions(io::Printer * p)125 virtual void GenerateNonInlineAccessorDefinitions(io::Printer* p) const {} 126 127 virtual void GenerateClearingCode(io::Printer* p) const = 0; 128 GenerateMessageClearingCode(io::Printer * p)129 virtual void GenerateMessageClearingCode(io::Printer* p) const { 130 GenerateClearingCode(p); 131 } 132 133 virtual void GenerateMergingCode(io::Printer* p) const = 0; 134 135 virtual void GenerateCopyConstructorCode(io::Printer* p) const; 136 137 virtual void GenerateSwappingCode(io::Printer* p) const = 0; 138 139 virtual void GenerateConstructorCode(io::Printer* p) const = 0; 140 GenerateDestructorCode(io::Printer * p)141 virtual void GenerateDestructorCode(io::Printer* p) const {} 142 GenerateArenaDestructorCode(io::Printer * p)143 virtual void GenerateArenaDestructorCode(io::Printer* p) const { 144 ABSL_CHECK(NeedsArenaDestructor() == ArenaDtorNeeds::kNone) 145 << field_->cpp_type_name(); 146 } 147 148 // Generates constexpr member initialization code, e.g.: `foo_{5}`. 149 // The default implementation generates the following code: 150 // - repeated fields and maps: `field_{}` 151 // - all other fields: `field_{<default value>}` 152 virtual void GenerateMemberConstexprConstructor(io::Printer* p) const; 153 154 // Generates member initialization code, e.g.: `foo_(5)`. 155 // The default implementation generates the following code: 156 // - repeated fields and maps: `field_{visibility, arena}` 157 // - split repeated fields (RawPtr): `field_{}` 158 // - all other fields: `field_{<default value>}` 159 virtual void GenerateMemberConstructor(io::Printer* p) const; 160 161 // Generates member copy initialization code, e.g.: `foo_(5)`. 162 // The default implementation generates the following code: 163 // - repeated fields and maps: `field_{visibility, arena, from.field_}` 164 // - all other fields: `field_{from.field_}` 165 virtual void GenerateMemberCopyConstructor(io::Printer* p) const; 166 167 // Generates 'placement new' copy construction code used to 168 // explicitly copy initialize oneof field values. 169 // The default implementation checks the current field to not be repeated, 170 // an extension or a map, and generates the following code: 171 // - `field_ = from.field_` 172 virtual void GenerateOneofCopyConstruct(io::Printer* p) const; 173 174 virtual void GenerateAggregateInitializer(io::Printer* p) const; 175 176 virtual void GenerateConstexprAggregateInitializer(io::Printer* p) const; 177 178 virtual void GenerateCopyAggregateInitializer(io::Printer* p) const; 179 180 virtual void GenerateSerializeWithCachedSizesToArray( 181 io::Printer* p) const = 0; 182 183 virtual void GenerateByteSize(io::Printer* p) const = 0; 184 GenerateIsInitialized(io::Printer * p)185 virtual void GenerateIsInitialized(io::Printer* p) const { 186 ABSL_CHECK(!NeedsIsInitialized()); 187 } NeedsIsInitialized()188 virtual bool NeedsIsInitialized() const { return false; } 189 IsInlined()190 virtual bool IsInlined() const { return false; } 191 NeedsArenaDestructor()192 virtual ArenaDtorNeeds NeedsArenaDestructor() const { 193 return ArenaDtorNeeds::kNone; 194 } 195 196 protected: 197 const FieldDescriptor* field_; 198 const Options& options_; 199 MessageSCCAnalyzer* scc_; 200 absl::flat_hash_map<absl::string_view, std::string> variables_; 201 202 private: 203 bool should_split_ = false; 204 bool is_trivial_ = false; 205 bool has_trivial_value_ = false; 206 bool has_trivial_zero_default_ = false; 207 bool has_brace_default_assign_ = false; 208 bool is_message_ = false; 209 bool is_group_ = false; 210 bool is_string_ = false; 211 bool is_bytes_ = false; 212 bool is_inlined_ = false; 213 bool is_foreign_ = false; 214 bool is_lazy_ = false; 215 bool is_weak_ = false; 216 bool is_oneof_ = false; 217 bool has_default_constexpr_constructor_ = false; 218 }; 219 220 inline FieldGeneratorBase::~FieldGeneratorBase() = default; 221 222 class FieldGenerator { 223 private: 224 // This function must be defined here so that the inline definitions below 225 // can see it, which is required because it has deduced return type. PushVarsForCall(io::Printer * p)226 auto PushVarsForCall(io::Printer* p) const { 227 // NOTE: we use a struct here because: 228 // * We want to ensure that order of evaluation below is well-defined, 229 // which {...} guarantees but (...) does not. 230 // * We do not require C++17 as of writing and therefore cannot use 231 // std::tuple with CTAD. 232 // * std::make_tuple uses (...), not {...}. 233 struct Vars { 234 decltype(p->WithVars(field_vars_)) cleanup1; 235 decltype(p->WithVars(tracker_vars_)) cleanup2; 236 decltype(p->WithVars(per_generator_vars_)) cleanup3; 237 }; 238 239 return Vars{p->WithVars(field_vars_), p->WithVars(tracker_vars_), 240 p->WithVars(per_generator_vars_)}; 241 } 242 243 public: 244 using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; 245 246 FieldGenerator(const FieldGenerator&) = delete; 247 FieldGenerator& operator=(const FieldGenerator&) = delete; 248 FieldGenerator(FieldGenerator&&) = default; 249 FieldGenerator& operator=(FieldGenerator&&) = default; 250 251 // Properties: see FieldGeneratorBase for documentation should_split()252 bool should_split() const { return impl_->should_split(); } is_trivial()253 bool is_trivial() const { return impl_->is_trivial(); } has_trivial_value()254 bool has_trivial_value() const { return impl_->has_trivial_value(); } has_trivial_zero_default()255 bool has_trivial_zero_default() const { 256 return impl_->has_trivial_zero_default(); 257 } has_brace_default_assign()258 bool has_brace_default_assign() const { 259 return impl_->has_brace_default_assign(); 260 } is_message()261 bool is_message() const { return impl_->is_message(); } is_group()262 bool is_group() const { return impl_->is_group(); } is_weak()263 bool is_weak() const { return impl_->is_weak(); } is_lazy()264 bool is_lazy() const { return impl_->is_lazy(); } is_foreign()265 bool is_foreign() const { return impl_->is_foreign(); } is_string()266 bool is_string() const { return impl_->is_string(); } is_bytes()267 bool is_bytes() const { return impl_->is_bytes(); } is_oneof()268 bool is_oneof() const { return impl_->is_oneof(); } is_inlined()269 bool is_inlined() const { return impl_->is_inlined(); } has_default_constexpr_constructor()270 bool has_default_constexpr_constructor() const { 271 return impl_->has_default_constexpr_constructor(); 272 } 273 274 // Requirements: see FieldGeneratorBase for documentation RequiresArena(GeneratorFunction function)275 bool RequiresArena(GeneratorFunction function) const { 276 return impl_->RequiresArena(function); 277 } 278 279 // Prints private members needed to represent this field. 280 // 281 // These are placed inside the class definition. GeneratePrivateMembers(io::Printer * p)282 void GeneratePrivateMembers(io::Printer* p) const { 283 auto vars = PushVarsForCall(p); 284 impl_->GeneratePrivateMembers(p); 285 } 286 287 // Prints static members needed to represent this field. 288 // 289 // These are placed inside the class definition. GenerateStaticMembers(io::Printer * p)290 void GenerateStaticMembers(io::Printer* p) const { 291 auto vars = PushVarsForCall(p); 292 impl_->GenerateStaticMembers(p); 293 } 294 GenerateMemberConstructor(io::Printer * p)295 void GenerateMemberConstructor(io::Printer* p) const { 296 auto vars = PushVarsForCall(p); 297 impl_->GenerateMemberConstructor(p); 298 } 299 GenerateMemberCopyConstructor(io::Printer * p)300 void GenerateMemberCopyConstructor(io::Printer* p) const { 301 auto vars = PushVarsForCall(p); 302 impl_->GenerateMemberCopyConstructor(p); 303 } 304 GenerateOneofCopyConstruct(io::Printer * p)305 void GenerateOneofCopyConstruct(io::Printer* p) const { 306 auto vars = PushVarsForCall(p); 307 impl_->GenerateOneofCopyConstruct(p); 308 } 309 GenerateMemberConstexprConstructor(io::Printer * p)310 void GenerateMemberConstexprConstructor(io::Printer* p) const { 311 auto vars = PushVarsForCall(p); 312 impl_->GenerateMemberConstexprConstructor(p); 313 } 314 315 // Generates declarations for all of the accessor functions related to this 316 // field. 317 // 318 // These are placed inside the class definition. GenerateAccessorDeclarations(io::Printer * p)319 void GenerateAccessorDeclarations(io::Printer* p) const { 320 auto vars = PushVarsForCall(p); 321 impl_->GenerateAccessorDeclarations(p); 322 } 323 324 // Generates inline definitions of accessor functions for this field. 325 // 326 // These are placed in namespace scope in the header after all class 327 // definitions. GenerateInlineAccessorDefinitions(io::Printer * p)328 void GenerateInlineAccessorDefinitions(io::Printer* p) const { 329 auto vars = PushVarsForCall(p); 330 impl_->GenerateInlineAccessorDefinitions(p); 331 } 332 333 // Generates definitions of accessors that aren't inlined. 334 // 335 // These are placed in namespace scope in the .cc file. GenerateNonInlineAccessorDefinitions(io::Printer * p)336 void GenerateNonInlineAccessorDefinitions(io::Printer* p) const { 337 auto vars = PushVarsForCall(p); 338 impl_->GenerateNonInlineAccessorDefinitions(p); 339 } 340 341 // Generates statements which clear the field. 342 // 343 // This is used to define the clear_$name$() method. GenerateClearingCode(io::Printer * p)344 void GenerateClearingCode(io::Printer* p) const { 345 auto vars = PushVarsForCall(p); 346 impl_->GenerateClearingCode(p); 347 } 348 349 // Generates statements which clear the field as part of the Clear() method 350 // for the whole message. 351 // 352 // For message types which have field presence bits, 353 // MessageGenerator::GenerateClear will have already checked the presence 354 // bits. GenerateMessageClearingCode(io::Printer * p)355 void GenerateMessageClearingCode(io::Printer* p) const { 356 auto vars = PushVarsForCall(p); 357 impl_->GenerateMessageClearingCode(p); 358 } 359 360 // Generates statements which merge the contents of the field from the current 361 // message to the target message, which is stored in the generated code 362 // variable `from`. 363 // 364 // This is used to fill in the MergeFrom method for the whole message. 365 // 366 // Details of this usage can be found in message.cc under the 367 // GenerateMergeFrom method. GenerateMergingCode(io::Printer * p)368 void GenerateMergingCode(io::Printer* p) const { 369 auto vars = PushVarsForCall(p); 370 impl_->GenerateMergingCode(p); 371 } 372 373 // Generates a copy constructor 374 // 375 // TODO: Document this properly. GenerateCopyConstructorCode(io::Printer * p)376 void GenerateCopyConstructorCode(io::Printer* p) const { 377 auto vars = PushVarsForCall(p); 378 impl_->GenerateCopyConstructorCode(p); 379 } 380 381 // Generates statements which swap this field and the corresponding field of 382 // another message, which is stored in the generated code variable `other`. 383 // 384 // This is used to define the Swap method. Details of usage can be found in 385 // message.cc under the GenerateSwap method. GenerateSwappingCode(io::Printer * p)386 void GenerateSwappingCode(io::Printer* p) const { 387 auto vars = PushVarsForCall(p); 388 impl_->GenerateSwappingCode(p); 389 } 390 391 // Generates initialization code for private members declared by 392 // GeneratePrivateMembers(). 393 // 394 // These go into the message class's SharedCtor() method, invoked by each of 395 // the generated constructors. GenerateConstructorCode(io::Printer * p)396 void GenerateConstructorCode(io::Printer* p) const { 397 auto vars = PushVarsForCall(p); 398 impl_->GenerateConstructorCode(p); 399 } 400 401 // Generates any code that needs to go in the class's SharedDtor() method, 402 // invoked by the destructor. GenerateDestructorCode(io::Printer * p)403 void GenerateDestructorCode(io::Printer* p) const { 404 auto vars = PushVarsForCall(p); 405 impl_->GenerateDestructorCode(p); 406 } 407 408 // Generates a manual destructor invocation for use when the message is on an 409 // arena. 410 // 411 // The code that this method generates will be executed inside a 412 // shared-for-the-whole-message-class method registered with OwnDestructor(). GenerateArenaDestructorCode(io::Printer * p)413 void GenerateArenaDestructorCode(io::Printer* p) const { 414 auto vars = PushVarsForCall(p); 415 impl_->GenerateArenaDestructorCode(p); 416 } 417 418 // Generates initialization code for private members declared by 419 // GeneratePrivateMembers(). 420 // 421 // These go into the SharedCtor's aggregate initialization of the _impl_ 422 // struct and must follow the syntax `decltype($field$){$default$}`. 423 // Does not include `:` or `,` separators. Default values should be specified 424 // here when possible. 425 // 426 // NOTE: We use `decltype($field$)` for both explicit construction and the 427 // fact that it's self-documenting. Pre-C++17, copy elision isn't guaranteed 428 // in aggregate initialization so a valid copy/move constructor must exist 429 // (even though it's not used). Because of this, we need to comment out the 430 // decltype and fallback to implicit construction. GenerateAggregateInitializer(io::Printer * p)431 void GenerateAggregateInitializer(io::Printer* p) const { 432 auto vars = PushVarsForCall(p); 433 impl_->GenerateAggregateInitializer(p); 434 } 435 436 // Generates constinit initialization code for private members declared by 437 // GeneratePrivateMembers(). 438 // 439 // These go into the constexpr constructor's aggregate initialization of the 440 // _impl_ struct and must follow the syntax `/*decltype($field$)*/{}` (see 441 // above). Does not include `:` or `,` separators. GenerateConstexprAggregateInitializer(io::Printer * p)442 void GenerateConstexprAggregateInitializer(io::Printer* p) const { 443 auto vars = PushVarsForCall(p); 444 impl_->GenerateConstexprAggregateInitializer(p); 445 } 446 447 // Generates copy initialization code for private members declared by 448 // GeneratePrivateMembers(). 449 // 450 // These go into the copy constructor's aggregate initialization of the _impl_ 451 // struct and must follow the syntax `decltype($field$){from.$field$}` (see 452 // above). Does not include `:` or `,` separators. GenerateCopyAggregateInitializer(io::Printer * p)453 void GenerateCopyAggregateInitializer(io::Printer* p) const { 454 auto vars = PushVarsForCall(p); 455 impl_->GenerateCopyAggregateInitializer(p); 456 } 457 458 // Generates statements to serialize this field directly to the array 459 // `target`, which are placed within the message's 460 // SerializeWithCachedSizesToArray() method. 461 // 462 // This must also advance `target` past the written bytes. GenerateSerializeWithCachedSizesToArray(io::Printer * p)463 void GenerateSerializeWithCachedSizesToArray(io::Printer* p) const { 464 auto vars = PushVarsForCall(p); 465 impl_->GenerateSerializeWithCachedSizesToArray(p); 466 } 467 468 // Generates statements to compute the serialized size of this field, which 469 // are placed in the message's ByteSize() method. GenerateByteSize(io::Printer * p)470 void GenerateByteSize(io::Printer* p) const { 471 auto vars = PushVarsForCall(p); 472 impl_->GenerateByteSize(p); 473 } 474 475 // Generates lines to call IsInitialized() for eligible message fields. Non 476 // message fields won't need to override this function. GenerateIsInitialized(io::Printer * p)477 void GenerateIsInitialized(io::Printer* p) const { 478 auto vars = PushVarsForCall(p); 479 impl_->GenerateIsInitialized(p); 480 } 481 NeedsIsInitialized()482 bool NeedsIsInitialized() const { return impl_->NeedsIsInitialized(); } 483 484 // TODO: Document this properly. IsInlined()485 bool IsInlined() const { return impl_->IsInlined(); } 486 487 // TODO: Document this properly. NeedsArenaDestructor()488 ArenaDtorNeeds NeedsArenaDestructor() const { 489 return impl_->NeedsArenaDestructor(); 490 } 491 492 private: 493 friend class FieldGeneratorTable; 494 FieldGenerator(const FieldDescriptor* field, const Options& options, 495 MessageSCCAnalyzer* scc_analyzer, 496 absl::optional<uint32_t> hasbit_index, 497 absl::optional<uint32_t> inlined_string_index); 498 499 std::unique_ptr<FieldGeneratorBase> impl_; 500 std::vector<io::Printer::Sub> field_vars_; 501 std::vector<io::Printer::Sub> tracker_vars_; 502 std::vector<io::Printer::Sub> per_generator_vars_; 503 }; 504 505 // Convenience class which constructs FieldGeneratorBases for a Descriptor. 506 class FieldGeneratorTable { 507 public: FieldGeneratorTable(const Descriptor * descriptor)508 explicit FieldGeneratorTable(const Descriptor* descriptor) 509 : descriptor_(descriptor) {} 510 511 FieldGeneratorTable(const FieldGeneratorTable&) = delete; 512 FieldGeneratorTable& operator=(const FieldGeneratorTable&) = delete; 513 514 void Build(const Options& options, MessageSCCAnalyzer* scc_analyzer, 515 absl::Span<const int32_t> has_bit_indices, 516 absl::Span<const int32_t> inlined_string_indices); 517 get(const FieldDescriptor * field)518 const FieldGenerator& get(const FieldDescriptor* field) const { 519 ABSL_CHECK_EQ(field->containing_type(), descriptor_); 520 ABSL_DCHECK_GE(field->index(), 0); 521 return fields_[static_cast<size_t>(field->index())]; 522 } 523 524 private: 525 const Descriptor* descriptor_; 526 std::vector<FieldGenerator> fields_; 527 }; 528 529 // Returns variables common to all fields. 530 // 531 // TODO: Make this function .cc-private. 532 std::vector<io::Printer::Sub> FieldVars(const FieldDescriptor* field, 533 const Options& opts); 534 } // namespace cpp 535 } // namespace compiler 536 } // namespace protobuf 537 } // namespace google 538 539 #endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__ 540