• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
36 #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
37 
38 #include <cstdint>
39 #include <memory>
40 #include <set>
41 #include <string>
42 
43 #include <google/protobuf/compiler/cpp/cpp_field.h>
44 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
45 #include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h>
46 #include <google/protobuf/compiler/cpp/cpp_options.h>
47 #include <google/protobuf/compiler/cpp/cpp_parse_function_generator.h>
48 
49 namespace google {
50 namespace protobuf {
51 namespace io {
52 class Printer;  // printer.h
53 }
54 }  // namespace protobuf
55 }  // namespace google
56 
57 namespace google {
58 namespace protobuf {
59 namespace compiler {
60 namespace cpp {
61 
62 class EnumGenerator;       // enum.h
63 class ExtensionGenerator;  // extension.h
64 
65 class MessageGenerator {
66  public:
67   // See generator.cc for the meaning of dllexport_decl.
68   MessageGenerator(const Descriptor* descriptor,
69                    const std::map<std::string, std::string>& vars,
70                    int index_in_file_messages, const Options& options,
71                    MessageSCCAnalyzer* scc_analyzer);
72   ~MessageGenerator();
73 
74   // Append the two types of nested generators to the corresponding vector.
75   void AddGenerators(
76       std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
77       std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
78 
79   // Generate definitions for this class and all its nested types.
80   void GenerateClassDefinition(io::Printer* printer);
81 
82   // Generate definitions of inline methods (placed at the end of the header
83   // file).
84   void GenerateInlineMethods(io::Printer* printer);
85 
86   // Source file stuff.
87 
88   // Generate all non-inline methods for this class.
89   void GenerateClassMethods(io::Printer* printer);
90 
91   // Generate source file code that should go outside any namespace.
92   void GenerateSourceInProto2Namespace(io::Printer* printer);
93 
94  private:
95   // Generate declarations and definitions of accessors for fields.
96   void GenerateFieldAccessorDeclarations(io::Printer* printer);
97   void GenerateFieldAccessorDefinitions(io::Printer* printer);
98 
99   // Generate the field offsets array.  Returns the a pair of the total number
100   // of entries generated and the index of the first has_bit entry.
101   std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
102   void GenerateSchema(io::Printer* printer, int offset, int has_offset);
103 
104   // Generate constructors and destructor.
105   void GenerateStructors(io::Printer* printer);
106 
107   // The compiler typically generates multiple copies of each constructor and
108   // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
109   // Placing common code in a separate method reduces the generated code size.
110   //
111   // Generate the shared constructor code.
112   void GenerateSharedConstructorCode(io::Printer* printer);
113   // Generate the shared destructor code.
114   void GenerateSharedDestructorCode(io::Printer* printer);
115   // Generate the arena-specific destructor code.
116   void GenerateArenaDestructorCode(io::Printer* printer);
117 
118   // Generate the constexpr constructor for constant initialization of the
119   // default instance.
120   void GenerateConstexprConstructor(io::Printer* printer);
121 
122   // Generate standard Message methods.
123   void GenerateClear(io::Printer* printer);
124   void GenerateOneofClear(io::Printer* printer);
125   void GenerateVerify(io::Printer* printer);
126   void GenerateSerializeWithCachedSizes(io::Printer* printer);
127   void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
128   void GenerateSerializeWithCachedSizesBody(io::Printer* printer);
129   void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer);
130   void GenerateByteSize(io::Printer* printer);
131   void GenerateMergeFrom(io::Printer* printer);
132   void GenerateClassSpecificMergeFrom(io::Printer* printer);
133   void GenerateCopyFrom(io::Printer* printer);
134   void GenerateSwap(io::Printer* printer);
135   void GenerateIsInitialized(io::Printer* printer);
136 
137   // Helpers for GenerateSerializeWithCachedSizes().
138   //
139   // cached_has_bit_index maintains that:
140   //   cached_has_bits = _has_bits_[cached_has_bit_index]
141   // for cached_has_bit_index >= 0
142   void GenerateSerializeOneField(io::Printer* printer,
143                                  const FieldDescriptor* field,
144                                  int cached_has_bits_index);
145   // Generate a switch statement to serialize 2+ fields from the same oneof.
146   // Or, if fields.size() == 1, just call GenerateSerializeOneField().
147   void GenerateSerializeOneofFields(
148       io::Printer* printer, const std::vector<const FieldDescriptor*>& fields);
149   void GenerateSerializeOneExtensionRange(
150       io::Printer* printer, const Descriptor::ExtensionRange* range);
151 
152   // Generates has_foo() functions and variables for singular field has-bits.
153   void GenerateSingularFieldHasBits(const FieldDescriptor* field,
154                                     Formatter format);
155   // Generates has_foo() functions and variables for oneof field has-bits.
156   void GenerateOneofHasBits(io::Printer* printer);
157   // Generates has_foo_bar() functions for oneof members.
158   void GenerateOneofMemberHasBits(const FieldDescriptor* field,
159                                   const Formatter& format);
160   // Generates the clear_foo() method for a field.
161   void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
162                           Formatter format);
163 
164   void GenerateConstructorBody(io::Printer* printer,
165                                std::vector<bool> already_processed,
166                                bool copy_constructor) const;
167 
168   // Returns the level that this message needs ArenaDtor. If the message has
169   // a field that is not arena-exclusive, it needs an ArenaDtor
170   // (go/proto-destructor).
171   //
172   // - Returning kNone means we don't need to generate ArenaDtor.
173   // - Returning kOnDemand means we need to generate ArenaDtor, but don't need
174   //   to register ArenaDtor at construction. Such as when the message's
175   //   ArenaDtor code is only for destructing inlined string.
176   // - Returning kRequired means we meed to generate ArenaDtor and register it
177   //   at construction.
178   ArenaDtorNeeds NeedsArenaDestructor() const;
179 
180   size_t HasBitsSize() const;
181   size_t InlinedStringDonatedSize() const;
182   int HasBitIndex(const FieldDescriptor* a) const;
183   int HasByteIndex(const FieldDescriptor* a) const;
184   int HasWordIndex(const FieldDescriptor* a) const;
185   bool SameHasByte(const FieldDescriptor* a, const FieldDescriptor* b) const;
186   std::vector<uint32_t> RequiredFieldsBitMask() const;
187 
188   const Descriptor* descriptor_;
189   int index_in_file_messages_;
190   std::string classname_;
191   Options options_;
192   FieldGeneratorMap field_generators_;
193   // optimized_order_ is the order we layout the message's fields in the
194   // class. This is reused to initialize the fields in-order for cache
195   // efficiency.
196   //
197   // optimized_order_ excludes oneof fields and weak fields.
198   std::vector<const FieldDescriptor*> optimized_order_;
199   std::vector<int> has_bit_indices_;
200   int max_has_bit_index_;
201 
202   // A map from field index to inlined_string index. For non-inlined-string
203   // fields, the element is -1. If there is no inlined string in the message,
204   // this is empty.
205   std::vector<int> inlined_string_indices_;
206   // The count of inlined_string fields in the message.
207   int max_inlined_string_index_;
208 
209   std::vector<const EnumGenerator*> enum_generators_;
210   std::vector<const ExtensionGenerator*> extension_generators_;
211   int num_required_fields_;
212   int num_weak_fields_;
213 
214   std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
215   std::unique_ptr<ParseFunctionGenerator> parse_function_generator_;
216 
217   MessageSCCAnalyzer* scc_analyzer_;
218 
219   std::map<std::string, std::string> variables_;
220 
221   friend class FileGenerator;
222   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
223 };
224 
225 }  // namespace cpp
226 }  // namespace compiler
227 }  // namespace protobuf
228 }  // namespace google
229 
230 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
231