• 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 <memory>
39 #include <set>
40 #include <string>
41 #include <google/protobuf/compiler/cpp/cpp_field.h>
42 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
43 #include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h>
44 #include <google/protobuf/compiler/cpp/cpp_options.h>
45 
46 namespace google {
47 namespace protobuf {
48 namespace io {
49 class Printer;  // printer.h
50 }
51 }  // namespace protobuf
52 }  // namespace google
53 
54 namespace google {
55 namespace protobuf {
56 namespace compiler {
57 namespace cpp {
58 
59 class EnumGenerator;       // enum.h
60 class ExtensionGenerator;  // extension.h
61 
62 class MessageGenerator {
63  public:
64   // See generator.cc for the meaning of dllexport_decl.
65   MessageGenerator(const Descriptor* descriptor,
66                    const std::map<std::string, std::string>& vars,
67                    int index_in_file_messages, const Options& options,
68                    MessageSCCAnalyzer* scc_analyzer);
69   ~MessageGenerator();
70 
71   // Append the two types of nested generators to the corresponding vector.
72   void AddGenerators(
73       std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
74       std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
75 
76   // Generate definitions for this class and all its nested types.
77   void GenerateClassDefinition(io::Printer* printer);
78 
79   // Generate definitions of inline methods (placed at the end of the header
80   // file).
81   void GenerateInlineMethods(io::Printer* printer);
82 
83   // Source file stuff.
84 
85   // Generate extra fields
86   void GenerateExtraDefaultFields(io::Printer* printer);
87 
88   // Generates code that creates default instances for fields.
89   void GenerateFieldDefaultInstances(io::Printer* printer);
90 
91   // Generates code that initializes the message's default instance.  This
92   // is separate from allocating because all default instances must be
93   // allocated before any can be initialized.
94   void GenerateDefaultInstanceInitializer(io::Printer* printer);
95 
96   // Generate all non-inline methods for this class.
97   void GenerateClassMethods(io::Printer* printer);
98 
99   // Generate source file code that should go outside any namespace.
100   void GenerateSourceInProto2Namespace(io::Printer* printer);
101 
102  private:
103   // Generate declarations and definitions of accessors for fields.
104   void GenerateFieldAccessorDeclarations(io::Printer* printer);
105   void GenerateFieldAccessorDefinitions(io::Printer* printer);
106 
107   // Generate the table-driven parsing array.  Returns the number of entries
108   // generated.
109   size_t GenerateParseOffsets(io::Printer* printer);
110   size_t GenerateParseAuxTable(io::Printer* printer);
111   // Generates a ParseTable entry.  Returns whether the proto uses
112   // table-driven parsing.
113   bool GenerateParseTable(io::Printer* printer, size_t offset,
114                           size_t aux_offset);
115 
116   // Generate the field offsets array.  Returns the a pair of the total numer
117   // of entries generated and the index of the first has_bit entry.
118   std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
119   void GenerateSchema(io::Printer* printer, int offset, int has_offset);
120   // For each field generates a table entry describing the field for the
121   // table driven serializer.
122   int GenerateFieldMetadata(io::Printer* printer);
123 
124   // Generate constructors and destructor.
125   void GenerateStructors(io::Printer* printer);
126 
127   // The compiler typically generates multiple copies of each constructor and
128   // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
129   // Placing common code in a separate method reduces the generated code size.
130   //
131   // Generate the shared constructor code.
132   void GenerateSharedConstructorCode(io::Printer* printer);
133   // Generate the shared destructor code.
134   void GenerateSharedDestructorCode(io::Printer* printer);
135   // Generate the arena-specific destructor code.
136   void GenerateArenaDestructorCode(io::Printer* printer);
137 
138   // Generate standard Message methods.
139   void GenerateClear(io::Printer* printer);
140   void GenerateOneofClear(io::Printer* printer);
141   void GenerateMergeFromCodedStream(io::Printer* printer);
142   void GenerateSerializeWithCachedSizes(io::Printer* printer);
143   void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
144   void GenerateSerializeWithCachedSizesBody(io::Printer* printer);
145   void GenerateByteSize(io::Printer* printer);
146   void GenerateMergeFrom(io::Printer* printer);
147   void GenerateClassSpecificMergeFrom(io::Printer* printer);
148   void GenerateCopyFrom(io::Printer* printer);
149   void GenerateSwap(io::Printer* printer);
150   void GenerateIsInitialized(io::Printer* printer);
151 
152   // Helpers for GenerateSerializeWithCachedSizes().
153   //
154   // cached_has_bit_index maintains that:
155   //   cached_has_bits = _has_bits_[cached_has_bit_index]
156   // for cached_has_bit_index >= 0
157   void GenerateSerializeOneField(io::Printer* printer,
158                                  const FieldDescriptor* field,
159                                  int cached_has_bits_index);
160   // Generate a switch statement to serialize 2+ fields from the same oneof.
161   // Or, if fields.size() == 1, just call GenerateSerializeOneField().
162   void GenerateSerializeOneofFields(
163       io::Printer* printer, const std::vector<const FieldDescriptor*>& fields);
164   void GenerateSerializeOneExtensionRange(
165       io::Printer* printer, const Descriptor::ExtensionRange* range);
166 
167   // Generates has_foo() functions and variables for singular field has-bits.
168   void GenerateSingularFieldHasBits(const FieldDescriptor* field,
169                                     Formatter format);
170   // Generates has_foo() functions and variables for oneof field has-bits.
171   void GenerateOneofHasBits(io::Printer* printer);
172   // Generates has_foo_bar() functions for oneof members.
173   void GenerateOneofMemberHasBits(const FieldDescriptor* field,
174                                   const Formatter& format);
175   // Generates the clear_foo() method for a field.
176   void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
177                           Formatter format);
178 
179   void GenerateConstructorBody(io::Printer* printer,
180                                std::vector<bool> already_processed,
181                                bool copy_constructor) const;
182 
183   size_t HasBitsSize() const;
184   int HasBitIndex(const FieldDescriptor* a) const;
185   int HasByteIndex(const FieldDescriptor* a) const;
186   int HasWordIndex(const FieldDescriptor* a) const;
187   bool SameHasByte(const FieldDescriptor* a, const FieldDescriptor* b) const;
188   std::vector<uint32> RequiredFieldsBitMask() const;
189 
190   const Descriptor* descriptor_;
191   int index_in_file_messages_;
192   std::string classname_;
193   Options options_;
194   FieldGeneratorMap field_generators_;
195   // optimized_order_ is the order we layout the message's fields in the
196   // class. This is reused to initialize the fields in-order for cache
197   // efficiency.
198   //
199   // optimized_order_ excludes oneof fields and weak fields.
200   std::vector<const FieldDescriptor*> optimized_order_;
201   std::vector<int> has_bit_indices_;
202   int max_has_bit_index_;
203   std::vector<const EnumGenerator*> enum_generators_;
204   std::vector<const ExtensionGenerator*> extension_generators_;
205   int num_required_fields_;
206   int num_weak_fields_;
207   // table_driven_ indicates the generated message uses table-driven parsing.
208   bool table_driven_;
209 
210   std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
211 
212   MessageSCCAnalyzer* scc_analyzer_;
213 
214   std::map<std::string, std::string> variables_;
215 
216   friend class FileGenerator;
217   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
218 };
219 
220 }  // namespace cpp
221 }  // namespace compiler
222 }  // namespace protobuf
223 }  // namespace google
224 
225 #endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
226