Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:11:56

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 
0012 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
0013 #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
0014 
0015 #include <cstddef>
0016 #include <cstdint>
0017 #include <limits>
0018 #include <memory>
0019 #include <string>
0020 #include <utility>
0021 #include <vector>
0022 
0023 #include "absl/container/flat_hash_map.h"
0024 #include "absl/strings/string_view.h"
0025 #include "google/protobuf/compiler/cpp/enum.h"
0026 #include "google/protobuf/compiler/cpp/extension.h"
0027 #include "google/protobuf/compiler/cpp/field.h"
0028 #include "google/protobuf/compiler/cpp/helpers.h"
0029 #include "google/protobuf/compiler/cpp/message_layout_helper.h"
0030 #include "google/protobuf/compiler/cpp/options.h"
0031 #include "google/protobuf/compiler/cpp/parse_function_generator.h"
0032 #include "google/protobuf/io/printer.h"
0033 
0034 namespace google {
0035 namespace protobuf {
0036 namespace compiler {
0037 namespace cpp {
0038 class MessageGenerator {
0039  public:
0040   MessageGenerator(
0041       const Descriptor* descriptor,
0042       const absl::flat_hash_map<absl::string_view, std::string>& ignored,
0043       int index_in_file_messages, const Options& options,
0044       MessageSCCAnalyzer* scc_analyzer);
0045 
0046   MessageGenerator(const MessageGenerator&) = delete;
0047   MessageGenerator& operator=(const MessageGenerator&) = delete;
0048 
0049   ~MessageGenerator() = default;
0050 
0051   int index_in_file_messages() const { return index_in_file_messages_; }
0052 
0053   // Append the two types of nested generators to the corresponding vector.
0054   void AddGenerators(
0055       std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
0056       std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
0057 
0058   // Generate definitions for this class and all its nested types.
0059   void GenerateClassDefinition(io::Printer* p);
0060 
0061   // Generate definitions of inline methods (placed at the end of the header
0062   // file).
0063   void GenerateInlineMethods(io::Printer* p);
0064 
0065   // Generate all non-inline methods for this class.
0066   void GenerateClassMethods(io::Printer* p);
0067 
0068   // Generate source file code that should go outside any namespace.
0069   void GenerateSourceInProto2Namespace(io::Printer* p);
0070 
0071 
0072   void GenerateInitDefaultSplitInstance(io::Printer* p);
0073 
0074   // Generate the constexpr constructor for constant initialization of the
0075   // default instance.
0076   void GenerateConstexprConstructor(io::Printer* p);
0077 
0078   void GenerateSchema(io::Printer* p, int offset, int has_offset);
0079 
0080   // Generate the field offsets array.  Returns the a pair of the total number
0081   // of entries generated and the index of the first has_bit entry.
0082   std::pair<size_t, size_t> GenerateOffsets(io::Printer* p);
0083 
0084   const Descriptor* descriptor() const { return descriptor_; }
0085 
0086  private:
0087   using GeneratorFunction = FieldGeneratorBase::GeneratorFunction;
0088   enum class InitType { kConstexpr, kArena, kArenaCopy };
0089 
0090   // Generate declarations and definitions of accessors for fields.
0091   void GenerateFieldAccessorDeclarations(io::Printer* p);
0092   void GenerateFieldAccessorDefinitions(io::Printer* p);
0093 
0094   // Generate constructors and destructor.
0095   void GenerateStructors(io::Printer* p);
0096 
0097   void GenerateZeroInitFields(io::Printer* p) const;
0098   void GenerateCopyInitFields(io::Printer* p) const;
0099 
0100   void GenerateImplMemberInit(io::Printer* p, InitType init_type);
0101 
0102   void GenerateArenaEnabledCopyConstructor(io::Printer* p);
0103 
0104   // The compiler typically generates multiple copies of each constructor and
0105   // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
0106   // Placing common code in a separate method reduces the generated code size.
0107   //
0108   // Generate the shared constructor code.
0109   void GenerateSharedConstructorCode(io::Printer* p);
0110 
0111   // Generate the shared destructor code.
0112   void GenerateSharedDestructorCode(io::Printer* p);
0113   // Generate the arena-specific destructor code.
0114   void GenerateArenaDestructorCode(io::Printer* p);
0115 
0116   // Generate standard Message methods.
0117   void GenerateClear(io::Printer* p);
0118   void GenerateOneofClear(io::Printer* p);
0119   void GenerateVerifyDecl(io::Printer* p);
0120   void GenerateVerify(io::Printer* p);
0121   void GenerateAnnotationDecl(io::Printer* p);
0122   void GenerateSerializeWithCachedSizes(io::Printer* p);
0123   void GenerateSerializeWithCachedSizesToArray(io::Printer* p);
0124   void GenerateSerializeWithCachedSizesBody(io::Printer* p);
0125   void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* p);
0126   void GenerateByteSize(io::Printer* p);
0127   void GenerateClassData(io::Printer* p);
0128   void GenerateMapEntryClassDefinition(io::Printer* p);
0129   void GenerateAnyMethodDefinition(io::Printer* p);
0130   void GenerateImplDefinition(io::Printer* p);
0131   void GenerateClassSpecificMergeImpl(io::Printer* p);
0132   void GenerateCopyFrom(io::Printer* p);
0133   void GenerateSwap(io::Printer* p);
0134   void GenerateIsInitialized(io::Printer* p);
0135   bool NeedsIsInitialized();
0136 
0137   // Helpers for GenerateSerializeWithCachedSizes().
0138   //
0139   // cached_has_bit_index maintains that:
0140   //   cached_has_bits = _has_bits_[cached_has_bit_index]
0141   // for cached_has_bit_index >= 0
0142   void GenerateSerializeOneField(io::Printer* p, const FieldDescriptor* field,
0143                                  int cached_has_bits_index);
0144   // Generate a switch statement to serialize 2+ fields from the same oneof.
0145   // Or, if fields.size() == 1, just call GenerateSerializeOneField().
0146   void GenerateSerializeOneofFields(
0147       io::Printer* p, const std::vector<const FieldDescriptor*>& fields);
0148   void GenerateSerializeOneExtensionRange(io::Printer* p, int start, int end);
0149 
0150   // Generates has_foo() functions and variables for singular field has-bits.
0151   void GenerateSingularFieldHasBits(const FieldDescriptor* field,
0152                                     io::Printer* p);
0153   // Generates has_foo() functions and variables for oneof field has-bits.
0154   void GenerateOneofHasBits(io::Printer* p);
0155   // Generates has_foo_bar() functions for oneof members.
0156   void GenerateOneofMemberHasBits(const FieldDescriptor* field, io::Printer* p);
0157   // Generates the clear_foo() method for a field.
0158   void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
0159                           io::Printer* p);
0160 
0161   // Returns true if any of the fields needs an `arena` variable containing
0162   // the current message's arena, reducing `GetArena()` call churn.
0163   bool RequiresArena(GeneratorFunction function) const;
0164 
0165   // Returns whether impl_ has a copy ctor.
0166   bool ImplHasCopyCtor() const;
0167 
0168   // Returns the level that this message needs ArenaDtor. If the message has
0169   // a field that is not arena-exclusive, it needs an ArenaDtor
0170   // (go/proto-destructor).
0171   //
0172   // - Returning kNone means we don't need to generate ArenaDtor.
0173   // - Returning kOnDemand means we need to generate ArenaDtor, but don't need
0174   //   to register ArenaDtor at construction. Such as when the message's
0175   //   ArenaDtor code is only for destructing inlined string.
0176   // - Returning kRequired means we meed to generate ArenaDtor and register it
0177   //   at construction.
0178   ArenaDtorNeeds NeedsArenaDestructor() const;
0179 
0180   size_t HasBitsSize() const;
0181   size_t InlinedStringDonatedSize() const;
0182   absl::flat_hash_map<absl::string_view, std::string> HasBitVars(
0183       const FieldDescriptor* field) const;
0184   int HasBitIndex(const FieldDescriptor* field) const;
0185   int HasByteIndex(const FieldDescriptor* field) const;
0186   int HasWordIndex(const FieldDescriptor* field) const;
0187   std::vector<uint32_t> RequiredFieldsBitMask() const;
0188 
0189   const Descriptor* descriptor_;
0190   int index_in_file_messages_;
0191   Options options_;
0192   FieldGeneratorTable field_generators_;
0193   // optimized_order_ is the order we layout the message's fields in the
0194   // class. This is reused to initialize the fields in-order for cache
0195   // efficiency.
0196   //
0197   // optimized_order_ excludes oneof fields and weak fields.
0198   std::vector<const FieldDescriptor*> optimized_order_;
0199   std::vector<int> has_bit_indices_;
0200   int max_has_bit_index_ = 0;
0201 
0202   // A map from field index to inlined_string index. For non-inlined-string
0203   // fields, the element is -1. If there is no inlined string in the message,
0204   // this is empty.
0205   std::vector<int> inlined_string_indices_;
0206   // The count of inlined_string fields in the message.
0207   int max_inlined_string_index_ = 0;
0208 
0209   std::vector<const EnumGenerator*> enum_generators_;
0210   std::vector<const ExtensionGenerator*> extension_generators_;
0211   int num_required_fields_ = 0;
0212   int num_weak_fields_ = 0;
0213 
0214   std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
0215   std::unique_ptr<ParseFunctionGenerator> parse_function_generator_;
0216 
0217   MessageSCCAnalyzer* scc_analyzer_;
0218 
0219   absl::flat_hash_map<absl::string_view, std::string> variables_;
0220 
0221 };
0222 
0223 }  // namespace cpp
0224 }  // namespace compiler
0225 }  // namespace protobuf
0226 }  // namespace google
0227 
0228 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__