My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes  
Changes to /trunk/src/google/protobuf/compiler/cpp/cpp_message.cc
r414 vs. r425 Compare: vs.  Format:
Revision r425
Go to: 
Project members, sign in to write a code review
/trunk/src/google/protobuf/compiler/cpp/cpp_message.cc   r414 /trunk/src/google/protobuf/compiler/cpp/cpp_message.cc   r425
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/ 3 // http://code.google.com/p/protobuf/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above 11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer 12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the 13 // in the documentation and/or other materials provided with the
14 // distribution. 14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its 15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from 16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission. 17 // this software without specific prior written permission.
18 // 18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 // Author: kenton@google.com (Kenton Varda) 31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by 32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others. 33 // Sanjay Ghemawat, Jeff Dean, and others.
34 34
35 #include <algorithm> 35 #include <algorithm>
36 #include <google/protobuf/stubs/hash.h> 36 #include <google/protobuf/stubs/hash.h>
37 #include <map> 37 #include <map>
38 #include <utility> 38 #include <utility>
39 #include <vector> 39 #include <vector>
40 #include <google/protobuf/compiler/cpp/cpp_message.h> 40 #include <google/protobuf/compiler/cpp/cpp_message.h>
41 #include <google/protobuf/compiler/cpp/cpp_field.h> 41 #include <google/protobuf/compiler/cpp/cpp_field.h>
42 #include <google/protobuf/compiler/cpp/cpp_enum.h> 42 #include <google/protobuf/compiler/cpp/cpp_enum.h>
43 #include <google/protobuf/compiler/cpp/cpp_extension.h> 43 #include <google/protobuf/compiler/cpp/cpp_extension.h>
44 #include <google/protobuf/compiler/cpp/cpp_helpers.h> 44 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
45 #include <google/protobuf/stubs/strutil.h> 45 #include <google/protobuf/stubs/strutil.h>
46 #include <google/protobuf/io/printer.h> 46 #include <google/protobuf/io/printer.h>
47 #include <google/protobuf/io/coded_stream.h> 47 #include <google/protobuf/io/coded_stream.h>
48 #include <google/protobuf/wire_format.h> 48 #include <google/protobuf/wire_format.h>
49 #include <google/protobuf/descriptor.pb.h> 49 #include <google/protobuf/descriptor.pb.h>
50 50
51
51 namespace google { 52 namespace google {
52 namespace protobuf { 53 namespace protobuf {
53 namespace compiler { 54 namespace compiler {
54 namespace cpp { 55 namespace cpp {
55 56
56 using internal::WireFormat; 57 using internal::WireFormat;
57 using internal::WireFormatLite; 58 using internal::WireFormatLite;
58 59
59 namespace { 60 namespace {
60 61
61 void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { 62 void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
62 // Print the field's proto-syntax definition as a comment. We don't want to 63 // Print the field's proto-syntax definition as a comment. We don't want to
63 // print group bodies so we cut off after the first line. 64 // print group bodies so we cut off after the first line.
64 string def = field->DebugString(); 65 string def = field->DebugString();
65 printer->Print("// $def$\n", 66 printer->Print("// $def$\n",
66 "def", def.substr(0, def.find_first_of('\n'))); 67 "def", def.substr(0, def.find_first_of('\n')));
67 } 68 }
68 69
69 struct FieldOrderingByNumber { 70 struct FieldOrderingByNumber {
70 inline bool operator()(const FieldDescriptor* a, 71 inline bool operator()(const FieldDescriptor* a,
71 const FieldDescriptor* b) const { 72 const FieldDescriptor* b) const {
72 return a->number() < b->number(); 73 return a->number() < b->number();
73 } 74 }
74 }; 75 };
75 76
76 const char* kWireTypeNames[] = { 77 const char* kWireTypeNames[] = {
77 "VARINT", 78 "VARINT",
78 "FIXED64", 79 "FIXED64",
79 "LENGTH_DELIMITED", 80 "LENGTH_DELIMITED",
80 "START_GROUP", 81 "START_GROUP",
81 "END_GROUP", 82 "END_GROUP",
82 "FIXED32", 83 "FIXED32",
83 }; 84 };
84 85
85 // Sort the fields of the given Descriptor by number into a new[]'d array 86 // Sort the fields of the given Descriptor by number into a new[]'d array
86 // and return it. 87 // and return it.
87 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 88 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
88 const FieldDescriptor** fields = 89 const FieldDescriptor** fields =
89 new const FieldDescriptor*[descriptor->field_count()]; 90 new const FieldDescriptor*[descriptor->field_count()];
90 for (int i = 0; i < descriptor->field_count(); i++) { 91 for (int i = 0; i < descriptor->field_count(); i++) {
91 fields[i] = descriptor->field(i); 92 fields[i] = descriptor->field(i);
92 } 93 }
93 sort(fields, fields + descriptor->field_count(), 94 sort(fields, fields + descriptor->field_count(),
94 FieldOrderingByNumber()); 95 FieldOrderingByNumber());
95 return fields; 96 return fields;
96 } 97 }
97 98
98 // Functor for sorting extension ranges by their "start" field number. 99 // Functor for sorting extension ranges by their "start" field number.
99 struct ExtensionRangeSorter { 100 struct ExtensionRangeSorter {
100 bool operator()(const Descriptor::ExtensionRange* left, 101 bool operator()(const Descriptor::ExtensionRange* left,
101 const Descriptor::ExtensionRange* right) const { 102 const Descriptor::ExtensionRange* right) const {
102 return left->start < right->start; 103 return left->start < right->start;
103 } 104 }
104 }; 105 };
106
107 // Returns true if the "required" restriction check should be ignored for the
108 // given field.
109 inline static bool ShouldIgnoreRequiredFieldCheck(
110 const FieldDescriptor* field) {
111 return false;
112 }
105 113
106 // Returns true if the message type has any required fields. If it doesn't, 114 // Returns true if the message type has any required fields. If it doesn't,
107 // we can optimize out calls to its IsInitialized() method. 115 // we can optimize out calls to its IsInitialized() method.
108 // 116 //
109 // already_seen is used to avoid checking the same type multiple times 117 // already_seen is used to avoid checking the same type multiple times
110 // (and also to protect against recursion). 118 // (and also to protect against recursion).
111 static bool HasRequiredFields( 119 static bool HasRequiredFields(
112 const Descriptor* type, 120 const Descriptor* type,
113 hash_set<const Descriptor*>* already_seen) { 121 hash_set<const Descriptor*>* already_seen) {
114 if (already_seen->count(type) > 0) { 122 if (already_seen->count(type) > 0) {
115 // Since the first occurrence of a required field causes the whole 123 // Since the first occurrence of a required field causes the whole
116 // function to return true, we can assume that if the type is already 124 // function to return true, we can assume that if the type is already
117 // in the cache it didn't have any required fields. 125 // in the cache it didn't have any required fields.
118 return false; 126 return false;
119 } 127 }
120 already_seen->insert(type); 128 already_seen->insert(type);
121 129
122 // If the type has extensions, an extension with message type could contain 130 // If the type has extensions, an extension with message type could contain
123 // required fields, so we have to be conservative and assume such an 131 // required fields, so we have to be conservative and assume such an
124 // extension exists. 132 // extension exists.
125 if (type->extension_range_count() > 0) return true; 133 if (type->extension_range_count() > 0) return true;
126 134
127 for (int i = 0; i < type->field_count(); i++) { 135 for (int i = 0; i < type->field_count(); i++) {
128 const FieldDescriptor* field = type->field(i); 136 const FieldDescriptor* field = type->field(i);
129 if (field->is_required()) { 137 if (field->is_required()) {
130 return true; 138 return true;
131 } 139 }
132 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 140 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
141 !ShouldIgnoreRequiredFieldCheck(field)) {
133 if (HasRequiredFields(field->message_type(), already_seen)) { 142 if (HasRequiredFields(field->message_type(), already_seen)) {
134 return true; 143 return true;
135 } 144 }
136 } 145 }
137 } 146 }
138 147
139 return false; 148 return false;
140 } 149 }
141 150
142 static bool HasRequiredFields(const Descriptor* type) { 151 static bool HasRequiredFields(const Descriptor* type) {
143 hash_set<const Descriptor*> already_seen; 152 hash_set<const Descriptor*> already_seen;
144 return HasRequiredFields(type, &already_seen); 153 return HasRequiredFields(type, &already_seen);
145 } 154 }
146 155
147 // This returns an estimate of the compiler's alignment for the field. This 156 // This returns an estimate of the compiler's alignment for the field. This
148 // can't guarantee to be correct because the generated code could be compiled on 157 // can't guarantee to be correct because the generated code could be compiled on
149 // different systems with different alignment rules. The estimates below assume 158 // different systems with different alignment rules. The estimates below assume
150 // 64-bit pointers. 159 // 64-bit pointers.
151 int EstimateAlignmentSize(const FieldDescriptor* field) { 160 int EstimateAlignmentSize(const FieldDescriptor* field) {
152 if (field == NULL) return 0; 161 if (field == NULL) return 0;
153 if (field->is_repeated()) return 8; 162 if (field->is_repeated()) return 8;
154 switch (field->cpp_type()) { 163 switch (field->cpp_type()) {
155 case FieldDescriptor::CPPTYPE_BOOL: 164 case FieldDescriptor::CPPTYPE_BOOL:
156 return 1; 165 return 1;
157 166
158 case FieldDescriptor::CPPTYPE_INT32: 167 case FieldDescriptor::CPPTYPE_INT32:
159 case FieldDescriptor::CPPTYPE_UINT32: 168 case FieldDescriptor::CPPTYPE_UINT32:
160 case FieldDescriptor::CPPTYPE_ENUM: 169 case FieldDescriptor::CPPTYPE_ENUM:
161 case FieldDescriptor::CPPTYPE_FLOAT: 170 case FieldDescriptor::CPPTYPE_FLOAT:
162 return 4; 171 return 4;
163 172
164 case FieldDescriptor::CPPTYPE_INT64: 173 case FieldDescriptor::CPPTYPE_INT64:
165 case FieldDescriptor::CPPTYPE_UINT64: 174 case FieldDescriptor::CPPTYPE_UINT64:
166 case FieldDescriptor::CPPTYPE_DOUBLE: 175 case FieldDescriptor::CPPTYPE_DOUBLE:
167 case FieldDescriptor::CPPTYPE_STRING: 176 case FieldDescriptor::CPPTYPE_STRING:
168 case FieldDescriptor::CPPTYPE_MESSAGE: 177 case FieldDescriptor::CPPTYPE_MESSAGE:
169 return 8; 178 return 8;
170 } 179 }
171 GOOGLE_LOG(FATAL) << "Can't get here."; 180 GOOGLE_LOG(FATAL) << "Can't get here.";
172 return -1; // Make compiler happy. 181 return -1; // Make compiler happy.
173 } 182 }
174 183
175 // FieldGroup is just a helper for OptimizePadding below. It holds a vector of 184 // FieldGroup is just a helper for OptimizePadding below. It holds a vector of
176 // fields that are grouped together because they have compatible alignment, and 185 // fields that are grouped together because they have compatible alignment, and
177 // a preferred location in the final field ordering. 186 // a preferred location in the final field ordering.
178 class FieldGroup { 187 class FieldGroup {
179 public: 188 public:
180 FieldGroup() 189 FieldGroup()
181 : preferred_location_(0) {} 190 : preferred_location_(0) {}
182 191
183 // A group with a single field. 192 // A group with a single field.
184 FieldGroup(float preferred_location, const FieldDescriptor* field) 193 FieldGroup(float preferred_location, const FieldDescriptor* field)
185 : preferred_location_(preferred_location), 194 : preferred_location_(preferred_location),
186 fields_(1, field) {} 195 fields_(1, field) {}
187 196
188 // Append the fields in 'other' to this group. 197 // Append the fields in 'other' to this group.
189 void Append(const FieldGroup& other) { 198 void Append(const FieldGroup& other) {
190 if (other.fields_.empty()) { 199 if (other.fields_.empty()) {
191 return; 200 return;
192 } 201 }
193 // Preferred location is the average among all the fields, so we weight by 202 // Preferred location is the average among all the fields, so we weight by
194 // the number of fields on each FieldGroup object. 203 // the number of fields on each FieldGroup object.
195 preferred_location_ = 204 preferred_location_ =
196 (preferred_location_ * fields_.size() + 205 (preferred_location_ * fields_.size() +
197 (other.preferred_location_ * other.fields_.size())) / 206 (other.preferred_location_ * other.fields_.size())) /
198 (fields_.size() + other.fields_.size()); 207 (fields_.size() + other.fields_.size());
199 fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); 208 fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
200 } 209 }
201 210
202 void SetPreferredLocation(float location) { preferred_location_ = location; } 211 void SetPreferredLocation(float location) { preferred_location_ = location; }
203 const vector<const FieldDescriptor*>& fields() const { return fields_; } 212 const vector<const FieldDescriptor*>& fields() const { return fields_; }
204 213
205 // FieldGroup objects sort by their preferred location. 214 // FieldGroup objects sort by their preferred location.
206 bool operator<(const FieldGroup& other) const { 215 bool operator<(const FieldGroup& other) const {
207 return preferred_location_ < other.preferred_location_; 216 return preferred_location_ < other.preferred_location_;
208 } 217 }
209 218
210 private: 219 private:
211 // "preferred_location_" is an estimate of where this group should go in the 220 // "preferred_location_" is an estimate of where this group should go in the
212 // final list of fields. We compute this by taking the average index of each 221 // final list of fields. We compute this by taking the average index of each
213 // field in this group in the original ordering of fields. This is very 222 // field in this group in the original ordering of fields. This is very
214 // approximate, but should put this group close to where its member fields 223 // approximate, but should put this group close to where its member fields
215 // originally went. 224 // originally went.
216 float preferred_location_; 225 float preferred_location_;
217 vector<const FieldDescriptor*> fields_; 226 vector<const FieldDescriptor*> fields_;
218 // We rely on the default copy constructor and operator= so this type can be 227 // We rely on the default copy constructor and operator= so this type can be
219 // used in a vector. 228 // used in a vector.
220 }; 229 };
221 230
222 // Reorder 'fields' so that if the fields are output into a c++ class in the new 231 // Reorder 'fields' so that if the fields are output into a c++ class in the new
223 // order, the alignment padding is minimized. We try to do this while keeping 232 // order, the alignment padding is minimized. We try to do this while keeping
224 // each field as close as possible to its original position so that we don't 233 // each field as close as possible to its original position so that we don't
225 // reduce cache locality much for function that access each field in order. 234 // reduce cache locality much for function that access each field in order.
226 void OptimizePadding(vector<const FieldDescriptor*>* fields) { 235 void OptimizePadding(vector<const FieldDescriptor*>* fields) {
227 // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. 236 // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
228 vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8; 237 vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
229 for (int i = 0; i < fields->size(); ++i) { 238 for (int i = 0; i < fields->size(); ++i) {
230 switch (EstimateAlignmentSize((*fields)[i])) { 239 switch (EstimateAlignmentSize((*fields)[i])) {
231 case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; 240 case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
232 case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; 241 case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
233 case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; 242 case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
234 default: 243 default:
235 GOOGLE_LOG(FATAL) << "Unknown alignment size."; 244 GOOGLE_LOG(FATAL) << "Unknown alignment size.";
236 } 245 }
237 } 246 }
238 247
239 // Now group fields aligned to 1 byte into sets of 4, and treat those like a 248 // Now group fields aligned to 1 byte into sets of 4, and treat those like a
240 // single field aligned to 4 bytes. 249 // single field aligned to 4 bytes.
241 for (int i = 0; i < aligned_to_1.size(); i += 4) { 250 for (int i = 0; i < aligned_to_1.size(); i += 4) {
242 FieldGroup field_group; 251 FieldGroup field_group;
243 for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { 252 for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
244 field_group.Append(aligned_to_1[j]); 253 field_group.Append(aligned_to_1[j]);
245 } 254 }
246 aligned_to_4.push_back(field_group); 255 aligned_to_4.push_back(field_group);
247 } 256 }
248 // Sort by preferred location to keep fields as close to their original 257 // Sort by preferred location to keep fields as close to their original
249 // location as possible. 258 // location as possible.
250 sort(aligned_to_4.begin(), aligned_to_4.end()); 259 sort(aligned_to_4.begin(), aligned_to_4.end());
251 260
252 // Now group fields aligned to 4 bytes (or the 4-field groups created above) 261 // Now group fields aligned to 4 bytes (or the 4-field groups created above)
253 // into pairs, and treat those like a single field aligned to 8 bytes. 262 // into pairs, and treat those like a single field aligned to 8 bytes.
254 for (int i = 0; i < aligned_to_4.size(); i += 2) { 263 for (int i = 0; i < aligned_to_4.size(); i += 2) {
255 FieldGroup field_group; 264 FieldGroup field_group;
256 for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) { 265 for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
257 field_group.Append(aligned_to_4[j]); 266 field_group.Append(aligned_to_4[j]);
258 } 267 }
259 if (i == aligned_to_4.size() - 1) { 268 if (i == aligned_to_4.size() - 1) {
260 // Move incomplete 4-byte block to the end. 269 // Move incomplete 4-byte block to the end.
261 field_group.SetPreferredLocation(fields->size() + 1); 270 field_group.SetPreferredLocation(fields->size() + 1);
262 } 271 }
263 aligned_to_8.push_back(field_group); 272 aligned_to_8.push_back(field_group);
264 } 273 }
265 // Sort by preferred location to keep fields as close to their original 274 // Sort by preferred location to keep fields as close to their original
266 // location as possible. 275 // location as possible.
267 sort(aligned_to_8.begin(), aligned_to_8.end()); 276 sort(aligned_to_8.begin(), aligned_to_8.end());
268 277
269 // Now pull out all the FieldDescriptors in order. 278 // Now pull out all the FieldDescriptors in order.
270 fields->clear(); 279 fields->clear();
271 for (int i = 0; i < aligned_to_8.size(); ++i) { 280 for (int i = 0; i < aligned_to_8.size(); ++i) {
272 fields->insert(fields->end(), 281 fields->insert(fields->end(),
273 aligned_to_8[i].fields().begin(), 282 aligned_to_8[i].fields().begin(),
274 aligned_to_8[i].fields().end()); 283 aligned_to_8[i].fields().end());
275 } 284 }
276 } 285 }
277 286
278 } 287 }
279 288
280 // =================================================================== 289 // ===================================================================
281 290
282 MessageGenerator::MessageGenerator(const Descriptor* descriptor, 291 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
283 const string& dllexport_decl) 292 const Options& options)
284 : descriptor_(descriptor), 293 : descriptor_(descriptor),
285 classname_(ClassName(descriptor, false)), 294 classname_(ClassName(descriptor, false)),
286 dllexport_decl_(dllexport_decl), 295 options_(options),
287 field_generators_(descriptor), 296 field_generators_(descriptor, options),
288 nested_generators_(new scoped_ptr<MessageGenerator>[ 297 nested_generators_(new scoped_ptr<MessageGenerator>[
289 descriptor->nested_type_count()]), 298 descriptor->nested_type_count()]),
290 enum_generators_(new scoped_ptr<EnumGenerator>[ 299 enum_generators_(new scoped_ptr<EnumGenerator>[
291 descriptor->enum_type_count()]), 300 descriptor->enum_type_count()]),
292 extension_generators_(new scoped_ptr<ExtensionGenerator>[ 301 extension_generators_(new scoped_ptr<ExtensionGenerator>[
293 descriptor->extension_count()]) { 302 descriptor->extension_count()]) {
294 303
295 for (int i = 0; i < descriptor->nested_type_count(); i++) { 304 for (int i = 0; i < descriptor->nested_type_count(); i++) {
296 nested_generators_[i].reset( 305 nested_generators_[i].reset(
297 new MessageGenerator(descriptor->nested_type(i), dllexport_decl)); 306 new MessageGenerator(descriptor->nested_type(i), options));
298 } 307 }
299 308
300 for (int i = 0; i < descriptor->enum_type_count(); i++) { 309 for (int i = 0; i < descriptor->enum_type_count(); i++) {
301 enum_generators_[i].reset( 310 enum_generators_[i].reset(
302 new EnumGenerator(descriptor->enum_type(i), dllexport_decl)); 311 new EnumGenerator(descriptor->enum_type(i), options));
303 } 312 }
304 313
305 for (int i = 0; i < descriptor->extension_count(); i++) { 314 for (int i = 0; i < descriptor->extension_count(); i++) {
306 extension_generators_[i].reset( 315 extension_generators_[i].reset(
307 new ExtensionGenerator(descriptor->extension(i), dllexport_decl)); 316 new ExtensionGenerator(descriptor->extension(i), options));
308 } 317 }
309 } 318 }
310 319
311 MessageGenerator::~MessageGenerator() {} 320 MessageGenerator::~MessageGenerator() {}
312 321
313 void MessageGenerator:: 322 void MessageGenerator::
314 GenerateForwardDeclaration(io::Printer* printer) { 323 GenerateForwardDeclaration(io::Printer* printer) {
315 printer->Print("class $classname$;\n", 324 printer->Print("class $classname$;\n",
316 "classname", classname_); 325 "classname", classname_);
317 326
318 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 327 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
319 nested_generators_[i]->GenerateForwardDeclaration(printer); 328 nested_generators_[i]->GenerateForwardDeclaration(printer);
320 } 329 }
321 } 330 }
322 331
323 void MessageGenerator:: 332 void MessageGenerator::
324 GenerateEnumDefinitions(io::Printer* printer) { 333 GenerateEnumDefinitions(io::Printer* printer) {
325 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 334 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
326 nested_generators_[i]->GenerateEnumDefinitions(printer); 335 nested_generators_[i]->GenerateEnumDefinitions(printer);
327 } 336 }
328 337
329 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 338 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
330 enum_generators_[i]->GenerateDefinition(printer); 339 enum_generators_[i]->GenerateDefinition(printer);
331 } 340 }
332 } 341 }
333 342
334 void MessageGenerator:: 343 void MessageGenerator::
335 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { 344 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
336 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 345 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
337 nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 346 nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
338 } 347 }
339 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 348 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
340 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 349 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
341 } 350 }
342 } 351 }
343 352
344 void MessageGenerator:: 353 void MessageGenerator::
345 GenerateFieldAccessorDeclarations(io::Printer* printer) { 354 GenerateFieldAccessorDeclarations(io::Printer* printer) {
346 for (int i = 0; i < descriptor_->field_count(); i++) { 355 for (int i = 0; i < descriptor_->field_count(); i++) {
347 const FieldDescriptor* field = descriptor_->field(i); 356 const FieldDescriptor* field = descriptor_->field(i);
348 357
349 PrintFieldComment(printer, field); 358 PrintFieldComment(printer, field);
350 359
351 map<string, string> vars; 360 map<string, string> vars;
352 SetCommonFieldVariables(field, &vars); 361 SetCommonFieldVariables(field, &vars, options_);
353 vars["constant_name"] = FieldConstantName(field); 362 vars["constant_name"] = FieldConstantName(field);
354 363
355 if (field->is_repeated()) { 364 if (field->is_repeated()) {
356 printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); 365 printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
357 } else { 366 } else {
358 printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); 367 printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
359 } 368 }
360 369
361 printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); 370 printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
362 printer->Print(vars, "static const int $constant_name$ = $number$;\n"); 371 printer->Print(vars, "static const int $constant_name$ = $number$;\n");
363 372
364 // Generate type-specific accessor declarations. 373 // Generate type-specific accessor declarations.
365 field_generators_.get(field).GenerateAccessorDeclarations(printer); 374 field_generators_.get(field).GenerateAccessorDeclarations(printer);
366 375
367 printer->Print("\n"); 376 printer->Print("\n");
368 } 377 }
369 378
370 if (descriptor_->extension_range_count() > 0) { 379 if (descriptor_->extension_range_count() > 0) {
371 // Generate accessors for extensions. We just call a macro located in 380 // Generate accessors for extensions. We just call a macro located in
372 // extension_set.h since the accessors about 80 lines of static code. 381 // extension_set.h since the accessors about 80 lines of static code.
373 printer->Print( 382 printer->Print(
374 "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n", 383 "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
375 "classname", classname_); 384 "classname", classname_);
376 } 385 }
377 } 386 }
378 387
379 void MessageGenerator:: 388 void MessageGenerator::
380 GenerateFieldAccessorDefinitions(io::Printer* printer) { 389 GenerateFieldAccessorDefinitions(io::Printer* printer) {
381 printer->Print("// $classname$\n\n", "classname", classname_); 390 printer->Print("// $classname$\n\n", "classname", classname_);
382 391
383 for (int i = 0; i < descriptor_->field_count(); i++) { 392 for (int i = 0; i < descriptor_->field_count(); i++) {
384 const FieldDescriptor* field = descriptor_->field(i); 393 const FieldDescriptor* field = descriptor_->field(i);
385 394
386 PrintFieldComment(printer, field); 395 PrintFieldComment(printer, field);
387 396
388 map<string, string> vars; 397 map<string, string> vars;
389 SetCommonFieldVariables(field, &vars); 398 SetCommonFieldVariables(field, &vars, options_);
390 399
391 // Generate has_$name$() or $name$_size(). 400 // Generate has_$name$() or $name$_size().
392 if (field->is_repeated()) { 401 if (field->is_repeated()) {
393 printer->Print(vars, 402 printer->Print(vars,
394 "inline int $classname$::$name$_size() const {\n" 403 "inline int $classname$::$name$_size() const {\n"
395 " return $name$_.size();\n" 404 " return $name$_.size();\n"
396 "}\n"); 405 "}\n");
397 } else { 406 } else {
398 // Singular field. 407 // Singular field.
399 char buffer[kFastToBufferSize]; 408 char buffer[kFastToBufferSize];
400 vars["has_array_index"] = SimpleItoa(field->index() / 32); 409 vars["has_array_index"] = SimpleItoa(field->index() / 32);
401 vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); 410 vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
402 printer->Print(vars, 411 printer->Print(vars,
403 "inline bool $classname$::has_$name$() const {\n" 412 "inline bool $classname$::has_$name$() const {\n"
404 " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" 413 " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
405 "}\n" 414 "}\n"
406 "inline void $classname$::set_has_$name$() {\n" 415 "inline void $classname$::set_has_$name$() {\n"
407 " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" 416 " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
408 "}\n" 417 "}\n"
409 "inline void $classname$::clear_has_$name$() {\n" 418 "inline void $classname$::clear_has_$name$() {\n"
410 " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" 419 " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
411 "}\n" 420 "}\n"
412 ); 421 );
413 } 422 }
414 423
415 // Generate clear_$name$() 424 // Generate clear_$name$()
416 printer->Print(vars, 425 printer->Print(vars,
417 "inline void $classname$::clear_$name$() {\n"); 426 "inline void $classname$::clear_$name$() {\n");
418 427
419 printer->Indent(); 428 printer->Indent();
420 field_generators_.get(field).GenerateClearingCode(printer); 429 field_generators_.get(field).GenerateClearingCode(printer);
421 printer->Outdent(); 430 printer->Outdent();
422 431
423 if (!field->is_repeated()) { 432 if (!field->is_repeated()) {
424 printer->Print(vars, 433 printer->Print(vars,
425 " clear_has_$name$();\n"); 434 " clear_has_$name$();\n");
426 } 435 }
427 436
428 printer->Print("}\n"); 437 printer->Print("}\n");
429 438
430 // Generate type-specific accessors. 439 // Generate type-specific accessors.
431 field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); 440 field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
432 441
433 printer->Print("\n"); 442 printer->Print("\n");
434 } 443 }
435 } 444 }
436 445
437 void MessageGenerator:: 446 void MessageGenerator::
438 GenerateClassDefinition(io::Printer* printer) { 447 GenerateClassDefinition(io::Printer* printer) {
439 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 448 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
440 nested_generators_[i]->GenerateClassDefinition(printer); 449 nested_generators_[i]->GenerateClassDefinition(printer);
441 printer->Print("\n"); 450 printer->Print("\n");
442 printer->Print(kThinSeparator); 451 printer->Print(kThinSeparator);
443 printer->Print("\n"); 452 printer->Print("\n");
444 } 453 }
445 454
446 map<string, string> vars; 455 map<string, string> vars;
447 vars["classname"] = classname_; 456 vars["classname"] = classname_;
448 vars["field_count"] = SimpleItoa(descriptor_->field_count()); 457 vars["field_count"] = SimpleItoa(descriptor_->field_count());
449 if (dllexport_decl_.empty()) { 458 if (options_.dllexport_decl.empty()) {
450 vars["dllexport"] = ""; 459 vars["dllexport"] = "";
451 } else { 460 } else {
452 vars["dllexport"] = dllexport_decl_ + " "; 461 vars["dllexport"] = options_.dllexport_decl + " ";
453 } 462 }
454 vars["superclass"] = SuperClassName(descriptor_); 463 vars["superclass"] = SuperClassName(descriptor_);
455 464
456 printer->Print(vars, 465 printer->Print(vars,
457 "class $dllexport$$classname$ : public $superclass$ {\n" 466 "class $dllexport$$classname$ : public $superclass$ {\n"
458 " public:\n"); 467 " public:\n");
459 printer->Indent(); 468 printer->Indent();
460 469
461 printer->Print(vars, 470 printer->Print(vars,
462 "$classname$();\n" 471 "$classname$();\n"
463 "virtual ~$classname$();\n" 472 "virtual ~$classname$();\n"
464 "\n" 473 "\n"
465 "$classname$(const $classname$& from);\n" 474 "$classname$(const $classname$& from);\n"
466 "\n" 475 "\n"
467 "inline $classname$& operator=(const $classname$& from) {\n" 476 "inline $classname$& operator=(const $classname$& from) {\n"
468 " CopyFrom(from);\n" 477 " CopyFrom(from);\n"
469 " return *this;\n" 478 " return *this;\n"
470 "}\n" 479 "}\n"
471 "\n"); 480 "\n");
472 481
473 if (HasUnknownFields(descriptor_->file())) { 482 if (HasUnknownFields(descriptor_->file())) {
474 printer->Print( 483 printer->Print(
475 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n" 484 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
476 " return _unknown_fields_;\n" 485 " return _unknown_fields_;\n"
477 "}\n" 486 "}\n"
478 "\n" 487 "\n"
479 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n" 488 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
480 " return &_unknown_fields_;\n" 489 " return &_unknown_fields_;\n"
481 "}\n" 490 "}\n"
482 "\n"); 491 "\n");
483 } 492 }
484 493
485 // Only generate this member if it's not disabled. 494 // Only generate this member if it's not disabled.
486 if (HasDescriptorMethods(descriptor_->file()) && 495 if (HasDescriptorMethods(descriptor_->file()) &&
487 !descriptor_->options().no_standard_descriptor_accessor()) { 496 !descriptor_->options().no_standard_descriptor_accessor()) {
488 printer->Print(vars, 497 printer->Print(vars,
489 "static const ::google::protobuf::Descriptor* descriptor();\n"); 498 "static const ::google::protobuf::Descriptor* descriptor();\n");
490 } 499 }
491 500
492 printer->Print(vars, 501 printer->Print(vars,
493 "static const $classname$& default_instance();\n" 502 "static const $classname$& default_instance();\n"
494 "\n"); 503 "\n");
495 504
496 if (!StaticInitializersForced(descriptor_->file())) { 505 if (!StaticInitializersForced(descriptor_->file())) {
497 printer->Print(vars, 506 printer->Print(vars,
498 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" 507 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
499 "// Returns the internal default instance pointer. This function can\n" 508 "// Returns the internal default instance pointer. This function can\n"
500 "// return NULL thus should not be used by the user. This is intended\n" 509 "// return NULL thus should not be used by the user. This is intended\n"
501 "// for Protobuf internal code. Please use default_instance() declared\n" 510 "// for Protobuf internal code. Please use default_instance() declared\n"
502 "// above instead.\n" 511 "// above instead.\n"
503 "static inline const $classname$* internal_default_instance() {\n" 512 "static inline const $classname$* internal_default_instance() {\n"
504 " return default_instance_;\n" 513 " return default_instance_;\n"
505 "}\n" 514 "}\n"
506 "#endif\n" 515 "#endif\n"
507 "\n"); 516 "\n");
508 } 517 }
518
509 519
510 printer->Print(vars, 520 printer->Print(vars,
511 "void Swap($classname$* other);\n" 521 "void Swap($classname$* other);\n"
512 "\n" 522 "\n"
513 "// implements Message ----------------------------------------------\n" 523 "// implements Message ----------------------------------------------\n"
514 "\n" 524 "\n"
515 "$classname$* New() const;\n"); 525 "$classname$* New() const;\n");
516 526
517 if (HasGeneratedMethods(descriptor_->file())) { 527 if (HasGeneratedMethods(descriptor_->file())) {
518 if (HasDescriptorMethods(descriptor_->file())) { 528 if (HasDescriptorMethods(descriptor_->file())) {
519 printer->Print(vars, 529 printer->Print(vars,
520 "void CopyFrom(const ::google::protobuf::Message& from);\n" 530 "void CopyFrom(const ::google::protobuf::Message& from);\n"
521 "void MergeFrom(const ::google::protobuf::Message& from);\n"); 531 "void MergeFrom(const ::google::protobuf::Message& from);\n");
522 } else { 532 } else {
523 printer->Print(vars, 533 printer->Print(vars,
524 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n"); 534 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
525 } 535 }
526 536
527 printer->Print(vars, 537 printer->Print(vars,
528 "void CopyFrom(const $classname$& from);\n" 538 "void CopyFrom(const $classname$& from);\n"
529 "void MergeFrom(const $classname$& from);\n" 539 "void MergeFrom(const $classname$& from);\n"
530 "void Clear();\n" 540 "void Clear();\n"
531 "bool IsInitialized() const;\n" 541 "bool IsInitialized() const;\n"
532 "\n" 542 "\n"
533 "int ByteSize() const;\n" 543 "int ByteSize() const;\n"
534 "bool MergePartialFromCodedStream(\n" 544 "bool MergePartialFromCodedStream(\n"
535 " ::google::protobuf::io::CodedInputStream* input);\n" 545 " ::google::protobuf::io::CodedInputStream* input);\n"
536 "void SerializeWithCachedSizes(\n" 546 "void SerializeWithCachedSizes(\n"
537 " ::google::protobuf::io::CodedOutputStream* output) const;\n"); 547 " ::google::protobuf::io::CodedOutputStream* output) const;\n");
538 if (HasFastArraySerialization(descriptor_->file())) { 548 if (HasFastArraySerialization(descriptor_->file())) {
539 printer->Print( 549 printer->Print(
540 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n"); 550 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
541 } 551 }
542 } 552 }
543 553
544 printer->Print(vars, 554 printer->Print(vars,
545 "int GetCachedSize() const { return _cached_size_; }\n" 555 "int GetCachedSize() const { return _cached_size_; }\n"
546 "private:\n" 556 "private:\n"
547 "void SharedCtor();\n" 557 "void SharedCtor();\n"
548 "void SharedDtor();\n" 558 "void SharedDtor();\n"
549 "void SetCachedSize(int size) const;\n" 559 "void SetCachedSize(int size) const;\n"
550 "public:\n" 560 "public:\n"
551 "\n"); 561 "\n");
552 562
553 if (HasDescriptorMethods(descriptor_->file())) { 563 if (HasDescriptorMethods(descriptor_->file())) {
554 printer->Print( 564 printer->Print(
555 "::google::protobuf::Metadata GetMetadata() const;\n" 565 "::google::protobuf::Metadata GetMetadata() const;\n"
556 "\n"); 566 "\n");
557 } else { 567 } else {
558 printer->Print( 568 printer->Print(
559 "::std::string GetTypeName() const;\n" 569 "::std::string GetTypeName() const;\n"
560 "\n"); 570 "\n");
561 } 571 }
562 572
563 printer->Print( 573 printer->Print(
564 "// nested types ----------------------------------------------------\n" 574 "// nested types ----------------------------------------------------\n"
565 "\n"); 575 "\n");
566 576
567 // Import all nested message classes into this class's scope with typedefs. 577 // Import all nested message classes into this class's scope with typedefs.
568 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 578 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
569 const Descriptor* nested_type = descriptor_->nested_type(i); 579 const Descriptor* nested_type = descriptor_->nested_type(i);
570 printer->Print("typedef $nested_full_name$ $nested_name$;\n", 580 printer->Print("typedef $nested_full_name$ $nested_name$;\n",
571 "nested_name", nested_type->name(), 581 "nested_name", nested_type->name(),
572 "nested_full_name", ClassName(nested_type, false)); 582 "nested_full_name", ClassName(nested_type, false));
573 } 583 }
574 584
575 if (descriptor_->nested_type_count() > 0) { 585 if (descriptor_->nested_type_count() > 0) {
576 printer->Print("\n"); 586 printer->Print("\n");
577 } 587 }
578 588
579 // Import all nested enums and their values into this class's scope with 589 // Import all nested enums and their values into this class's scope with
580 // typedefs and constants. 590 // typedefs and constants.
581 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 591 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
582 enum_generators_[i]->GenerateSymbolImports(printer); 592 enum_generators_[i]->GenerateSymbolImports(printer);
583 printer->Print("\n"); 593 printer->Print("\n");
584 } 594 }
585 595
586 printer->Print( 596 printer->Print(
587 "// accessors -------------------------------------------------------\n" 597 "// accessors -------------------------------------------------------\n"
588 "\n"); 598 "\n");
589 599
590 // Generate accessor methods for all fields. 600 // Generate accessor methods for all fields.
591 GenerateFieldAccessorDeclarations(printer); 601 GenerateFieldAccessorDeclarations(printer);
592 602
593 // Declare extension identifiers. 603 // Declare extension identifiers.
594 for (int i = 0; i < descriptor_->extension_count(); i++) { 604 for (int i = 0; i < descriptor_->extension_count(); i++) {
595 extension_generators_[i]->GenerateDeclaration(printer); 605 extension_generators_[i]->GenerateDeclaration(printer);
596 } 606 }
597 607
598 608
599 printer->Print( 609 printer->Print(
600 "// @@protoc_insertion_point(class_scope:$full_name$)\n", 610 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
601 "full_name", descriptor_->full_name()); 611 "full_name", descriptor_->full_name());
602 612
603 // Generate private members. 613 // Generate private members.
604 printer->Outdent(); 614 printer->Outdent();
605 printer->Print(" private:\n"); 615 printer->Print(" private:\n");
606 printer->Indent(); 616 printer->Indent();
607 617
618
608 for (int i = 0; i < descriptor_->field_count(); i++) { 619 for (int i = 0; i < descriptor_->field_count(); i++) {
609 if (!descriptor_->field(i)->is_repeated()) { 620 if (!descriptor_->field(i)->is_repeated()) {
610 printer->Print( 621 printer->Print(
611 "inline void set_has_$name$();\n", 622 "inline void set_has_$name$();\n",
612 "name", FieldName(descriptor_->field(i))); 623 "name", FieldName(descriptor_->field(i)));
613 printer->Print( 624 printer->Print(
614 "inline void clear_has_$name$();\n", 625 "inline void clear_has_$name$();\n",
615 "name", FieldName(descriptor_->field(i))); 626 "name", FieldName(descriptor_->field(i)));
616 } 627 }
617 } 628 }
618 printer->Print("\n"); 629 printer->Print("\n");
619 630
620 // To minimize padding, data members are divided into three sections: 631 // To minimize padding, data members are divided into three sections:
621 // (1) members assumed to align to 8 bytes 632 // (1) members assumed to align to 8 bytes
622 // (2) members corresponding to message fields, re-ordered to optimize 633 // (2) members corresponding to message fields, re-ordered to optimize
623 // alignment. 634 // alignment.
624 // (3) members assumed to align to 4 bytes. 635 // (3) members assumed to align to 4 bytes.
625 636
626 // Members assumed to align to 8 bytes: 637 // Members assumed to align to 8 bytes:
627 638
628 if (descriptor_->extension_range_count() > 0) { 639 if (descriptor_->extension_range_count() > 0) {
629 printer->Print( 640 printer->Print(
630 "::google::protobuf::internal::ExtensionSet _extensions_;\n" 641 "::google::protobuf::internal::ExtensionSet _extensions_;\n"
631 "\n"); 642 "\n");
632 } 643 }
633 644
634 if (HasUnknownFields(descriptor_->file())) { 645 if (HasUnknownFields(descriptor_->file())) {
635 printer->Print( 646 printer->Print(
636 "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" 647 "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
637 "\n"); 648 "\n");
638 } 649 }
639 650
640 // Field members: 651 // Field members:
641 652
642 vector<const FieldDescriptor*> fields; 653 vector<const FieldDescriptor*> fields;
643 for (int i = 0; i < descriptor_->field_count(); i++) { 654 for (int i = 0; i < descriptor_->field_count(); i++) {
644 fields.push_back(descriptor_->field(i)); 655 fields.push_back(descriptor_->field(i));
645 } 656 }
646 OptimizePadding(&fields); 657 OptimizePadding(&fields);
647 for (int i = 0; i < fields.size(); ++i) { 658 for (int i = 0; i < fields.size(); ++i) {
648 field_generators_.get(fields[i]).GeneratePrivateMembers(printer); 659 field_generators_.get(fields[i]).GeneratePrivateMembers(printer);
649 } 660 }
650 661
651 // Members assumed to align to 4 bytes: 662 // Members assumed to align to 4 bytes:
652 663
653 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. 664 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
654 printer->Print( 665 printer->Print(
655 "\n" 666 "\n"
656 "mutable int _cached_size_;\n"); 667 "mutable int _cached_size_;\n");
657 668
658 // Generate _has_bits_. 669 // Generate _has_bits_.
659 if (descriptor_->field_count() > 0) { 670 if (descriptor_->field_count() > 0) {
660 printer->Print(vars, 671 printer->Print(vars,
661 "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n" 672 "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"
662 "\n"); 673 "\n");
663 } else { 674 } else {
664 // Zero-size arrays aren't technically allowed, and MSVC in particular 675 // Zero-size arrays aren't technically allowed, and MSVC in particular
665 // doesn't like them. We still need to declare these arrays to make 676 // doesn't like them. We still need to declare these arrays to make
666 // other code compile. Since this is an uncommon case, we'll just declare 677 // other code compile. Since this is an uncommon case, we'll just declare
667 // them with size 1 and waste some space. Oh well. 678 // them with size 1 and waste some space. Oh well.
668 printer->Print( 679 printer->Print(
669 "::google::protobuf::uint32 _has_bits_[1];\n" 680 "::google::protobuf::uint32 _has_bits_[1];\n"
670 "\n"); 681 "\n");
671 } 682 }
672 683
673 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as 684 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
674 // friends so that they can access private static variables like 685 // friends so that they can access private static variables like
675 // default_instance_ and reflection_. 686 // default_instance_ and reflection_.
676 PrintHandlingOptionalStaticInitializers( 687 PrintHandlingOptionalStaticInitializers(
677 descriptor_->file(), printer, 688 descriptor_->file(), printer,
678 // With static initializers. 689 // With static initializers.
679 "friend void $dllexport_decl$ $adddescriptorsname$();\n", 690 "friend void $dllexport_decl$ $adddescriptorsname$();\n",
680 // Without. 691 // Without.
681 "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", 692 "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
682 // Vars. 693 // Vars.
683 "dllexport_decl", dllexport_decl_, 694 "dllexport_decl", options_.dllexport_decl,
684 "adddescriptorsname", 695 "adddescriptorsname",
685 GlobalAddDescriptorsName(descriptor_->file()->name())); 696 GlobalAddDescriptorsName(descriptor_->file()->name()));
686 697
687 printer->Print( 698 printer->Print(
688 "friend void $assigndescriptorsname$();\n" 699 "friend void $assigndescriptorsname$();\n"
689 "friend void $shutdownfilename$();\n" 700 "friend void $shutdownfilename$();\n"
690 "\n", 701 "\n",
691 "assigndescriptorsname", 702 "assigndescriptorsname",
692 GlobalAssignDescriptorsName(descriptor_->file()->name()), 703 GlobalAssignDescriptorsName(descriptor_->file()->name()),
693 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); 704 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
694 705
695 printer->Print( 706 printer->Print(
696 "void InitAsDefaultInstance();\n" 707 "void InitAsDefaultInstance();\n"
697 "static $classname$* default_instance_;\n", 708 "static $classname$* default_instance_;\n",
698 "classname", classname_); 709 "classname", classname_);
699 710
700 printer->Outdent(); 711 printer->Outdent();
701 printer->Print(vars, "};"); 712 printer->Print(vars, "};");
702 } 713 }
703 714
704 void MessageGenerator:: 715 void MessageGenerator::
705 GenerateInlineMethods(io::Printer* printer) { 716 GenerateInlineMethods(io::Printer* printer) {
706 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 717 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
707 nested_generators_[i]->GenerateInlineMethods(printer); 718 nested_generators_[i]->GenerateInlineMethods(printer);
708 printer->Print(kThinSeparator); 719 printer->Print(kThinSeparator);
709 printer->Print("\n"); 720 printer->Print("\n");
710 } 721 }
711 722
712 GenerateFieldAccessorDefinitions(printer); 723 GenerateFieldAccessorDefinitions(printer);
713 } 724 }
714 725
715 void MessageGenerator:: 726 void MessageGenerator::
716 GenerateDescriptorDeclarations(io::Printer* printer) { 727 GenerateDescriptorDeclarations(io::Printer* printer) {
717 printer->Print( 728 printer->Print(
718 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" 729 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
719 "const ::google::protobuf::internal::GeneratedMessageReflection*\n" 730 "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
720 " $name$_reflection_ = NULL;\n", 731 " $name$_reflection_ = NULL;\n",
721 "name", classname_); 732 "name", classname_);
722 733
723 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 734 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
724 nested_generators_[i]->GenerateDescriptorDeclarations(printer); 735 nested_generators_[i]->GenerateDescriptorDeclarations(printer);
725 } 736 }
726 737
727 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 738 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
728 printer->Print( 739 printer->Print(
729 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", 740 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
730 "name", ClassName(descriptor_->enum_type(i), false)); 741 "name", ClassName(descriptor_->enum_type(i), false));
731 } 742 }
732 } 743 }
733 744
734 void MessageGenerator:: 745 void MessageGenerator::
735 GenerateDescriptorInitializer(io::Printer* printer, int index) { 746 GenerateDescriptorInitializer(io::Printer* printer, int index) {
736 // TODO(kenton): Passing the index to this method is redundant; just use 747 // TODO(kenton): Passing the index to this method is redundant; just use
737 // descriptor_->index() instead. 748 // descriptor_->index() instead.
738 map<string, string> vars; 749 map<string, string> vars;
739 vars["classname"] = classname_; 750 vars["classname"] = classname_;
740 vars["index"] = SimpleItoa(index); 751 vars["index"] = SimpleItoa(index);
741 752
742 // Obtain the descriptor from the parent's descriptor. 753 // Obtain the descriptor from the parent's descriptor.
743 if (descriptor_->containing_type() == NULL) { 754 if (descriptor_->containing_type() == NULL) {
744 printer->Print(vars, 755 printer->Print(vars,
745 "$classname$_descriptor_ = file->message_type($index$);\n"); 756 "$classname$_descriptor_ = file->message_type($index$);\n");
746 } else { 757 } else {
747 vars["parent"] = ClassName(descriptor_->containing_type(), false); 758 vars["parent"] = ClassName(descriptor_->containing_type(), false);
748 printer->Print(vars, 759 printer->Print(vars,
749 "$classname$_descriptor_ = " 760 "$classname$_descriptor_ = "
750 "$parent$_descriptor_->nested_type($index$);\n"); 761 "$parent$_descriptor_->nested_type($index$);\n");
751 } 762 }
752 763
753 // Generate the offsets. 764 // Generate the offsets.
754 GenerateOffsets(printer); 765 GenerateOffsets(printer);
755 766
756 // Construct the reflection object. 767 // Construct the reflection object.
757 printer->Print(vars, 768 printer->Print(vars,
758 "$classname$_reflection_ =\n" 769 "$classname$_reflection_ =\n"
759 " new ::google::protobuf::internal::GeneratedMessageReflection(\n" 770 " new ::google::protobuf::internal::GeneratedMessageReflection(\n"
760 " $classname$_descriptor_,\n" 771 " $classname$_descriptor_,\n"
761 " $classname$::default_instance_,\n" 772 " $classname$::default_instance_,\n"
762 " $classname$_offsets_,\n" 773 " $classname$_offsets_,\n"
763 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n" 774 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
764 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 775 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
765 "$classname$, _unknown_fields_),\n"); 776 "$classname$, _unknown_fields_),\n");
766 if (descriptor_->extension_range_count() > 0) { 777 if (descriptor_->extension_range_count() > 0) {
767 printer->Print(vars, 778 printer->Print(vars,
768 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 779 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
769 "$classname$, _extensions_),\n"); 780 "$classname$, _extensions_),\n");
770 } else { 781 } else {
771 // No extensions. 782 // No extensions.
772 printer->Print(vars, 783 printer->Print(vars,
773 " -1,\n"); 784 " -1,\n");
774 } 785 }
786 printer->Print(
787 " ::google::protobuf::DescriptorPool::generated_pool(),\n");
788 printer->Print(vars,
789 " ::google::protobuf::MessageFactory::generated_factory(),\n");
775 printer->Print(vars, 790 printer->Print(vars,
776 " ::google::protobuf::DescriptorPool::generated_pool(),\n"
777 " ::google::protobuf::MessageFactory::generated_factory(),\n"
778 " sizeof($classname$));\n"); 791 " sizeof($classname$));\n");
779 792
780 // Handle nested types. 793 // Handle nested types.
781 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 794 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
782 nested_generators_[i]->GenerateDescriptorInitializer(printer, i); 795 nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
783 } 796 }
784 797
785 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 798 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
786 enum_generators_[i]->GenerateDescriptorInitializer(printer, i); 799 enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
787 } 800 }
788 } 801 }
789 802
790 void MessageGenerator:: 803 void MessageGenerator::
791 GenerateTypeRegistrations(io::Printer* printer) { 804 GenerateTypeRegistrations(io::Printer* printer) {
792 // Register this message type with the message factory. 805 // Register this message type with the message factory.
793 printer->Print( 806 printer->Print(
794 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" 807 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
795 " $classname$_descriptor_, &$classname$::default_instance());\n", 808 " $classname$_descriptor_, &$classname$::default_instance());\n",
796 "classname", classname_); 809 "classname", classname_);
797 810
798 // Handle nested types. 811 // Handle nested types.
799 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 812 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
800 nested_generators_[i]->GenerateTypeRegistrations(printer); 813 nested_generators_[i]->GenerateTypeRegistrations(printer);
801 } 814 }
802 } 815 }
803 816
804 void MessageGenerator:: 817 void MessageGenerator::
805 GenerateDefaultInstanceAllocator(io::Printer* printer) { 818 GenerateDefaultInstanceAllocator(io::Printer* printer) {
819 // Construct the default instances of all fields, as they will be used
820 // when creating the default instance of the entire message.
821 for (int i = 0; i < descriptor_->field_count(); i++) {
822 field_generators_.get(descriptor_->field(i))
823 .GenerateDefaultInstanceAllocator(printer);
824 }
825
806 // Construct the default instance. We can't call InitAsDefaultInstance() yet 826 // Construct the default instance. We can't call InitAsDefaultInstance() yet
807 // because we need to make sure all default instances that this one might 827 // because we need to make sure all default instances that this one might
808 // depend on are constructed first. 828 // depend on are constructed first.
809 printer->Print( 829 printer->Print(
810 "$classname$::default_instance_ = new $classname$();\n", 830 "$classname$::default_instance_ = new $classname$();\n",
811 "classname", classname_); 831 "classname", classname_);
812 832
813 // Handle nested types. 833 // Handle nested types.
814 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 834 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
815 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer); 835 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
816 } 836 }
817 837
818 } 838 }
819 839
820 void MessageGenerator:: 840 void MessageGenerator::
821 GenerateDefaultInstanceInitializer(io::Printer* printer) { 841 GenerateDefaultInstanceInitializer(io::Printer* printer) {
822 printer->Print( 842 printer->Print(
823 "$classname$::default_instance_->InitAsDefaultInstance();\n", 843 "$classname$::default_instance_->InitAsDefaultInstance();\n",
824 "classname", classname_); 844 "classname", classname_);
825 845
826 // Register extensions. 846 // Register extensions.
827 for (int i = 0; i < descriptor_->extension_count(); i++) { 847 for (int i = 0; i < descriptor_->extension_count(); i++) {
828 extension_generators_[i]->GenerateRegistration(printer); 848 extension_generators_[i]->GenerateRegistration(printer);
829 } 849 }
830 850
831 // Handle nested types. 851 // Handle nested types.
832 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 852 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
833 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer); 853 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
834 } 854 }
835 } 855 }
836 856
837 void MessageGenerator:: 857 void MessageGenerator::
838 GenerateShutdownCode(io::Printer* printer) { 858 GenerateShutdownCode(io::Printer* printer) {
839 printer->Print( 859 printer->Print(
840 "delete $classname$::default_instance_;\n", 860 "delete $classname$::default_instance_;\n",
841 "classname", classname_); 861 "classname", classname_);
842 862
843 if (HasDescriptorMethods(descriptor_->file())) { 863 if (HasDescriptorMethods(descriptor_->file())) {
844 printer->Print( 864 printer->Print(
845 "delete $classname$_reflection_;\n", 865 "delete $classname$_reflection_;\n",
846 "classname", classname_); 866 "classname", classname_);
847 } 867 }
868
869 // Handle default instances of fields.
870 for (int i = 0; i < descriptor_->field_count(); i++) {
871 field_generators_.get(descriptor_->field(i))
872 .GenerateShutdownCode(printer);
873 }
848 874
849 // Handle nested types. 875 // Handle nested types.
850 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 876 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
851 nested_generators_[i]->GenerateShutdownCode(printer); 877 nested_generators_[i]->GenerateShutdownCode(printer);
852 } 878 }
853 } 879 }
854 880
855 void MessageGenerator:: 881 void MessageGenerator::
856 GenerateClassMethods(io::Printer* printer) { 882 GenerateClassMethods(io::Printer* printer) {
857 for (int i = 0; i < descriptor_->enum_type_count(); i++) { 883 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
858 enum_generators_[i]->GenerateMethods(printer); 884 enum_generators_[i]->GenerateMethods(printer);
859 } 885 }
860 886
861 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 887 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
862 nested_generators_[i]->GenerateClassMethods(printer); 888 nested_generators_[i]->GenerateClassMethods(printer);
863 printer->Print("\n"); 889 printer->Print("\n");
864 printer->Print(kThinSeparator); 890 printer->Print(kThinSeparator);
865 printer->Print("\n"); 891 printer->Print("\n");
866 } 892 }
867 893
868 // Generate non-inline field definitions. 894 // Generate non-inline field definitions.
869 for (int i = 0; i < descriptor_->field_count(); i++) { 895 for (int i = 0; i < descriptor_->field_count(); i++) {
870 field_generators_.get(descriptor_->field(i)) 896 field_generators_.get(descriptor_->field(i))
871 .GenerateNonInlineAccessorDefinitions(printer); 897 .GenerateNonInlineAccessorDefinitions(printer);
872 } 898 }
873 899
874 // Generate field number constants. 900 // Generate field number constants.
875 printer->Print("#ifndef _MSC_VER\n"); 901 printer->Print("#ifndef _MSC_VER\n");
876 for (int i = 0; i < descriptor_->field_count(); i++) { 902 for (int i = 0; i < descriptor_->field_count(); i++) {
877 const FieldDescriptor *field = descriptor_->field(i); 903 const FieldDescriptor *field = descriptor_->field(i);
878 printer->Print( 904 printer->Print(
879 "const int $classname$::$constant_name$;\n", 905 "const int $classname$::$constant_name$;\n",
880 "classname", ClassName(FieldScope(field), false), 906 "classname", ClassName(FieldScope(field), false),
881 "constant_name", FieldConstantName(field)); 907 "constant_name", FieldConstantName(field));
882 } 908 }
883 printer->Print( 909 printer->Print(
884 "#endif // !_MSC_VER\n" 910 "#endif // !_MSC_VER\n"
885 "\n"); 911 "\n");
886 912
887 // Define extension identifiers. 913 // Define extension identifiers.
888 for (int i = 0; i < descriptor_->extension_count(); i++) { 914 for (int i = 0; i < descriptor_->extension_count(); i++) {
889 extension_generators_[i]->GenerateDefinition(printer); 915 extension_generators_[i]->GenerateDefinition(printer);
890 } 916 }
891 917
892 GenerateStructors(printer); 918 GenerateStructors(printer);
893 printer->Print("\n"); 919 printer->Print("\n");
894 920
895 if (HasGeneratedMethods(descriptor_->file())) { 921 if (HasGeneratedMethods(descriptor_->file())) {
896 GenerateClear(printer); 922 GenerateClear(printer);
897 printer->Print("\n"); 923 printer->Print("\n");
898 924
899 GenerateMergeFromCodedStream(printer); 925 GenerateMergeFromCodedStream(printer);
900 printer->Print("\n"); 926 printer->Print("\n");
901 927
902 GenerateSerializeWithCachedSizes(printer); 928 GenerateSerializeWithCachedSizes(printer);
903 printer->Print("\n"); 929 printer->Print("\n");
904 930
905 if (HasFastArraySerialization(descriptor_->file())) { 931 if (HasFastArraySerialization(descriptor_->file())) {
906 GenerateSerializeWithCachedSizesToArray(printer); 932 GenerateSerializeWithCachedSizesToArray(printer);
907 printer->Print("\n"); 933 printer->Print("\n");
908 } 934 }
909 935
910 GenerateByteSize(printer); 936 GenerateByteSize(printer);
911 printer->Print("\n"); 937 printer->Print("\n");
912 938
913 GenerateMergeFrom(printer); 939 GenerateMergeFrom(printer);
914 printer->Print("\n"); 940 printer->Print("\n");
915 941
916 GenerateCopyFrom(printer); 942 GenerateCopyFrom(printer);
917 printer->Print("\n"); 943 printer->Print("\n");
918 944
919 GenerateIsInitialized(printer); 945 GenerateIsInitialized(printer);
920 printer->Print("\n"); 946 printer->Print("\n");
921 } 947 }
922 948
923 GenerateSwap(printer); 949 GenerateSwap(printer);
924 printer->Print("\n"); 950 printer->Print("\n");
925 951
926 if (HasDescriptorMethods(descriptor_->file())) { 952 if (HasDescriptorMethods(descriptor_->file())) {
927 printer->Print( 953 printer->Print(
928 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" 954 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
929 " protobuf_AssignDescriptorsOnce();\n" 955 " protobuf_AssignDescriptorsOnce();\n"
930 " ::google::protobuf::Metadata metadata;\n" 956 " ::google::protobuf::Metadata metadata;\n"
931 " metadata.descriptor = $classname$_descriptor_;\n" 957 " metadata.descriptor = $classname$_descriptor_;\n"
932 " metadata.reflection = $classname$_reflection_;\n" 958 " metadata.reflection = $classname$_reflection_;\n"
933 " return metadata;\n" 959 " return metadata;\n"
934 "}\n" 960 "}\n"
935 "\n", 961 "\n",
936 "classname", classname_); 962 "classname", classname_);
937 } else { 963 } else {
938 printer->Print( 964 printer->Print(
939 "::std::string $classname$::GetTypeName() const {\n" 965 "::std::string $classname$::GetTypeName() const {\n"
940 " return \"$type_name$\";\n" 966 " return \"$type_name$\";\n"
941 "}\n" 967 "}\n"
942 "\n", 968 "\n",
943 "classname", classname_, 969 "classname", classname_,
944 "type_name", descriptor_->full_name()); 970 "type_name", descriptor_->full_name());
945 } 971 }
946 972
947 } 973 }
948 974
949 void MessageGenerator:: 975 void MessageGenerator::
950 GenerateOffsets(io::Printer* printer) { 976 GenerateOffsets(io::Printer* printer) {
951 printer->Print( 977 printer->Print(
952 "static const int $classname$_offsets_[$field_count$] = {\n", 978 "static const int $classname$_offsets_[$field_count$] = {\n",
953 "classname", classname_, 979 "classname", classname_,
954 "field_count", SimpleItoa(max(1, descriptor_->field_count()))); 980 "field_count", SimpleItoa(max(1, descriptor_->field_count())));
955 printer->Indent(); 981 printer->Indent();
956 982
957 for (int i = 0; i < descriptor_->field_count(); i++) { 983 for (int i = 0; i < descriptor_->field_count(); i++) {
958 const FieldDescriptor* field = descriptor_->field(i); 984 const FieldDescriptor* field = descriptor_->field(i);
959 printer->Print( 985 printer->Print(
960 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", 986 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
961 "classname", classname_, 987 "classname", classname_,
962 "name", FieldName(field)); 988 "name", FieldName(field));
963 } 989 }
964 990
965 printer->Outdent(); 991 printer->Outdent();
966 printer->Print("};\n"); 992 printer->Print("};\n");
967 } 993 }
968 994
969 void MessageGenerator:: 995 void MessageGenerator::
970 GenerateSharedConstructorCode(io::Printer* printer) { 996 GenerateSharedConstructorCode(io::Printer* printer) {
971 printer->Print( 997 printer->Print(
972 "void $classname$::SharedCtor() {\n", 998 "void $classname$::SharedCtor() {\n",
973 "classname", classname_); 999 "classname", classname_);
974 printer->Indent(); 1000 printer->Indent();
975 1001
976 printer->Print( 1002 printer->Print(
977 "_cached_size_ = 0;\n"); 1003 "_cached_size_ = 0;\n");
978 1004
979 for (int i = 0; i < descriptor_->field_count(); i++) { 1005 for (int i = 0; i < descriptor_->field_count(); i++) {
980 field_generators_.get(descriptor_->field(i)) 1006 field_generators_.get(descriptor_->field(i))
981 .GenerateConstructorCode(printer); 1007 .GenerateConstructorCode(printer);
982 } 1008 }
983 1009
984 printer->Print( 1010 printer->Print(
985 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 1011 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
986 1012
987 printer->Outdent(); 1013 printer->Outdent();
988 printer->Print("}\n\n"); 1014 printer->Print("}\n\n");
989 } 1015 }
990 1016
991 void MessageGenerator:: 1017 void MessageGenerator::
992 GenerateSharedDestructorCode(io::Printer* printer) { 1018 GenerateSharedDestructorCode(io::Printer* printer) {
993 printer->Print( 1019 printer->Print(
994 "void $classname$::SharedDtor() {\n", 1020 "void $classname$::SharedDtor() {\n",
995 "classname", classname_); 1021 "classname", classname_);
996 printer->Indent(); 1022 printer->Indent();
997 // Write the destructors for each field. 1023 // Write the destructors for each field.
998 for (int i = 0; i < descriptor_->field_count(); i++) { 1024 for (int i = 0; i < descriptor_->field_count(); i++) {
999 field_generators_.get(descriptor_->field(i)) 1025 field_generators_.get(descriptor_->field(i))
1000 .GenerateDestructorCode(printer); 1026 .GenerateDestructorCode(printer);
1001 } 1027 }
1002 1028
1003 PrintHandlingOptionalStaticInitializers( 1029 PrintHandlingOptionalStaticInitializers(
1004 descriptor_->file(), printer, 1030 descriptor_->file(), printer,
1005 // With static initializers. 1031 // With static initializers.
1006 "if (this != default_instance_) {\n", 1032 "if (this != default_instance_) {\n",
1007 // Without. 1033 // Without.
1008 "if (this != &default_instance()) {\n"); 1034 "if (this != &default_instance()) {\n");
1009 1035
1010 // We need to delete all embedded messages. 1036 // We need to delete all embedded messages.
1011 // TODO(kenton): If we make unset messages point at default instances 1037 // TODO(kenton): If we make unset messages point at default instances
1012 // instead of NULL, then it would make sense to move this code into 1038 // instead of NULL, then it would make sense to move this code into
1013 // MessageFieldGenerator::GenerateDestructorCode(). 1039 // MessageFieldGenerator::GenerateDestructorCode().
1014 for (int i = 0; i < descriptor_->field_count(); i++) { 1040 for (int i = 0; i < descriptor_->field_count(); i++) {
1015 const FieldDescriptor* field = descriptor_->field(i); 1041 const FieldDescriptor* field = descriptor_->field(i);
1016 1042
1017 if (!field->is_repeated() && 1043 if (!field->is_repeated() &&
1018 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1044 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1019 printer->Print(" delete $name$_;\n", 1045 printer->Print(" delete $name$_;\n",
1020 "name", FieldName(field)); 1046 "name", FieldName(field));
1021 } 1047 }
1022 } 1048 }
1023 1049
1024 printer->Outdent(); 1050 printer->Outdent();
1025 printer->Print( 1051 printer->Print(
1026 " }\n" 1052 " }\n"
1027 "}\n" 1053 "}\n"
1028 "\n"); 1054 "\n");
1029 } 1055 }
1030 1056
1031 void MessageGenerator:: 1057 void MessageGenerator::
1032 GenerateStructors(io::Printer* printer) { 1058 GenerateStructors(io::Printer* printer) {
1033 string superclass = SuperClassName(descriptor_); 1059 string superclass = SuperClassName(descriptor_);
1034 1060
1035 // Generate the default constructor. 1061 // Generate the default constructor.
1036 printer->Print( 1062 printer->Print(
1037 "$classname$::$classname$()\n" 1063 "$classname$::$classname$()\n"
1038 " : $superclass$() {\n" 1064 " : $superclass$() {\n"
1039 " SharedCtor();\n" 1065 " SharedCtor();\n"
1040 "}\n", 1066 "}\n",
1041 "classname", classname_, 1067 "classname", classname_,
1042 "superclass", superclass); 1068 "superclass", superclass);
1043 1069
1044 printer->Print( 1070 printer->Print(
1045 "\n" 1071 "\n"
1046 "void $classname$::InitAsDefaultInstance() {\n", 1072 "void $classname$::InitAsDefaultInstance() {\n",
1047 "classname", classname_); 1073 "classname", classname_);
1048 1074
1049 // The default instance needs all of its embedded message pointers 1075 // The default instance needs all of its embedded message pointers
1050 // cross-linked to other default instances. We can't do this initialization 1076 // cross-linked to other default instances. We can't do this initialization
1051 // in the constructor because some other default instances may not have been 1077 // in the constructor because some other default instances may not have been
1052 // constructed yet at that time. 1078 // constructed yet at that time.
1053 // TODO(kenton): Maybe all message fields (even for non-default messages) 1079 // TODO(kenton): Maybe all message fields (even for non-default messages)
1054 // should be initialized to point at default instances rather than NULL? 1080 // should be initialized to point at default instances rather than NULL?
1055 for (int i = 0; i < descriptor_->field_count(); i++) { 1081 for (int i = 0; i < descriptor_->field_count(); i++) {
1056 const FieldDescriptor* field = descriptor_->field(i); 1082 const FieldDescriptor* field = descriptor_->field(i);
1057 1083
1058 if (!field->is_repeated() && 1084 if (!field->is_repeated() &&
1059 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1085 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1060 PrintHandlingOptionalStaticInitializers( 1086 PrintHandlingOptionalStaticInitializers(
1061 descriptor_->file(), printer, 1087 descriptor_->file(), printer,
1062 // With static initializers. 1088 // With static initializers.
1063 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", 1089 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
1064 // Without. 1090 // Without.
1065 " $name$_ = const_cast< $type$*>(\n" 1091 " $name$_ = const_cast< $type$*>(\n"
1066 " $type$::internal_default_instance());\n", 1092 " $type$::internal_default_instance());\n",
1067 // Vars. 1093 // Vars.
1068 "name", FieldName(field), 1094 "name", FieldName(field),
1069 "type", FieldMessageTypeName(field)); 1095 "type", FieldMessageTypeName(field));
1070 } 1096 }
1071 } 1097 }
1072 printer->Print( 1098 printer->Print(
1073 "}\n" 1099 "}\n"
1074 "\n"); 1100 "\n");
1075 1101
1076 // Generate the copy constructor. 1102 // Generate the copy constructor.
1077 printer->Print( 1103 printer->Print(
1078 "$classname$::$classname$(const $classname$& from)\n" 1104 "$classname$::$classname$(const $classname$& from)\n"
1079 " : $superclass$() {\n" 1105 " : $superclass$() {\n"
1080 " SharedCtor();\n" 1106 " SharedCtor();\n"
1081 " MergeFrom(from);\n" 1107 " MergeFrom(from);\n"
1082 "}\n" 1108 "}\n"
1083 "\n", 1109 "\n",
1084 "classname", classname_, 1110 "classname", classname_,
1085 "superclass", superclass); 1111 "superclass", superclass);
1086 1112
1087 // Generate the shared constructor code. 1113 // Generate the shared constructor code.
1088 GenerateSharedConstructorCode(printer); 1114 GenerateSharedConstructorCode(printer);
1089 1115
1090 // Generate the destructor. 1116 // Generate the destructor.
1091 printer->Print( 1117 printer->Print(
1092 "$classname$::~$classname$() {\n" 1118 "$classname$::~$classname$() {\n"
1093 " SharedDtor();\n" 1119 " SharedDtor();\n"
1094 "}\n" 1120 "}\n"
1095 "\n", 1121 "\n",
1096 "classname", classname_); 1122 "classname", classname_);
1097 1123
1098 // Generate the shared destructor code. 1124 // Generate the shared destructor code.
1099 GenerateSharedDestructorCode(printer); 1125 GenerateSharedDestructorCode(printer);
1100 1126
1101 // Generate SetCachedSize. 1127 // Generate SetCachedSize.
1102 printer->Print( 1128 printer->Print(
1103 "void $classname$::SetCachedSize(int size) const {\n" 1129 "void $classname$::SetCachedSize(int size) const {\n"
1104 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 1130 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1105 " _cached_size_ = size;\n" 1131 " _cached_size_ = size;\n"
1106 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 1132 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1107 "}\n", 1133 "}\n",
1108 "classname", classname_); 1134 "classname", classname_);
1109 1135
1110 // Only generate this member if it's not disabled. 1136 // Only generate this member if it's not disabled.
1111 if (HasDescriptorMethods(descriptor_->file()) && 1137 if (HasDescriptorMethods(descriptor_->file()) &&
1112 !descriptor_->options().no_standard_descriptor_accessor()) { 1138 !descriptor_->options().no_standard_descriptor_accessor()) {
1113 printer->Print( 1139 printer->Print(
1114 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" 1140 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
1115 " protobuf_AssignDescriptorsOnce();\n" 1141 " protobuf_AssignDescriptorsOnce();\n"
1116 " return $classname$_descriptor_;\n" 1142 " return $classname$_descriptor_;\n"
1117 "}\n" 1143 "}\n"
1118 "\n", 1144 "\n",
1119 "classname", classname_, 1145 "classname", classname_,
1120 "adddescriptorsname", 1146 "adddescriptorsname",
1121 GlobalAddDescriptorsName(descriptor_->file()->name())); 1147 GlobalAddDescriptorsName(descriptor_->file()->name()));
1122 } 1148 }
1123 1149
1124 printer->Print( 1150 printer->Print(
1125 "const $classname$& $classname$::default_instance() {\n", 1151 "const $classname$& $classname$::default_instance() {\n",
1126 "classname", classname_); 1152 "classname", classname_);
1127 1153
1128 PrintHandlingOptionalStaticInitializers( 1154 PrintHandlingOptionalStaticInitializers(
1129 descriptor_->file(), printer, 1155 descriptor_->file(), printer,
1130 // With static initializers. 1156 // With static initializers.
1131 " if (default_instance_ == NULL) $adddescriptorsname$();\n", 1157 " if (default_instance_ == NULL) $adddescriptorsname$();\n",
1132 // Without. 1158 // Without.
1133 " $adddescriptorsname$();\n", 1159 " $adddescriptorsname$();\n",
1134 // Vars. 1160 // Vars.
1135 "adddescriptorsname", 1161 "adddescriptorsname",
1136 GlobalAddDescriptorsName(descriptor_->file()->name())); 1162 GlobalAddDescriptorsName(descriptor_->file()->name()));
1137 1163
1138 printer->Print( 1164 printer->Print(
1139 " return *default_instance_;\n" 1165 " return *default_instance_;\n"
1140 "}\n" 1166 "}\n"
1141 "\n" 1167 "\n"
1142 "$classname$* $classname$::default_instance_ = NULL;\n" 1168 "$classname$* $classname$::default_instance_ = NULL;\n"
1143 "\n" 1169 "\n"
1144 "$classname$* $classname$::New() const {\n" 1170 "$classname$* $classname$::New() const {\n"
1145 " return new $classname$;\n" 1171 " return new $classname$;\n"
1146 "}\n", 1172 "}\n",
1147 "classname", classname_, 1173 "classname", classname_,
1148 "adddescriptorsname", 1174 "adddescriptorsname",
1149 GlobalAddDescriptorsName(descriptor_->file()->name())); 1175 GlobalAddDescriptorsName(descriptor_->file()->name()));
1150 } 1176 }
1151 1177
1152 void MessageGenerator:: 1178 void MessageGenerator::
1153 GenerateClear(io::Printer* printer) { 1179 GenerateClear(io::Printer* printer) {
1154 printer->Print("void $classname$::Clear() {\n", 1180 printer->Print("void $classname$::Clear() {\n",
1155 "classname", classname_); 1181 "classname", classname_);
1156 printer->Indent(); 1182 printer->Indent();
1157 1183
1158 int last_index = -1; 1184 int last_index = -1;
1159 1185
1160 if (descriptor_->extension_range_count() > 0) { 1186 if (descriptor_->extension_range_count() > 0) {
1161 printer->Print("_extensions_.Clear();\n"); 1187 printer->Print("_extensions_.Clear();\n");
1162 } 1188 }
1163 1189
1164 for (int i = 0; i < descriptor_->field_count(); i++) { 1190 for (int i = 0; i < descriptor_->field_count(); i++) {
1165 const FieldDescriptor* field = descriptor_->field(i); 1191 const FieldDescriptor* field = descriptor_->field(i);
1166 1192
1167 if (!field->is_repeated()) { 1193 if (!field->is_repeated()) {
1168 // We can use the fact that _has_bits_ is a giant bitfield to our 1194 // We can use the fact that _has_bits_ is a giant bitfield to our
1169 // advantage: We can check up to 32 bits at a time for equality to 1195 // advantage: We can check up to 32 bits at a time for equality to
1170 // zero, and skip the whole range if so. This can improve the speed 1196 // zero, and skip the whole range if so. This can improve the speed
1171 // of Clear() for messages which contain a very large number of 1197 // of Clear() for messages which contain a very large number of
1172 // optional fields of which only a few are used at a time. Here, 1198 // optional fields of which only a few are used at a time. Here,
1173 // we've chosen to check 8 bits at a time rather than 32. 1199 // we've chosen to check 8 bits at a time rather than 32.
1174 if (i / 8 != last_index / 8 || last_index < 0) { 1200 if (i / 8 != last_index / 8 || last_index < 0) {
1175 if (last_index >= 0) { 1201 if (last_index >= 0) {
1176 printer->Outdent(); 1202 printer->Outdent();
1177 printer->Print("}\n"); 1203 printer->Print("}\n");
1178 } 1204 }
1179 printer->Print( 1205 printer->Print(
1180 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 1206 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1181 "index", SimpleItoa(field->index())); 1207 "index", SimpleItoa(field->index()));
1182 printer->Indent(); 1208 printer->Indent();
1183 } 1209 }
1184 last_index = i; 1210 last_index = i;
1185 1211
1186 // It's faster to just overwrite primitive types, but we should 1212 // It's faster to just overwrite primitive types, but we should
1187 // only clear strings and messages if they were set. 1213 // only clear strings and messages if they were set.
1188 // TODO(kenton): Let the CppFieldGenerator decide this somehow. 1214 // TODO(kenton): Let the CppFieldGenerator decide this somehow.
1189 bool should_check_bit = 1215 bool should_check_bit =
1190 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 1216 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1191 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; 1217 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
1192 1218
1193 if (should_check_bit) { 1219 if (should_check_bit) {
1194 printer->Print( 1220 printer->Print(
1195 "if (has_$name$()) {\n", 1221 "if (has_$name$()) {\n",
1196 "name", FieldName(field)); 1222 "name", FieldName(field));
1197 printer->Indent(); 1223 printer->Indent();
1198 } 1224 }
1199 1225
1200 field_generators_.get(field).GenerateClearingCode(printer); 1226 field_generators_.get(field).GenerateClearingCode(printer);
1201 1227
1202 if (should_check_bit) { 1228 if (should_check_bit) {
1203 printer->Outdent(); 1229 printer->Outdent();
1204 printer->Print("}\n"); 1230 printer->Print("}\n");
1205 } 1231 }
1206 } 1232 }
1207 } 1233 }
1208 1234
1209 if (last_index >= 0) { 1235 if (last_index >= 0) {
1210 printer->Outdent(); 1236 printer->Outdent();
1211 printer->Print("}\n"); 1237 printer->Print("}\n");
1212 } 1238 }
1213 1239
1214 // Repeated fields don't use _has_bits_ so we clear them in a separate 1240 // Repeated fields don't use _has_bits_ so we clear them in a separate
1215 // pass. 1241 // pass.
1216 for (int i = 0; i < descriptor_->field_count(); i++) { 1242 for (int i = 0; i < descriptor_->field_count(); i++) {
1217 const FieldDescriptor* field = descriptor_->field(i); 1243 const FieldDescriptor* field = descriptor_->field(i);
1218 1244
1219 if (field->is_repeated()) { 1245 if (field->is_repeated()) {
1220 field_generators_.get(field).GenerateClearingCode(printer); 1246 field_generators_.get(field).GenerateClearingCode(printer);
1221 } 1247 }
1222 } 1248 }
1223 1249
1224 printer->Print( 1250 printer->Print(
1225 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 1251 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1226 1252
1227 if (HasUnknownFields(descriptor_->file())) { 1253 if (HasUnknownFields(descriptor_->file())) {
1228 printer->Print( 1254 printer->Print(
1229 "mutable_unknown_fields()->Clear();\n"); 1255 "mutable_unknown_fields()->Clear();\n");
1230 } 1256 }
1231 1257
1232 printer->Outdent(); 1258 printer->Outdent();
1233 printer->Print("}\n"); 1259 printer->Print("}\n");
1234 } 1260 }
1235 1261
1236 void MessageGenerator:: 1262 void MessageGenerator::
1237 GenerateSwap(io::Printer* printer) { 1263 GenerateSwap(io::Printer* printer) {
1238 // Generate the Swap member function. 1264 // Generate the Swap member function.
1239 printer->Print("void $classname$::Swap($classname$* other) {\n", 1265 printer->Print("void $classname$::Swap($classname$* other) {\n",
1240 "classname", classname_); 1266 "classname", classname_);
1241 printer->Indent(); 1267 printer->Indent();
1242 printer->Print("if (other != this) {\n"); 1268 printer->Print("if (other != this) {\n");
1243 printer->Indent(); 1269 printer->Indent();
1244 1270
1245 if (HasGeneratedMethods(descriptor_->file())) { 1271 if (HasGeneratedMethods(descriptor_->file())) {
1246 for (int i = 0; i < descriptor_->field_count(); i++) { 1272 for (int i = 0; i < descriptor_->field_count(); i++) {
1247 const FieldDescriptor* field = descriptor_->field(i); 1273 const FieldDescriptor* field = descriptor_->field(i);
1248 field_generators_.get(field).GenerateSwappingCode(printer); 1274 field_generators_.get(field).GenerateSwappingCode(printer);
1249 } 1275 }
1250 1276
1251 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) { 1277 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1252 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", 1278 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1253 "i", SimpleItoa(i)); 1279 "i", SimpleItoa(i));
1254 } 1280 }
1255 1281
1256 if (HasUnknownFields(descriptor_->file())) { 1282 if (HasUnknownFields(descriptor_->file())) {
1257 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n"); 1283 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1258 } 1284 }
1259 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); 1285 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1260 if (descriptor_->extension_range_count() > 0) { 1286 if (descriptor_->extension_range_count() > 0) {
1261 printer->Print("_extensions_.Swap(&other->_extensions_);\n"); 1287 printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1262 } 1288 }
1263 } else { 1289 } else {
1264 printer->Print("GetReflection()->Swap(this, other);"); 1290 printer->Print("GetReflection()->Swap(this, other);");
1265 } 1291 }
1266 1292
1267 printer->Outdent(); 1293 printer->Outdent();
1268 printer->Print("}\n"); 1294 printer->Print("}\n");
1269 printer->Outdent(); 1295 printer->Outdent();
1270 printer->Print("}\n"); 1296 printer->Print("}\n");
1271 } 1297 }
1272 1298
1273 void MessageGenerator:: 1299 void MessageGenerator::
1274 GenerateMergeFrom(io::Printer* printer) { 1300 GenerateMergeFrom(io::Printer* printer) {
1275 if (HasDescriptorMethods(descriptor_->file())) { 1301 if (HasDescriptorMethods(descriptor_->file())) {
1276 // Generate the generalized MergeFrom (aka that which takes in the Message 1302 // Generate the generalized MergeFrom (aka that which takes in the Message
1277 // base class as a parameter). 1303 // base class as a parameter).
1278 printer->Print( 1304 printer->Print(
1279 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n" 1305 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1280 " GOOGLE_CHECK_NE(&from, this);\n", 1306 " GOOGLE_CHECK_NE(&from, this);\n",
1281 "classname", classname_); 1307 "classname", classname_);
1282 printer->Indent(); 1308 printer->Indent();
1283 1309
1284 // Cast the message to the proper type. If we find that the message is 1310 // Cast the message to the proper type. If we find that the message is
1285 // *not* of the proper type, we can still call Merge via the reflection 1311 // *not* of the proper type, we can still call Merge via the reflection
1286 // system, as the GOOGLE_CHECK above ensured that we have the same descriptor 1312 // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1287 // for each message. 1313 // for each message.
1288 printer->Print( 1314 printer->Print(
1289 "const $classname$* source =\n" 1315 "const $classname$* source =\n"
1290 " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n" 1316 " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1291 " &from);\n" 1317 " &from);\n"
1292 "if (source == NULL) {\n" 1318 "if (source == NULL) {\n"
1293 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" 1319 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1294 "} else {\n" 1320 "} else {\n"
1295 " MergeFrom(*source);\n" 1321 " MergeFrom(*source);\n"
1296 "}\n", 1322 "}\n",
1297 "classname", classname_); 1323 "classname", classname_);
1298 1324
1299 printer->Outdent(); 1325 printer->Outdent();
1300 printer->Print("}\n\n"); 1326 printer->Print("}\n\n");
1301 } else { 1327 } else {
1302 // Generate CheckTypeAndMergeFrom(). 1328 // Generate CheckTypeAndMergeFrom().
1303 printer->Print( 1329 printer->Print(
1304 "void $classname$::CheckTypeAndMergeFrom(\n" 1330 "void $classname$::CheckTypeAndMergeFrom(\n"
1305 " const ::google::protobuf::MessageLite& from) {\n" 1331 " const ::google::protobuf::MessageLite& from) {\n"
1306 " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n" 1332 " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1307 "}\n" 1333 "}\n"
1308 "\n", 1334 "\n",
1309 "classname", classname_); 1335 "classname", classname_);
1310 } 1336 }
1311 1337
1312 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. 1338 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1313 printer->Print( 1339 printer->Print(
1314 "void $classname$::MergeFrom(const $classname$& from) {\n" 1340 "void $classname$::MergeFrom(const $classname$& from) {\n"
1315 " GOOGLE_CHECK_NE(&from, this);\n", 1341 " GOOGLE_CHECK_NE(&from, this);\n",
1316 "classname", classname_); 1342 "classname", classname_);
1317 printer->Indent(); 1343 printer->Indent();
1318 1344
1319 // Merge Repeated fields. These fields do not require a 1345 // Merge Repeated fields. These fields do not require a
1320 // check as we can simply iterate over them. 1346 // check as we can simply iterate over them.
1321 for (int i = 0; i < descriptor_->field_count(); ++i) { 1347 for (int i = 0; i < descriptor_->field_count(); ++i) {
1322 const FieldDescriptor* field = descriptor_->field(i); 1348 const FieldDescriptor* field = descriptor_->field(i);
1323 1349
1324 if (field->is_repeated()) { 1350 if (field->is_repeated()) {
1325 field_generators_.get(field).GenerateMergingCode(printer); 1351 field_generators_.get(field).GenerateMergingCode(printer);
1326 } 1352 }
1327 } 1353 }
1328 1354
1329 // Merge Optional and Required fields (after a _has_bit check). 1355 // Merge Optional and Required fields (after a _has_bit check).
1330 int last_index = -1; 1356 int last_index = -1;
1331 1357
1332 for (int i = 0; i < descriptor_->field_count(); ++i) { 1358 for (int i = 0; i < descriptor_->field_count(); ++i) {
1333 const FieldDescriptor* field = descriptor_->field(i); 1359 const FieldDescriptor* field = descriptor_->field(i);
1334 1360
1335 if (!field->is_repeated()) { 1361 if (!field->is_repeated()) {
1336 // See above in GenerateClear for an explanation of this. 1362 // See above in GenerateClear for an explanation of this.
1337 if (i / 8 != last_index / 8 || last_index < 0) { 1363 if (i / 8 != last_index / 8 || last_index < 0) {
1338 if (last_index >= 0) { 1364 if (last_index >= 0) {
1339 printer->Outdent(); 1365 printer->Outdent();
1340 printer->Print("}\n"); 1366 printer->Print("}\n");
1341 } 1367 }
1342 printer->Print( 1368 printer->Print(
1343 "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 1369 "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1344 "index", SimpleItoa(field->index())); 1370 "index", SimpleItoa(field->index()));
1345 printer->Indent(); 1371 printer->Indent();
1346 } 1372 }
1347 1373
1348 last_index = i; 1374 last_index = i;
1349 1375
1350 printer->Print( 1376 printer->Print(
1351 "if (from.has_$name$()) {\n", 1377 "if (from.has_$name$()) {\n",
1352 "name", FieldName(field)); 1378 "name", FieldName(field));
1353 printer->Indent(); 1379 printer->Indent();
1354 1380
1355 field_generators_.get(field).GenerateMergingCode(printer); 1381 field_generators_.get(field).GenerateMergingCode(printer);
1356 1382
1357 printer->Outdent(); 1383 printer->Outdent();
1358 printer->Print("}\n"); 1384 printer->Print("}\n");
1359 } 1385 }
1360 } 1386 }
1361 1387
1362 if (last_index >= 0) { 1388 if (last_index >= 0) {
1363 printer->Outdent(); 1389 printer->Outdent();
1364 printer->Print("}\n"); 1390 printer->Print("}\n");
1365 } 1391 }
1366 1392
1367 if (descriptor_->extension_range_count() > 0) { 1393 if (descriptor_->extension_range_count() > 0) {
1368 printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); 1394 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1369 } 1395 }
1370 1396
1371 if (HasUnknownFields(descriptor_->file())) { 1397 if (HasUnknownFields(descriptor_->file())) {
1372 printer->Print( 1398 printer->Print(
1373 "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"); 1399 "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1374 } 1400 }
1375 1401
1376 printer->Outdent(); 1402 printer->Outdent();
1377 printer->Print("}\n"); 1403 printer->Print("}\n");
1378 } 1404 }
1379 1405
1380 void MessageGenerator:: 1406 void MessageGenerator::
1381 GenerateCopyFrom(io::Printer* printer) { 1407 GenerateCopyFrom(io::Printer* printer) {
1382 if (HasDescriptorMethods(descriptor_->file())) { 1408 if (HasDescriptorMethods(descriptor_->file())) {
1383 // Generate the generalized CopyFrom (aka that which takes in the Message 1409 // Generate the generalized CopyFrom (aka that which takes in the Message
1384 // base class as a parameter). 1410 // base class as a parameter).
1385 printer->Print( 1411 printer->Print(
1386 "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n", 1412 "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1387 "classname", classname_); 1413 "classname", classname_);
1388 printer->Indent(); 1414 printer->Indent();
1389 1415
1390 printer->Print( 1416 printer->Print(
1391 "if (&from == this) return;\n" 1417 "if (&from == this) return;\n"
1392 "Clear();\n" 1418 "Clear();\n"
1393 "MergeFrom(from);\n"); 1419 "MergeFrom(from);\n");
1394 1420
1395 printer->Outdent(); 1421 printer->Outdent();
1396 printer->Print("}\n\n"); 1422 printer->Print("}\n\n");
1397 } 1423 }
1398 1424
1399 // Generate the class-specific CopyFrom. 1425 // Generate the class-specific CopyFrom.
1400 printer->Print( 1426 printer->Print(
1401 "void $classname$::CopyFrom(const $classname$& from) {\n", 1427 "void $classname$::CopyFrom(const $classname$& from) {\n",
1402 "classname", classname_); 1428 "classname", classname_);
1403 printer->Indent(); 1429 printer->Indent();
1404 1430
1405 printer->Print( 1431 printer->Print(
1406 "if (&from == this) return;\n" 1432 "if (&from == this) return;\n"
1407 "Clear();\n" 1433 "Clear();\n"
1408 "MergeFrom(from);\n"); 1434 "MergeFrom(from);\n");
1409 1435
1410 printer->Outdent(); 1436 printer->Outdent();
1411 printer->Print("}\n"); 1437 printer->Print("}\n");
1412 } 1438 }
1413 1439
1414 void MessageGenerator:: 1440 void MessageGenerator::
1415 GenerateMergeFromCodedStream(io::Printer* printer) { 1441 GenerateMergeFromCodedStream(io::Printer* printer) {
1416 if (descriptor_->options().message_set_wire_format()) { 1442 if (descriptor_->options().message_set_wire_format()) {
1417 // Special-case MessageSet. 1443 // Special-case MessageSet.
1418 printer->Print( 1444 printer->Print(
1419 "bool $classname$::MergePartialFromCodedStream(\n" 1445 "bool $classname$::MergePartialFromCodedStream(\n"
1420 " ::google::protobuf::io::CodedInputStream* input) {\n", 1446 " ::google::protobuf::io::CodedInputStream* input) {\n",
1421 "classname", classname_); 1447 "classname", classname_);
1422 1448
1423 PrintHandlingOptionalStaticInitializers( 1449 PrintHandlingOptionalStaticInitializers(
1424 descriptor_->file(), printer, 1450 descriptor_->file(), printer,
1425 // With static initializers. 1451 // With static initializers.
1426 " return _extensions_.ParseMessageSet(input, default_instance_,\n" 1452 " return _extensions_.ParseMessageSet(input, default_instance_,\n"
1427 " mutable_unknown_fields());\n", 1453 " mutable_unknown_fields());\n",
1428 // Without. 1454 // Without.
1429 " return _extensions_.ParseMessageSet(input, &default_instance(),\n" 1455 " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
1430 " mutable_unknown_fields());\n", 1456 " mutable_unknown_fields());\n",
1431 // Vars. 1457 // Vars.
1432 "classname", classname_); 1458 "classname", classname_);
1433 1459
1434 printer->Print( 1460 printer->Print(
1435 "}\n"); 1461 "}\n");
1436 return; 1462 return;
1437 } 1463 }
1438 1464
1439 printer->Print( 1465 printer->Print(
1440 "bool $classname$::MergePartialFromCodedStream(\n" 1466 "bool $classname$::MergePartialFromCodedStream(\n"
1441 " ::google::protobuf::io::CodedInputStream* input) {\n" 1467 " ::google::protobuf::io::CodedInputStream* input) {\n"
1442 "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" 1468 "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1443 " ::google::protobuf::uint32 tag;\n" 1469 " ::google::protobuf::uint32 tag;\n"
1444 " while ((tag = input->ReadTag()) != 0) {\n", 1470 " while ((tag = input->ReadTag()) != 0) {\n",
1445 "classname", classname_); 1471 "classname", classname_);
1446 1472
1447 printer->Indent(); 1473 printer->Indent();
1448 printer->Indent(); 1474 printer->Indent();
1449 1475
1450 if (descriptor_->field_count() > 0) { 1476 if (descriptor_->field_count() > 0) {
1451 // We don't even want to print the switch() if we have no fields because 1477 // We don't even want to print the switch() if we have no fields because
1452 // MSVC dislikes switch() statements that contain only a default value. 1478 // MSVC dislikes switch() statements that contain only a default value.
1453 1479
1454 // Note: If we just switched on the tag rather than the field number, we 1480 // Note: If we just switched on the tag rather than the field number, we
1455 // could avoid the need for the if() to check the wire type at the beginning 1481 // could avoid the need for the if() to check the wire type at the beginning
1456 // of each case. However, this is actually a bit slower in practice as it 1482 // of each case. However, this is actually a bit slower in practice as it
1457 // creates a jump table that is 8x larger and sparser, and meanwhile the 1483 // creates a jump table that is 8x larger and sparser, and meanwhile the
1458 // if()s are highly predictable. 1484 // if()s are highly predictable.
1459 printer->Print( 1485 printer->Print(
1460 "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n"); 1486 "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1461 1487
1462 printer->Indent(); 1488 printer->Indent();
1463 1489
1464 scoped_array<const FieldDescriptor*> ordered_fields( 1490 scoped_array<const FieldDescriptor*> ordered_fields(
1465 SortFieldsByNumber(descriptor_)); 1491 SortFieldsByNumber(descriptor_));
1466 1492
1467 for (int i = 0; i < descriptor_->field_count(); i++) { 1493 for (int i = 0; i < descriptor_->field_count(); i++) {
1468 const FieldDescriptor* field = ordered_fields[i]; 1494 const FieldDescriptor* field = ordered_fields[i];
1469 1495
1470 PrintFieldComment(printer, field); 1496 PrintFieldComment(printer, field);
1471 1497
1472 printer->Print( 1498 printer->Print(
1473 "case $number$: {\n", 1499 "case $number$: {\n",
1474 "number", SimpleItoa(field->number())); 1500 "number", SimpleItoa(field->number()));
1475 printer->Indent(); 1501 printer->Indent();
1476 const FieldGenerator& field_generator = field_generators_.get(field); 1502 const FieldGenerator& field_generator = field_generators_.get(field);
1477 1503
1478 // Emit code to parse the common, expected case. 1504 // Emit code to parse the common, expected case.
1479 printer->Print( 1505 printer->Print(
1480 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" 1506 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1481 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n", 1507 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1482 "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); 1508 "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
1483 1509
1484 if (i > 0 || (field->is_repeated() && !field->options().packed())) { 1510 if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1485 printer->Print( 1511 printer->Print(
1486 " parse_$name$:\n", 1512 " parse_$name$:\n",
1487 "name", field->name()); 1513 "name", field->name());
1488 } 1514 }
1489 1515
1490 printer->Indent(); 1516 printer->Indent();
1491 if (field->options().packed()) { 1517 if (field->options().packed()) {
1492 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 1518 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1493 } else { 1519 } else {
1494 field_generator.GenerateMergeFromCodedStream(printer); 1520 field_generator.GenerateMergeFromCodedStream(printer);
1495 } 1521 }
1496 printer->Outdent(); 1522 printer->Outdent();
1497 1523
1498 // Emit code to parse unexpectedly packed or unpacked values. 1524 // Emit code to parse unexpectedly packed or unpacked values.
1499 if (field->is_packable() && field->options().packed()) { 1525 if (field->is_packable() && field->options().packed()) {
1500 printer->Print( 1526 printer->Print(
1501 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" 1527 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1502 " == ::google::protobuf::internal::WireFormatLite::\n" 1528 " == ::google::protobuf::internal::WireFormatLite::\n"
1503 " WIRETYPE_$wiretype$) {\n", 1529 " WIRETYPE_$wiretype$) {\n",
1504 "wiretype", 1530 "wiretype",
1505 kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); 1531 kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
1506 printer->Indent(); 1532 printer->Indent();
1507 field_generator.GenerateMergeFromCodedStream(printer); 1533 field_generator.GenerateMergeFromCodedStream(printer);
1508 printer->Outdent(); 1534 printer->Outdent();
1509 } else if (field->is_packable() && !field->options().packed()) { 1535 } else if (field->is_packable() && !field->options().packed()) {
1510 printer->Print( 1536 printer->Print(
1511 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" 1537 "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1512 " == ::google::protobuf::internal::WireFormatLite::\n" 1538 " == ::google::protobuf::internal::WireFormatLite::\n"
1513 " WIRETYPE_LENGTH_DELIMITED) {\n"); 1539 " WIRETYPE_LENGTH_DELIMITED) {\n");
1514 printer->Indent(); 1540 printer->Indent();
1515 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 1541 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1516 printer->Outdent(); 1542 printer->Outdent();
1517 } 1543 }
1518 1544
1519 printer->Print( 1545 printer->Print(
1520 "} else {\n" 1546 "} else {\n"
1521 " goto handle_uninterpreted;\n" 1547 " goto handle_uninterpreted;\n"
1522 "}\n"); 1548 "}\n");
1523 1549
1524 // switch() is slow since it can't be predicted well. Insert some if()s 1550 // switch() is slow since it can't be predicted well. Insert some if()s
1525 // here that attempt to predict the next tag. 1551 // here that attempt to predict the next tag.
1526 if (field->is_repeated() && !field->options().packed()) { 1552 if (field->is_repeated() && !field->options().packed()) {
1527 // Expect repeats of this field. 1553 // Expect repeats of this field.
1528 printer->Print( 1554 printer->Print(
1529 "if (input->ExpectTag($tag$)) goto parse_$name$;\n", 1555 "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
1530 "tag", SimpleItoa(WireFormat::MakeTag(field)), 1556 "tag", SimpleItoa(WireFormat::MakeTag(field)),
1531 "name", field->name()); 1557 "name", field->name());
1532 } 1558 }
1533 1559
1534 if (i + 1 < descriptor_->field_count()) { 1560 if (i + 1 < descriptor_->field_count()) {
1535 // Expect the next field in order. 1561 // Expect the next field in order.
1536 const FieldDescriptor* next_field = ordered_fields[i + 1]; 1562 const FieldDescriptor* next_field = ordered_fields[i + 1];
1537 printer->Print( 1563 printer->Print(
1538 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", 1564 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
1539 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), 1565 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
1540 "next_name", next_field->name()); 1566 "next_name", next_field->name());
1541 } else { 1567 } else {
1542 // Expect EOF. 1568 // Expect EOF.
1543 // TODO(kenton): Expect group end-tag? 1569 // TODO(kenton): Expect group end-tag?
1544 printer->Print( 1570 printer->Print(
1545 "if (input->ExpectAtEnd()) return true;\n"); 1571 "if (input->ExpectAtEnd()) return true;\n");
1546 } 1572 }
1547 1573
1548 printer->Print( 1574 printer->Print(
1549 "break;\n"); 1575 "break;\n");
1550 1576
1551 printer->Outdent(); 1577 printer->Outdent();
1552 printer->Print("}\n\n"); 1578 printer->Print("}\n\n");
1553 } 1579 }
1554 1580
1555 printer->Print( 1581 printer->Print(
1556 "default: {\n" 1582 "default: {\n"
1557 "handle_uninterpreted:\n"); 1583 "handle_uninterpreted:\n");
1558 printer->Indent(); 1584 printer->Indent();
1559 } 1585 }
1560 1586
1561 // Is this an end-group tag? If so, this must be the end of the message. 1587 // Is this an end-group tag? If so, this must be the end of the message.
1562 printer->Print( 1588 printer->Print(
1563 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" 1589 "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1564 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" 1590 " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1565 " return true;\n" 1591 " return true;\n"
1566 "}\n"); 1592 "}\n");
1567 1593
1568 // Handle extension ranges. 1594 // Handle extension ranges.
1569 if (descriptor_->extension_range_count() > 0) { 1595 if (descriptor_->extension_range_count() > 0) {
1570 printer->Print( 1596 printer->Print(
1571 "if ("); 1597 "if (");
1572 for (int i = 0; i < descriptor_->extension_range_count(); i++) { 1598 for (int i = 0; i < descriptor_->extension_range_count(); i++) {
1573 const Descriptor::ExtensionRange* range = 1599 const Descriptor::ExtensionRange* range =
1574 descriptor_->extension_range(i); 1600 descriptor_->extension_range(i);
1575 if (i > 0) printer->Print(" ||\n "); 1601 if (i > 0) printer->Print(" ||\n ");
1576 1602
1577 uint32 start_tag = WireFormatLite::MakeTag( 1603 uint32 start_tag = WireFormatLite::MakeTag(
1578 range->start, static_cast<WireFormatLite::WireType>(0)); 1604 range->start, static_cast<WireFormatLite::WireType>(0));
1579 uint32 end_tag = WireFormatLite::MakeTag( 1605 uint32 end_tag = WireFormatLite::MakeTag(
1580 range->end, static_cast<WireFormatLite::WireType>(0)); 1606 range->end, static_cast<WireFormatLite::WireType>(0));
1581 1607
1582 if (range->end > FieldDescriptor::kMaxNumber) { 1608 if (range->end > FieldDescriptor::kMaxNumber) {
1583 printer->Print( 1609 printer->Print(
1584 "($start$u <= tag)", 1610 "($start$u <= tag)",
1585 "start", SimpleItoa(start_tag)); 1611 "start", SimpleItoa(start_tag));
1586 } else { 1612 } else {
1587 printer->Print( 1613 printer->Print(
1588 "($start$u <= tag && tag < $end$u)", 1614 "($start$u <= tag && tag < $end$u)",
1589 "start", SimpleItoa(start_tag), 1615 "start", SimpleItoa(start_tag),
1590 "end", SimpleItoa(end_tag)); 1616 "end", SimpleItoa(end_tag));
1591 } 1617 }
1592 } 1618 }
1593 printer->Print(") {\n"); 1619 printer->Print(") {\n");
1594 if (HasUnknownFields(descriptor_->file())) { 1620 if (HasUnknownFields(descriptor_->file())) {
1595 PrintHandlingOptionalStaticInitializers( 1621 PrintHandlingOptionalStaticInitializers(
1596 descriptor_->file(), printer, 1622 descriptor_->file(), printer,
1597 // With static initializers. 1623 // With static initializers.
1598 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" 1624 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
1599 " mutable_unknown_fields()));\n", 1625 " mutable_unknown_fields()));\n",
1600 // Without. 1626 // Without.
1601 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" 1627 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
1602 " mutable_unknown_fields()));\n"); 1628 " mutable_unknown_fields()));\n");
1603 } else { 1629 } else {
1604 PrintHandlingOptionalStaticInitializers( 1630 PrintHandlingOptionalStaticInitializers(
1605 descriptor_->file(), printer, 1631 descriptor_->file(), printer,
1606 // With static initializers. 1632 // With static initializers.
1607 " DO_(_extensions_.ParseField(tag, input, default_instance_));\n", 1633 " DO_(_extensions_.ParseField(tag, input, default_instance_));\n",
1608 // Without. 1634 // Without.
1609 " DO_(_extensions_.ParseField(tag, input, &default_instance()));\n"); 1635 " DO_(_extensions_.ParseField(tag, input, &default_instance()));\n");
1610 } 1636 }
1611 printer->Print( 1637 printer->Print(
1612 " continue;\n" 1638 " continue;\n"
1613 "}\n"); 1639 "}\n");
1614 } 1640 }
1615 1641
1616 // We really don't recognize this tag. Skip it. 1642 // We really don't recognize this tag. Skip it.
1617 if (HasUnknownFields(descriptor_->file())) { 1643 if (HasUnknownFields(descriptor_->file())) {
1618 printer->Print( 1644 printer->Print(
1619 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" 1645 "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1620 " input, tag, mutable_unknown_fields()));\n"); 1646 " input, tag, mutable_unknown_fields()));\n");
1621 } else { 1647 } else {
1622 printer->Print( 1648 printer->Print(
1623 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n"); 1649 "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
1624 } 1650 }
1625 1651
1626 if (descriptor_->field_count() > 0) { 1652 if (descriptor_->field_count() > 0) {
1627 printer->Print("break;\n"); 1653 printer->Print("break;\n");
1628 printer->Outdent(); 1654 printer->Outdent();
1629 printer->Print("}\n"); // default: 1655 printer->Print("}\n"); // default:
1630 printer->Outdent(); 1656 printer->Outdent();
1631 printer->Print("}\n"); // switch 1657 printer->Print("}\n"); // switch
1632 } 1658 }
1633 1659
1634 printer->Outdent(); 1660 printer->Outdent();
1635 printer->Outdent(); 1661 printer->Outdent();
1636 printer->Print( 1662 printer->Print(
1637 " }\n" // while 1663 " }\n" // while
1638 " return true;\n" 1664 " return true;\n"
1639 "#undef DO_\n" 1665 "#undef DO_\n"
1640 "}\n"); 1666 "}\n");
1641 } 1667 }
1642 1668
1643 void MessageGenerator::GenerateSerializeOneField( 1669 void MessageGenerator::GenerateSerializeOneField(
1644 io::Printer* printer, const FieldDescriptor* field, bool to_array) { 1670 io::Printer* printer, const FieldDescriptor* field, bool to_array) {
1645 PrintFieldComment(printer, field); 1671 PrintFieldComment(printer, field);
1646 1672
1647 if (!field->is_repeated()) { 1673 if (!field->is_repeated()) {
1648 printer->Print( 1674 printer->Print(
1649 "if (has_$name$()) {\n", 1675 "if (has_$name$()) {\n",
1650 "name", FieldName(field)); 1676 "name", FieldName(field));
1651 printer->Indent(); 1677 printer->Indent();
1652 } 1678 }
1653 1679
1654 if (to_array) { 1680 if (to_array) {
1655 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( 1681 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
1656 printer); 1682 printer);
1657 } else { 1683 } else {
1658 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); 1684 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
1659 } 1685 }
1660 1686
1661 if (!field->is_repeated()) { 1687 if (!field->is_repeated()) {
1662 printer->Outdent(); 1688 printer->Outdent();
1663 printer->Print("}\n"); 1689 printer->Print("}\n");
1664 } 1690 }
1665 printer->Print("\n"); 1691 printer->Print("\n");
1666 } 1692 }
1667 1693
1668 void MessageGenerator::GenerateSerializeOneExtensionRange( 1694 void MessageGenerator::GenerateSerializeOneExtensionRange(
1669 io::Printer* printer, const Descriptor::ExtensionRange* range, 1695 io::Printer* printer, const Descriptor::ExtensionRange* range,
1670 bool to_array) { 1696 bool to_array) {
1671 map<string, string> vars; 1697 map<string, string> vars;
1672 vars["start"] = SimpleItoa(range->start); 1698 vars["start"] = SimpleItoa(range->start);
1673 vars["end"] = SimpleItoa(range->end); 1699 vars["end"] = SimpleItoa(range->end);
1674 printer->Print(vars, 1700 printer->Print(vars,
1675 "// Extension range [$start$, $end$)\n"); 1701 "// Extension range [$start$, $end$)\n");
1676 if (to_array) { 1702 if (to_array) {
1677 printer->Print(vars, 1703 printer->Print(vars,
1678 "target = _extensions_.SerializeWithCachedSizesToArray(\n" 1704 "target = _extensions_.SerializeWithCachedSizesToArray(\n"
1679 " $start$, $end$, target);\n\n"); 1705 " $start$, $end$, target);\n\n");
1680 } else { 1706 } else {
1681 printer->Print(vars, 1707 printer->Print(vars,
1682 "_extensions_.SerializeWithCachedSizes(\n" 1708 "_extensions_.SerializeWithCachedSizes(\n"
1683 " $start$, $end$, output);\n\n"); 1709 " $start$, $end$, output);\n\n");
1684 } 1710 }
1685 } 1711 }
1686 1712
1687 void MessageGenerator:: 1713 void MessageGenerator::
1688 GenerateSerializeWithCachedSizes(io::Printer* printer) { 1714 GenerateSerializeWithCachedSizes(io::Printer* printer) {
1689 if (descriptor_->options().message_set_wire_format()) { 1715 if (descriptor_->options().message_set_wire_format()) {
1690 // Special-case MessageSet. 1716 // Special-case MessageSet.
1691 printer->Print( 1717 printer->Print(
1692 "void $classname$::SerializeWithCachedSizes(\n" 1718 "void $classname$::SerializeWithCachedSizes(\n"
1693 " ::google::protobuf::io::CodedOutputStream* output) const {\n" 1719 " ::google::protobuf::io::CodedOutputStream* output) const {\n"
1694 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", 1720 " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
1695 "classname", classname_); 1721 "classname", classname_);
1696 if (HasUnknownFields(descriptor_->file())) { 1722 if (HasUnknownFields(descriptor_->file())) {
1697 printer->Print( 1723 printer->Print(
1698 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" 1724 " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
1699 " unknown_fields(), output);\n"); 1725 " unknown_fields(), output);\n");
1700 } 1726 }
1701 printer->Print( 1727 printer->Print(
1702 "}\n"); 1728 "}\n");
1703 return; 1729 return;
1704 } 1730 }
1705 1731
1706 printer->Print( 1732 printer->Print(
1707 "void $classname$::SerializeWithCachedSizes(\n" 1733 "void $classname$::SerializeWithCachedSizes(\n"
1708 " ::google::protobuf::io::CodedOutputStream* output) const {\n", 1734 " ::google::protobuf::io::CodedOutputStream* output) const {\n",
1709 "classname", classname_); 1735 "classname", classname_);
1710 printer->Indent(); 1736 printer->Indent();
1711 1737
1712 GenerateSerializeWithCachedSizesBody(printer, false); 1738 GenerateSerializeWithCachedSizesBody(printer, false);
1713 1739
1714 printer->Outdent(); 1740 printer->Outdent();
1715 printer->Print( 1741 printer->Print(
1716 "}\n"); 1742 "}\n");
1717 } 1743 }
1718 1744
1719 void MessageGenerator:: 1745 void MessageGenerator::
1720 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { 1746 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
1721 if (descriptor_->options().message_set_wire_format()) { 1747 if (descriptor_->options().message_set_wire_format()) {
1722 // Special-case MessageSet. 1748 // Special-case MessageSet.
1723 printer->Print( 1749 printer->Print(
1724 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 1750 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1725 " ::google::protobuf::uint8* target) const {\n" 1751 " ::google::protobuf::uint8* target) const {\n"
1726 " target =\n" 1752 " target =\n"
1727 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n", 1753 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
1728 "classname", classname_); 1754 "classname", classname_);
1729 if (HasUnknownFields(descriptor_->file())) { 1755 if (HasUnknownFields(descriptor_->file())) {
1730 printer->Print( 1756 printer->Print(
1731 " target = ::google::protobuf::internal::WireFormat::\n" 1757 " target = ::google::protobuf::internal::WireFormat::\n"
1732 " SerializeUnknownMessageSetItemsToArray(\n" 1758 " SerializeUnknownMessageSetItemsToArray(\n"
1733 " unknown_fields(), target);\n"); 1759 " unknown_fields(), target);\n");
1734 } 1760 }
1735 printer->Print( 1761 printer->Print(
1736 " return target;\n" 1762 " return target;\n"
1737 "}\n"); 1763 "}\n");
1738 return; 1764 return;
1739 } 1765 }
1740 1766
1741 printer->Print( 1767 printer->Print(
1742 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 1768 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1743 " ::google::protobuf::uint8* target) const {\n", 1769 " ::google::protobuf::uint8* target) const {\n",
1744 "classname", classname_); 1770 "classname", classname_);
1745 printer->Indent(); 1771 printer->Indent();
1746 1772
1747 GenerateSerializeWithCachedSizesBody(printer, true); 1773 GenerateSerializeWithCachedSizesBody(printer, true);
1748 1774
1749 printer->Outdent(); 1775 printer->Outdent();
1750 printer->Print( 1776 printer->Print(
1751 " return target;\n" 1777 " return target;\n"
1752 "}\n"); 1778 "}\n");
1753 } 1779 }
1754 1780
1755 void MessageGenerator:: 1781 void MessageGenerator::
1756 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { 1782 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
1757 scoped_array<const FieldDescriptor*> ordered_fields( 1783 scoped_array<const FieldDescriptor*> ordered_fields(
1758 SortFieldsByNumber(descriptor_)); 1784 SortFieldsByNumber(descriptor_));
1759 1785
1760 vector<const Descriptor::ExtensionRange*> sorted_extensions; 1786 vector<const Descriptor::ExtensionRange*> sorted_extensions;
1761 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 1787 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
1762 sorted_extensions.push_back(descriptor_->extension_range(i)); 1788 sorted_extensions.push_back(descriptor_->extension_range(i));
1763 } 1789 }
1764 sort(sorted_extensions.begin(), sorted_extensions.end(), 1790 sort(sorted_extensions.begin(), sorted_extensions.end(),
1765 ExtensionRangeSorter()); 1791 ExtensionRangeSorter());
1766 1792
1767 // Merge the fields and the extension ranges, both sorted by field number. 1793 // Merge the fields and the extension ranges, both sorted by field number.
1768 int i, j; 1794 int i, j;
1769 for (i = 0, j = 0; 1795 for (i = 0, j = 0;
1770 i < descriptor_->field_count() || j < sorted_extensions.size(); 1796 i < descriptor_->field_count() || j < sorted_extensions.size();
1771 ) { 1797 ) {
1772 if (i == descriptor_->field_count()) { 1798 if (i == descriptor_->field_count()) {
1773 GenerateSerializeOneExtensionRange(printer, 1799 GenerateSerializeOneExtensionRange(printer,
1774 sorted_extensions[j++], 1800 sorted_extensions[j++],
1775 to_array); 1801 to_array);
1776 } else if (j == sorted_extensions.size()) { 1802 } else if (j == sorted_extensions.size()) {
1777 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 1803 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1778 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { 1804 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
1779 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 1805 GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1780 } else { 1806 } else {
1781 GenerateSerializeOneExtensionRange(printer, 1807 GenerateSerializeOneExtensionRange(printer,
1782 sorted_extensions[j++], 1808 sorted_extensions[j++],
1783 to_array); 1809 to_array);
1784 } 1810 }
1785 } 1811 }
1786 1812
1787 if (HasUnknownFields(descriptor_->file())) { 1813 if (HasUnknownFields(descriptor_->file())) {
1788 printer->Print("if (!unknown_fields().empty()) {\n"); 1814 printer->Print("if (!unknown_fields().empty()) {\n");
1789 printer->Indent(); 1815 printer->Indent();
1790 if (to_array) { 1816 if (to_array) {
1791 printer->Print( 1817 printer->Print(
1792 "target = " 1818 "target = "
1793 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" 1819 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
1794 " unknown_fields(), target);\n"); 1820 " unknown_fields(), target);\n");
1795 } else { 1821 } else {
1796 printer->Print( 1822 printer->Print(
1797 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" 1823 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
1798 " unknown_fields(), output);\n"); 1824 " unknown_fields(), output);\n");
1799 } 1825 }
1800 printer->Outdent(); 1826 printer->Outdent();
1801 1827
1802 printer->Print( 1828 printer->Print(
1803 "}\n"); 1829 "}\n");
1804 } 1830 }
1805 } 1831 }
1806 1832
1807 void MessageGenerator:: 1833 void MessageGenerator::
1808 GenerateByteSize(io::Printer* printer) { 1834 GenerateByteSize(io::Printer* printer) {
1809 if (descriptor_->options().message_set_wire_format()) { 1835 if (descriptor_->options().message_set_wire_format()) {
1810 // Special-case MessageSet. 1836 // Special-case MessageSet.
1811 printer->Print( 1837 printer->Print(
1812 "int $classname$::ByteSize() const {\n" 1838 "int $classname$::ByteSize() const {\n"
1813 " int total_size = _extensions_.MessageSetByteSize();\n", 1839 " int total_size = _extensions_.MessageSetByteSize();\n",
1814 "classname", classname_); 1840 "classname", classname_);
1815 if (HasUnknownFields(descriptor_->file())) { 1841 if (HasUnknownFields(descriptor_->file())) {
1816 printer->Print( 1842 printer->Print(
1817 " total_size += ::google::protobuf::internal::WireFormat::\n" 1843 " total_size += ::google::protobuf::internal::WireFormat::\n"
1818 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"); 1844 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1819 } 1845 }
1820 printer->Print( 1846 printer->Print(
1821 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 1847 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1822 " _cached_size_ = total_size;\n" 1848 " _cached_size_ = total_size;\n"
1823 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 1849 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1824 " return total_size;\n" 1850 " return total_size;\n"
1825 "}\n"); 1851 "}\n");
1826 return; 1852 return;
1827 } 1853 }
1828 1854
1829 printer->Print( 1855 printer->Print(
1830 "int $classname$::ByteSize() const {\n", 1856 "int $classname$::ByteSize() const {\n",
1831 "classname", classname_); 1857 "classname", classname_);
1832 printer->Indent(); 1858 printer->Indent();
1833 printer->Print( 1859 printer->Print(
1834 "int total_size = 0;\n" 1860 "int total_size = 0;\n"
1835 "\n"); 1861 "\n");
1836 1862
1837 int last_index = -1; 1863 int last_index = -1;
1838 1864
1839 for (int i = 0; i < descriptor_->field_count(); i++) { 1865 for (int i = 0; i < descriptor_->field_count(); i++) {
1840 const FieldDescriptor* field = descriptor_->field(i); 1866 const FieldDescriptor* field = descriptor_->field(i);
1841 1867
1842 if (!field->is_repeated()) { 1868 if (!field->is_repeated()) {
1843 // See above in GenerateClear for an explanation of this. 1869 // See above in GenerateClear for an explanation of this.
1844 // TODO(kenton): Share code? Unclear how to do so without 1870 // TODO(kenton): Share code? Unclear how to do so without
1845 // over-engineering. 1871 // over-engineering.
1846 if ((i / 8) != (last_index / 8) || 1872 if ((i / 8) != (last_index / 8) ||
1847 last_index < 0) { 1873 last_index < 0) {
1848 if (last_index >= 0) { 1874 if (last_index >= 0) {
1849 printer->Outdent(); 1875 printer->Outdent();
1850 printer->Print("}\n"); 1876 printer->Print("}\n");
1851 } 1877 }
1852 printer->Print( 1878 printer->Print(
1853 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 1879 "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1854 "index", SimpleItoa(field->index())); 1880 "index", SimpleItoa(field->index()));
1855 printer->Indent(); 1881 printer->Indent();
1856 } 1882 }
1857 last_index = i; 1883 last_index = i;
1858 1884
1859 PrintFieldComment(printer, field); 1885 PrintFieldComment(printer, field);
1860 1886
1861 printer->Print( 1887 printer->Print(
1862 "if (has_$name$()) {\n", 1888 "if (has_$name$()) {\n",
1863 "name", FieldName(field)); 1889 "name", FieldName(field));
1864 printer->Indent(); 1890 printer->Indent();
1865 1891
1866 field_generators_.get(field).GenerateByteSize(printer); 1892 field_generators_.get(field).GenerateByteSize(printer);
1867 1893
1868 printer->Outdent(); 1894 printer->Outdent();
1869 printer->Print( 1895 printer->Print(
1870 "}\n" 1896 "}\n"
1871 "\n"); 1897 "\n");
1872 } 1898 }
1873 } 1899 }
1874 1900
1875 if (last_index >= 0) { 1901 if (last_index >= 0) {
1876 printer->Outdent(); 1902 printer->Outdent();
1877 printer->Print("}\n"); 1903 printer->Print("}\n");
1878 } 1904 }
1879 1905
1880 // Repeated fields don't use _has_bits_ so we count them in a separate 1906 // Repeated fields don't use _has_bits_ so we count them in a separate
1881 // pass. 1907 // pass.
1882 for (int i = 0; i < descriptor_->field_count(); i++) { 1908 for (int i = 0; i < descriptor_->field_count(); i++) {
1883 const FieldDescriptor* field = descriptor_->field(i); 1909 const FieldDescriptor* field = descriptor_->field(i);
1884 1910
1885 if (field->is_repeated()) { 1911 if (field->is_repeated()) {
1886 PrintFieldComment(printer, field); 1912 PrintFieldComment(printer, field);
1887 field_generators_.get(field).GenerateByteSize(printer); 1913 field_generators_.get(field).GenerateByteSize(printer);
1888 printer->Print("\n"); 1914 printer->Print("\n");
1889 } 1915 }
1890 } 1916 }
1891 1917
1892 if (descriptor_->extension_range_count() > 0) { 1918 if (descriptor_->extension_range_count() > 0) {
1893 printer->Print( 1919 printer->Print(
1894 "total_size += _extensions_.ByteSize();\n" 1920 "total_size += _extensions_.ByteSize();\n"
1895 "\n"); 1921 "\n");
1896 } 1922 }
1897 1923
1898 if (HasUnknownFields(descriptor_->file())) { 1924 if (HasUnknownFields(descriptor_->file())) {
1899 printer->Print("if (!unknown_fields().empty()) {\n"); 1925 printer->Print("if (!unknown_fields().empty()) {\n");
1900 printer->Indent(); 1926 printer->Indent();
1901 printer->Print( 1927 printer->Print(
1902 "total_size +=\n" 1928 "total_size +=\n"
1903 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" 1929 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
1904 " unknown_fields());\n"); 1930 " unknown_fields());\n");
1905 printer->Outdent(); 1931 printer->Outdent();
1906 printer->Print("}\n"); 1932 printer->Print("}\n");
1907 } 1933 }
1908 1934
1909 // We update _cached_size_ even though this is a const method. In theory, 1935 // We update _cached_size_ even though this is a const method. In theory,
1910 // this is not thread-compatible, because concurrent writes have undefined 1936 // this is not thread-compatible, because concurrent writes have undefined
1911 // results. In practice, since any concurrent writes will be writing the 1937 // results. In practice, since any concurrent writes will be writing the
1912 // exact same value, it works on all common processors. In a future version 1938 // exact same value, it works on all common processors. In a future version
1913 // of C++, _cached_size_ should be made into an atomic<int>. 1939 // of C++, _cached_size_ should be made into an atomic<int>.
1914 printer->Print( 1940 printer->Print(
1915 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 1941 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1916 "_cached_size_ = total_size;\n" 1942 "_cached_size_ = total_size;\n"
1917 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 1943 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1918 "return total_size;\n"); 1944 "return total_size;\n");
1919 1945
1920 printer->Outdent(); 1946 printer->Outdent();
1921 printer->Print("}\n"); 1947 printer->Print("}\n");
1922 } 1948 }
1923 1949
1924 void MessageGenerator:: 1950 void MessageGenerator::
1925 GenerateIsInitialized(io::Printer* printer) { 1951 GenerateIsInitialized(io::Printer* printer) {
1926 printer->Print( 1952 printer->Print(
1927 "bool $classname$::IsInitialized() const {\n", 1953 "bool $classname$::IsInitialized() const {\n",
1928 "classname", classname_); 1954 "classname", classname_);
1929 printer->Indent(); 1955 printer->Indent();
1930 1956
1931 // Check that all required fields in this message are set. We can do this 1957 // Check that all required fields in this message are set. We can do this
1932 // most efficiently by checking 32 "has bits" at a time. 1958 // most efficiently by checking 32 "has bits" at a time.
1933 int has_bits_array_size = (descriptor_->field_count() + 31) / 32; 1959 int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
1934 for (int i = 0; i < has_bits_array_size; i++) { 1960 for (int i = 0; i < has_bits_array_size; i++) {
1935 uint32 mask = 0; 1961 uint32 mask = 0;
1936 for (int bit = 0; bit < 32; bit++) { 1962 for (int bit = 0; bit < 32; bit++) {
1937 int index = i * 32 + bit; 1963 int index = i * 32 + bit;
1938 if (index >= descriptor_->field_count()) break; 1964 if (index >= descriptor_->field_count()) break;
1939 const FieldDescriptor* field = descriptor_->field(index); 1965 const FieldDescriptor* field = descriptor_->field(index);
1940 1966
1941 if (field->is_required()) { 1967 if (field->is_required()) {
1942 mask |= 1 << bit; 1968 mask |= 1 << bit;
1943 } 1969 }
1944 } 1970 }
1945 1971
1946 if (mask != 0) { 1972 if (mask != 0) {
1947 char buffer[kFastToBufferSize]; 1973 char buffer[kFastToBufferSize];
1948 printer->Print( 1974 printer->Print(
1949 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", 1975 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
1950 "i", SimpleItoa(i), 1976 "i", SimpleItoa(i),
1951 "mask", FastHex32ToBuffer(mask, buffer)); 1977 "mask", FastHex32ToBuffer(mask, buffer));
1952 } 1978 }
1953 } 1979 }
1954 1980
1955 // Now check that all embedded messages are initialized. 1981 // Now check that all embedded messages are initialized.
1956 printer->Print("\n"); 1982 printer->Print("\n");
1957 for (int i = 0; i < descriptor_->field_count(); i++) { 1983 for (int i = 0; i < descriptor_->field_count(); i++) {
1958 const FieldDescriptor* field = descriptor_->field(i); 1984 const FieldDescriptor* field = descriptor_->field(i);
1959 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 1985 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1986 !ShouldIgnoreRequiredFieldCheck(field) &&
1960 HasRequiredFields(field->message_type())) { 1987 HasRequiredFields(field->message_type())) {
1961 if (field->is_repeated()) { 1988 if (field->is_repeated()) {
1962 printer->Print( 1989 printer->Print(
1963 "for (int i = 0; i < $name$_size(); i++) {\n" 1990 "for (int i = 0; i < $name$_size(); i++) {\n"
1964 " if (!this->$name$(i).IsInitialized()) return false;\n" 1991 " if (!this->$name$(i).IsInitialized()) return false;\n"
1965 "}\n", 1992 "}\n",
1966 "name", FieldName(field)); 1993 "name", FieldName(field));
1967 } else { 1994 } else {
1968 printer->Print( 1995 printer->Print(
1969 "if (has_$name$()) {\n" 1996 "if (has_$name$()) {\n"
1970 " if (!this->$name$().IsInitialized()) return false;\n" 1997 " if (!this->$name$().IsInitialized()) return false;\n"
1971 "}\n", 1998 "}\n",
1972 "name", FieldName(field)); 1999 "name", FieldName(field));
1973 } 2000 }
1974 } 2001 }
1975 } 2002 }
1976 2003
1977 if (descriptor_->extension_range_count() > 0) { 2004 if (descriptor_->extension_range_count() > 0) {
1978 printer->Print( 2005 printer->Print(
1979 "\n" 2006 "\n"
1980 "if (!_extensions_.IsInitialized()) return false;"); 2007 "if (!_extensions_.IsInitialized()) return false;");
1981 } 2008 }
1982 2009
1983 printer->Outdent(); 2010 printer->Outdent();
1984 printer->Print( 2011 printer->Print(
1985 " return true;\n" 2012 " return true;\n"
1986 "}\n"); 2013 "}\n");
1987 } 2014 }
1988 2015
1989 2016
1990 } // namespace cpp 2017 } // namespace cpp
1991 } // namespace compiler 2018 } // namespace compiler
1992 } // namespace protobuf 2019 } // namespace protobuf
1993 } // namespace google 2020 } // namespace google
Powered by Google Project Hosting