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_MESSAGE_H__ 13 #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <memory> 18 #include <string> 19 #include <utility> 20 #include <vector> 21 22 #include "absl/container/flat_hash_map.h" 23 #include "absl/strings/string_view.h" 24 #include "google/protobuf/compiler/cpp/enum.h" 25 #include "google/protobuf/compiler/cpp/extension.h" 26 #include "google/protobuf/compiler/cpp/field.h" 27 #include "google/protobuf/compiler/cpp/helpers.h" 28 #include "google/protobuf/compiler/cpp/message_layout_helper.h" 29 #include "google/protobuf/compiler/cpp/options.h" 30 #include "google/protobuf/compiler/cpp/parse_function_generator.h" 31 #include "google/protobuf/descriptor.h" 32 #include "google/protobuf/io/printer.h" 33 34 namespace google { 35 namespace protobuf { 36 namespace compiler { 37 namespace cpp { 38 class MessageGenerator { 39 public: 40 MessageGenerator( 41 const Descriptor* descriptor, 42 const absl::flat_hash_map<absl::string_view, std::string>& ignored, 43 int index_in_file_messages, const Options& options, 44 MessageSCCAnalyzer* scc_analyzer); 45 46 MessageGenerator(const MessageGenerator&) = delete; 47 MessageGenerator& operator=(const MessageGenerator&) = delete; 48 49 ~MessageGenerator() = default; 50 index_in_file_messages()51 int index_in_file_messages() const { return index_in_file_messages_; } 52 53 // Append the two types of nested generators to the corresponding vector. 54 void AddGenerators( 55 std::vector<std::unique_ptr<EnumGenerator>>* enum_generators, 56 std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators); 57 58 // Generate definitions for this class and all its nested types. 59 void GenerateClassDefinition(io::Printer* p); 60 61 // Generate definitions of inline methods (placed at the end of the header 62 // file). 63 void GenerateInlineMethods(io::Printer* p); 64 65 // Generate all non-inline methods for this class. 66 void GenerateClassMethods(io::Printer* p); 67 68 // Generate source file code that should go outside any namespace. 69 void GenerateSourceInProto2Namespace(io::Printer* p); 70 71 72 void GenerateInitDefaultSplitInstance(io::Printer* p); 73 74 // Generate the constexpr constructor for constant initialization of the 75 // default instance. 76 void GenerateConstexprConstructor(io::Printer* p); 77 78 void GenerateSchema(io::Printer* p, int offset, int has_offset); 79 80 // Generate the field offsets array. Returns the a pair of the total number 81 // of entries generated and the index of the first has_bit entry. 82 std::pair<size_t, size_t> GenerateOffsets(io::Printer* p); 83 descriptor()84 const Descriptor* descriptor() const { return descriptor_; } 85 86 private: 87 using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; 88 enum class InitType { kConstexpr, kArena, kArenaCopy }; 89 90 // Generate declarations and definitions of accessors for fields. 91 void GenerateFieldAccessorDeclarations(io::Printer* p); 92 void GenerateFieldAccessorDefinitions(io::Printer* p); 93 94 // Generate constructors and destructor. 95 void GenerateStructors(io::Printer* p); 96 97 void GenerateZeroInitFields(io::Printer* p) const; 98 void GenerateCopyInitFields(io::Printer* p) const; 99 100 void GenerateImplMemberInit(io::Printer* p, InitType init_type); 101 102 void GenerateArenaEnabledCopyConstructor(io::Printer* p); 103 104 // The compiler typically generates multiple copies of each constructor and 105 // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx 106 // Placing common code in a separate method reduces the generated code size. 107 // 108 // Generate the shared constructor code. 109 void GenerateSharedConstructorCode(io::Printer* p); 110 111 // Generate the shared destructor code. 112 void GenerateSharedDestructorCode(io::Printer* p); 113 // Generate the arena-specific destructor code. 114 void GenerateArenaDestructorCode(io::Printer* p); 115 116 // Generate standard Message methods. 117 void GenerateClear(io::Printer* p); 118 void GenerateOneofClear(io::Printer* p); 119 void GenerateVerifyDecl(io::Printer* p); 120 void GenerateVerify(io::Printer* p); 121 void GenerateAnnotationDecl(io::Printer* p); 122 void GenerateSerializeWithCachedSizes(io::Printer* p); 123 void GenerateSerializeWithCachedSizesToArray(io::Printer* p); 124 void GenerateSerializeWithCachedSizesBody(io::Printer* p); 125 void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* p); 126 void GenerateByteSize(io::Printer* p); 127 void GenerateClassData(io::Printer* p); 128 void GenerateMapEntryClassDefinition(io::Printer* p); 129 void GenerateAnyMethodDefinition(io::Printer* p); 130 void GenerateImplDefinition(io::Printer* p); 131 void GenerateClassSpecificMergeImpl(io::Printer* p); 132 void GenerateCopyFrom(io::Printer* p); 133 void GenerateSwap(io::Printer* p); 134 void GenerateIsInitialized(io::Printer* p); 135 bool NeedsIsInitialized(); 136 137 struct NewOpRequirements { 138 // Some field is initialized to non-zero values. Eg string fields pointing 139 // to default string. 140 bool needs_memcpy = false; 141 // Some field has a copy of the arena. 142 bool needs_arena_seeding = false; 143 // Some field has logic that needs to run. 144 bool needs_to_run_constructor = false; 145 }; 146 NewOpRequirements GetNewOp(io::Printer* arena_emitter) const; 147 148 // Helpers for GenerateSerializeWithCachedSizes(). 149 // 150 // cached_has_bit_index maintains that: 151 // cached_has_bits = _has_bits_[cached_has_bit_index] 152 // for cached_has_bit_index >= 0 153 void GenerateSerializeOneField(io::Printer* p, const FieldDescriptor* field, 154 int cached_has_bits_index); 155 // Generate a switch statement to serialize 2+ fields from the same oneof. 156 // Or, if fields.size() == 1, just call GenerateSerializeOneField(). 157 void GenerateSerializeOneofFields( 158 io::Printer* p, const std::vector<const FieldDescriptor*>& fields); 159 void GenerateSerializeOneExtensionRange(io::Printer* p, int start, int end); 160 161 // Generates has_foo() functions and variables for singular field has-bits. 162 void GenerateSingularFieldHasBits(const FieldDescriptor* field, 163 io::Printer* p); 164 // Generates has_foo() functions and variables for oneof field has-bits. 165 void GenerateOneofHasBits(io::Printer* p); 166 // Generates has_foo_bar() functions for oneof members. 167 void GenerateOneofMemberHasBits(const FieldDescriptor* field, io::Printer* p); 168 // Generates the clear_foo() method for a field. 169 void GenerateFieldClear(const FieldDescriptor* field, bool is_inline, 170 io::Printer* p); 171 172 // Returns true if any of the fields needs an `arena` variable containing 173 // the current message's arena, reducing `GetArena()` call churn. 174 bool RequiresArena(GeneratorFunction function) const; 175 176 // Returns whether impl_ has a copy ctor. 177 bool ImplHasCopyCtor() const; 178 179 // Returns the level that this message needs ArenaDtor. If the message has 180 // a field that is not arena-exclusive, it needs an ArenaDtor 181 // (go/proto-destructor). 182 // 183 // - Returning kNone means we don't need to generate ArenaDtor. 184 // - Returning kOnDemand means we need to generate ArenaDtor, but don't need 185 // to register ArenaDtor at construction. Such as when the message's 186 // ArenaDtor code is only for destructing inlined string. 187 // - Returning kRequired means we meed to generate ArenaDtor and register it 188 // at construction. 189 ArenaDtorNeeds NeedsArenaDestructor() const; 190 191 size_t HasBitsSize() const; 192 size_t InlinedStringDonatedSize() const; 193 absl::flat_hash_map<absl::string_view, std::string> HasBitVars( 194 const FieldDescriptor* field) const; 195 int HasBitIndex(const FieldDescriptor* field) const; 196 int HasByteIndex(const FieldDescriptor* field) const; 197 int HasWordIndex(const FieldDescriptor* field) const; 198 std::vector<uint32_t> RequiredFieldsBitMask() const; 199 200 // Helper functions to reduce nesting levels of deep Emit calls. 201 void EmitCheckAndUpdateByteSizeForField(const FieldDescriptor* field, 202 io::Printer* p) const; 203 void EmitUpdateByteSizeForField(const FieldDescriptor* field, io::Printer* p, 204 int& cached_has_word_index) const; 205 206 const Descriptor* descriptor_; 207 int index_in_file_messages_; 208 Options options_; 209 FieldGeneratorTable field_generators_; 210 // optimized_order_ is the order we layout the message's fields in the 211 // class. This is reused to initialize the fields in-order for cache 212 // efficiency. 213 // 214 // optimized_order_ excludes oneof fields and weak fields. 215 std::vector<const FieldDescriptor*> optimized_order_; 216 std::vector<int> has_bit_indices_; 217 int max_has_bit_index_ = 0; 218 219 // A map from field index to inlined_string index. For non-inlined-string 220 // fields, the element is -1. If there is no inlined string in the message, 221 // this is empty. 222 std::vector<int> inlined_string_indices_; 223 // The count of inlined_string fields in the message. 224 int max_inlined_string_index_ = 0; 225 226 std::vector<const EnumGenerator*> enum_generators_; 227 std::vector<const ExtensionGenerator*> extension_generators_; 228 int num_required_fields_ = 0; 229 int num_weak_fields_ = 0; 230 231 std::unique_ptr<MessageLayoutHelper> message_layout_helper_; 232 std::unique_ptr<ParseFunctionGenerator> parse_function_generator_; 233 234 MessageSCCAnalyzer* scc_analyzer_; 235 236 absl::flat_hash_map<absl::string_view, std::string> variables_; 237 238 }; 239 240 } // namespace cpp 241 } // namespace compiler 242 } // namespace protobuf 243 } // namespace google 244 245 #endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ 246