Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
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.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 78
79 struct FieldOrderingByNumber { 79 struct FieldOrderingByNumber {
80 inline bool operator()(const FieldDescriptor* a, 80 inline bool operator()(const FieldDescriptor* a,
81 const FieldDescriptor* b) const { 81 const FieldDescriptor* b) const {
82 return a->number() < b->number(); 82 return a->number() < b->number();
83 } 83 }
84 }; 84 };
85 85
86 // 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
87 // and return it. 87 // and return it.
88 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 88 std::vector<const FieldDescriptor*> SortFieldsByNumber(
89 const FieldDescriptor** fields = 89 const Descriptor* descriptor) {
90 new const FieldDescriptor*[descriptor->field_count()]; 90 std::vector<const FieldDescriptor*> fields(descriptor->field_count());
91 for (int i = 0; i < descriptor->field_count(); i++) { 91 for (int i = 0; i < descriptor->field_count(); i++) {
92 fields[i] = descriptor->field(i); 92 fields[i] = descriptor->field(i);
93 } 93 }
94 std::sort(fields, fields + descriptor->field_count(), 94 std::sort(fields.begin(), fields.end(), FieldOrderingByNumber());
95 FieldOrderingByNumber());
96 return fields; 95 return fields;
97 } 96 }
98 97
99 // Functor for sorting extension ranges by their "start" field number. 98 // Functor for sorting extension ranges by their "start" field number.
100 struct ExtensionRangeSorter { 99 struct ExtensionRangeSorter {
101 bool operator()(const Descriptor::ExtensionRange* left, 100 bool operator()(const Descriptor::ExtensionRange* left,
102 const Descriptor::ExtensionRange* right) const { 101 const Descriptor::ExtensionRange* right) const {
103 return left->start < right->start; 102 return left->start < right->start;
104 } 103 }
105 }; 104 };
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 // Preferred location is the average among all the fields, so we weight by 200 // Preferred location is the average among all the fields, so we weight by
202 // the number of fields on each FieldGroup object. 201 // the number of fields on each FieldGroup object.
203 preferred_location_ = 202 preferred_location_ =
204 (preferred_location_ * fields_.size() + 203 (preferred_location_ * fields_.size() +
205 (other.preferred_location_ * other.fields_.size())) / 204 (other.preferred_location_ * other.fields_.size())) /
206 (fields_.size() + other.fields_.size()); 205 (fields_.size() + other.fields_.size());
207 fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); 206 fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
208 } 207 }
209 208
210 void SetPreferredLocation(float location) { preferred_location_ = location; } 209 void SetPreferredLocation(float location) { preferred_location_ = location; }
211 const vector<const FieldDescriptor*>& fields() const { return fields_; } 210 const std::vector<const FieldDescriptor*>& fields() const { return fields_; }
212 211
213 // FieldGroup objects sort by their preferred location. 212 // FieldGroup objects sort by their preferred location.
214 bool operator<(const FieldGroup& other) const { 213 bool operator<(const FieldGroup& other) const {
215 return preferred_location_ < other.preferred_location_; 214 return preferred_location_ < other.preferred_location_;
216 } 215 }
217 216
218 private: 217 private:
219 // "preferred_location_" is an estimate of where this group should go in the 218 // "preferred_location_" is an estimate of where this group should go in the
220 // final list of fields. We compute this by taking the average index of each 219 // final list of fields. We compute this by taking the average index of each
221 // field in this group in the original ordering of fields. This is very 220 // field in this group in the original ordering of fields. This is very
222 // approximate, but should put this group close to where its member fields 221 // approximate, but should put this group close to where its member fields
223 // originally went. 222 // originally went.
224 float preferred_location_; 223 float preferred_location_;
225 vector<const FieldDescriptor*> fields_; 224 std::vector<const FieldDescriptor*> fields_;
226 // We rely on the default copy constructor and operator= so this type can be 225 // We rely on the default copy constructor and operator= so this type can be
227 // used in a vector. 226 // used in a vector.
228 }; 227 };
229 228
229 // Helper for the code that emits the Clear() method.
230 bool CanInitializeByZeroing(const FieldDescriptor* field) {
231 if (field->is_repeated() || field->is_extension()) return false;
232 switch (field->cpp_type()) {
233 case internal::WireFormatLite::CPPTYPE_ENUM:
234 return field->default_value_enum()->number() == 0;
235 case internal::WireFormatLite::CPPTYPE_INT32:
236 return field->default_value_int32() == 0;
237 case internal::WireFormatLite::CPPTYPE_INT64:
238 return field->default_value_int64() == 0;
239 case internal::WireFormatLite::CPPTYPE_UINT32:
240 return field->default_value_uint32() == 0;
241 case internal::WireFormatLite::CPPTYPE_UINT64:
242 return field->default_value_uint64() == 0;
243 case internal::WireFormatLite::CPPTYPE_FLOAT:
244 return field->default_value_float() == 0;
245 case internal::WireFormatLite::CPPTYPE_DOUBLE:
246 return field->default_value_double() == 0;
247 case internal::WireFormatLite::CPPTYPE_BOOL:
248 return field->default_value_bool() == false;
249 default:
250 return false;
251 }
252 }
253
254 bool IsPOD(const FieldDescriptor* field) {
255 if (field->is_repeated() || field->is_extension()) return false;
256 switch (field->cpp_type()) {
257 case internal::WireFormatLite::CPPTYPE_ENUM:
258 case internal::WireFormatLite::CPPTYPE_INT32:
259 case internal::WireFormatLite::CPPTYPE_INT64:
260 case internal::WireFormatLite::CPPTYPE_UINT32:
261 case internal::WireFormatLite::CPPTYPE_UINT64:
262 case internal::WireFormatLite::CPPTYPE_FLOAT:
263 case internal::WireFormatLite::CPPTYPE_DOUBLE:
264 case internal::WireFormatLite::CPPTYPE_BOOL:
265 return true;
266 case internal::WireFormatLite::CPPTYPE_STRING:
267 return false;
268 default:
269 return false;
270 }
271 }
272
273 // Helper for the code that emits the SharedCtor() method.
274 bool CanConstructByZeroing(const FieldDescriptor* field,
275 const Options& options) {
276 bool ret = CanInitializeByZeroing(field);
277
278 // Non-repeated, non-lazy message fields are simply raw pointers, so we can
279 // use memset to initialize these in SharedCtor. We cannot use this in
280 // Clear, as we need to potentially delete the existing value.
281 ret = ret ||
282 (!field->is_repeated() &&
283 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
284 return ret;
285 }
286
230 // Reorder 'fields' so that if the fields are output into a c++ class in the new 287 // Reorder 'fields' so that if the fields are output into a c++ class in the new
231 // order, the alignment padding is minimized. We try to do this while keeping 288 // order, fields of similiar family (see below) are together and within each
232 // each field as close as possible to its original position so that we don't 289 // family, alignment padding is minimized.
233 // reduce cache locality much for function that access each field in order. 290 //
234 void OptimizePadding(vector<const FieldDescriptor*>* fields) { 291 // We try to do this while keeping each field as close as possible to its
292 // declaration order (from the .proto file) so that we don't reduce cache
293 // locality much for function that access each field in order. This is also the
294 // only (weak) signal we have for author intent concerning field layout.
295 //
296 // TODO(ckennelly): If/when we have profiles available for the compiler, use
297 // those rather than respect declaration order.
298 //
299 // We classify each field into a particular "family" of fields, that we perform
300 // the same operation on in our generated functions.
301 //
302 // REPEATED is placed first, as the C++ compiler automatically initializes
303 // these fields in layout order.
304 //
305 // STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
306 // calls ArenaStringPtr::Destroy on each.
307 //
308 //
309 // MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
310 // delete on each. We initialize these fields with a NULL pointer (see
311 // MessageFieldGenerator::GenerateConstructorCode), which allows them to be
312 // memset.
313 //
314 // ZERO_INITIALIZABLE is memset in Clear/SharedCtor
315 //
316 // OTHER these fields are initialized one-by-one.
317 void OptimizePadding(std::vector<const FieldDescriptor*>* fields,
318 const Options& options) {
319 // The sorted numeric order of Family determines the declaration order in the
320 // memory layout.
321 enum Family {
322 REPEATED = 0,
323 STRING = 1,
324 MESSAGE = 2,
325 ZERO_INITIALIZABLE = 4,
326 OTHER = 5,
327 kMaxFamily
328 };
329
235 // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. 330 // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
236 vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8; 331 std::vector<FieldGroup> aligned_to_1[kMaxFamily];
332 std::vector<FieldGroup> aligned_to_4[kMaxFamily];
333 std::vector<FieldGroup> aligned_to_8[kMaxFamily];
237 for (int i = 0; i < fields->size(); ++i) { 334 for (int i = 0; i < fields->size(); ++i) {
238 switch (EstimateAlignmentSize((*fields)[i])) { 335 const FieldDescriptor* field = (*fields)[i];
239 case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; 336
240 case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; 337 Family f = OTHER;
241 case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; 338 if (field->is_repeated()) {
339 f = REPEATED;
340 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
341 f = STRING;
342 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
343 f = MESSAGE;
344
345 } else if (CanInitializeByZeroing(field)) {
346 f = ZERO_INITIALIZABLE;
347 }
348
349 switch (EstimateAlignmentSize(field)) {
350 case 1: aligned_to_1[f].push_back(FieldGroup(i, field)); break;
351 case 4: aligned_to_4[f].push_back(FieldGroup(i, field)); break;
352 case 8: aligned_to_8[f].push_back(FieldGroup(i, field)); break;
242 default: 353 default:
243 GOOGLE_LOG(FATAL) << "Unknown alignment size."; 354 GOOGLE_LOG(FATAL) << "Unknown alignment size.";
244 } 355 }
245 } 356 }
246 357
247 // Now group fields aligned to 1 byte into sets of 4, and treat those like a 358 // For each family, group fields to optimize padding.
248 // single field aligned to 4 bytes. 359 for (int f = 0; f < kMaxFamily; f++) {
249 for (int i = 0; i < aligned_to_1.size(); i += 4) { 360 // Now group fields aligned to 1 byte into sets of 4, and treat those like a
250 FieldGroup field_group; 361 // single field aligned to 4 bytes.
251 for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { 362 for (int i = 0; i < aligned_to_1[f].size(); i += 4) {
252 field_group.Append(aligned_to_1[j]); 363 FieldGroup field_group;
364 for (int j = i; j < aligned_to_1[f].size() && j < i + 4; ++j) {
365 field_group.Append(aligned_to_1[f][j]);
366 }
367 aligned_to_4[f].push_back(field_group);
253 } 368 }
254 aligned_to_4.push_back(field_group); 369 // Sort by preferred location to keep fields as close to their declaration
370 // order as possible. Using stable_sort ensures that the output is
371 // consistent across runs.
372 std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].end());
373
374 // Now group fields aligned to 4 bytes (or the 4-field groups created above)
375 // into pairs, and treat those like a single field aligned to 8 bytes.
376 for (int i = 0; i < aligned_to_4[f].size(); i += 2) {
377 FieldGroup field_group;
378 for (int j = i; j < aligned_to_4[f].size() && j < i + 2; ++j) {
379 field_group.Append(aligned_to_4[f][j]);
380 }
381 if (i == aligned_to_4[f].size() - 1) {
382 if (f == OTHER) {
383 // Move incomplete 4-byte block to the beginning. This is done to
384 // pair with the (possible) leftover blocks from the
385 // ZERO_INITIALIZABLE family.
386 field_group.SetPreferredLocation(-1);
387 } else {
388 // Move incomplete 4-byte block to the end.
389 field_group.SetPreferredLocation(fields->size() + 1);
390 }
391 }
392 aligned_to_8[f].push_back(field_group);
393 }
394 // Sort by preferred location.
395 std::stable_sort(aligned_to_8[f].begin(), aligned_to_8[f].end());
255 } 396 }
256 // Sort by preferred location to keep fields as close to their original
257 // location as possible. Using stable_sort ensures that the output is
258 // consistent across runs.
259 std::stable_sort(aligned_to_4.begin(), aligned_to_4.end());
260
261 // Now group fields aligned to 4 bytes (or the 4-field groups created above)
262 // into pairs, and treat those like a single field aligned to 8 bytes.
263 for (int i = 0; i < aligned_to_4.size(); i += 2) {
264 FieldGroup field_group;
265 for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
266 field_group.Append(aligned_to_4[j]);
267 }
268 if (i == aligned_to_4.size() - 1) {
269 // Move incomplete 4-byte block to the end.
270 field_group.SetPreferredLocation(fields->size() + 1);
271 }
272 aligned_to_8.push_back(field_group);
273 }
274 // Sort by preferred location.
275 std::stable_sort(aligned_to_8.begin(), aligned_to_8.end());
276 397
277 // Now pull out all the FieldDescriptors in order. 398 // Now pull out all the FieldDescriptors in order.
278 fields->clear(); 399 fields->clear();
279 for (int i = 0; i < aligned_to_8.size(); ++i) { 400 for (int f = 0; f < kMaxFamily; ++f) {
280 fields->insert(fields->end(), 401 for (int i = 0; i < aligned_to_8[f].size(); ++i) {
281 aligned_to_8[i].fields().begin(), 402 fields->insert(fields->end(),
282 aligned_to_8[i].fields().end()); 403 aligned_to_8[f][i].fields().begin(),
404 aligned_to_8[f][i].fields().end());
405 }
283 } 406 }
284 } 407 }
285 408
286 string MessageTypeProtoName(const FieldDescriptor* field) { 409 string MessageTypeProtoName(const FieldDescriptor* field) {
287 return field->message_type()->full_name(); 410 return field->message_type()->full_name();
288 } 411 }
289 412
290 // Emits an if-statement with a condition that evaluates to true if |field| is 413 // Emits an if-statement with a condition that evaluates to true if |field| is
291 // considered non-default (will be sent over the wire), for message types 414 // considered non-default (will be sent over the wire), for message types
292 // without true field presence. Should only be called if 415 // without true field presence. Should only be called if
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // In proto1/proto2, every field has a has_$name$() method. 455 // In proto1/proto2, every field has a has_$name$() method.
333 return true; 456 return true;
334 } 457 }
335 // For message types without true field presence, only fields with a message 458 // For message types without true field presence, only fields with a message
336 // type have a has_$name$() method. 459 // type have a has_$name$() method.
337 return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE; 460 return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
338 } 461 }
339 462
340 // Collects map entry message type information. 463 // Collects map entry message type information.
341 void CollectMapInfo(const Descriptor* descriptor, 464 void CollectMapInfo(const Descriptor* descriptor,
342 map<string, string>* variables) { 465 std::map<string, string>* variables) {
343 GOOGLE_CHECK(IsMapEntryMessage(descriptor)); 466 GOOGLE_CHECK(IsMapEntryMessage(descriptor));
344 const FieldDescriptor* key = descriptor->FindFieldByName("key"); 467 const FieldDescriptor* key = descriptor->FindFieldByName("key");
345 const FieldDescriptor* val = descriptor->FindFieldByName("value"); 468 const FieldDescriptor* val = descriptor->FindFieldByName("value");
346 (*variables)["key"] = PrimitiveTypeName(key->cpp_type()); 469 (*variables)["key"] = PrimitiveTypeName(key->cpp_type());
347 switch (val->cpp_type()) { 470 switch (val->cpp_type()) {
348 case FieldDescriptor::CPPTYPE_MESSAGE: 471 case FieldDescriptor::CPPTYPE_MESSAGE:
349 (*variables)["val"] = FieldMessageTypeName(val); 472 (*variables)["val"] = FieldMessageTypeName(val);
350 break; 473 break;
351 case FieldDescriptor::CPPTYPE_ENUM: 474 case FieldDescriptor::CPPTYPE_ENUM:
352 (*variables)["val"] = ClassName(val->enum_type(), true); 475 (*variables)["val"] = ClassName(val->enum_type(), true);
(...skipping 11 matching lines...) Expand all
364 487
365 // Does the given field have a private (internal helper only) has_$name$() 488 // Does the given field have a private (internal helper only) has_$name$()
366 // method? 489 // method?
367 bool HasPrivateHasMethod(const FieldDescriptor* field) { 490 bool HasPrivateHasMethod(const FieldDescriptor* field) {
368 // Only for oneofs in message types with no field presence. has_$name$(), 491 // Only for oneofs in message types with no field presence. has_$name$(),
369 // based on the oneof case, is still useful internally for generated code. 492 // based on the oneof case, is still useful internally for generated code.
370 return (!HasFieldPresence(field->file()) && 493 return (!HasFieldPresence(field->file()) &&
371 field->containing_oneof() != NULL); 494 field->containing_oneof() != NULL);
372 } 495 }
373 496
497
374 } // anonymous namespace 498 } // anonymous namespace
375 499
376 // =================================================================== 500 // ===================================================================
377 501
378 MessageGenerator::MessageGenerator(const Descriptor* descriptor, 502 MessageGenerator::MessageGenerator(const Descriptor* descriptor,
379 const Options& options) 503 const Options& options)
380 : descriptor_(descriptor), 504 : descriptor_(descriptor),
381 classname_(ClassName(descriptor, false)), 505 classname_(ClassName(descriptor, false)),
382 options_(options), 506 options_(options),
383 field_generators_(descriptor, options), 507 field_generators_(descriptor, options),
384 nested_generators_(new google::protobuf::scoped_ptr< 508 nested_generators_(new google::protobuf::scoped_ptr<
385 MessageGenerator>[descriptor->nested_type_count()]), 509 MessageGenerator>[descriptor->nested_type_count()]),
386 enum_generators_( 510 enum_generators_(
387 new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_ count()]), 511 new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_ count()]),
388 extension_generators_(new google::protobuf::scoped_ptr< 512 extension_generators_(new google::protobuf::scoped_ptr<
389 ExtensionGenerator>[descriptor->extension_count()]), 513 ExtensionGenerator>[descriptor->extension_count()]),
390 use_dependent_base_(false) { 514 use_dependent_base_(false) {
391 515
516 // Compute optimized field order to be used for layout and initialization
517 // purposes.
518 for (int i = 0; i < descriptor_->field_count(); i++) {
519 if (!descriptor_->field(i)->containing_oneof()) {
520 optimized_order_.push_back(descriptor_->field(i));
521 }
522 }
523 OptimizePadding(&optimized_order_, options_);
524
525 if (HasFieldPresence(descriptor_->file())) {
526 int has_bit_index = 0;
527 has_bit_indices_.resize(descriptor_->field_count(), -1);
528 for (int i = 0; i < optimized_order_.size(); i++) {
529 const FieldDescriptor* field = optimized_order_[i];
530 // Skip fields that do not have has bits.
531 if (field->is_repeated()) {
532 continue;
533 }
534
535 has_bit_indices_[field->index()] = has_bit_index;
536 has_bit_index++;
537 }
538
539 // Assign fields that do not use has bits to be at the end. This can be
540 // removed once we shrink the has bits we assign.
541 //
542 // TODO(ckennelly): Shrink the has bits for these fields.
543 for (int i = 0; i < descriptor_->field_count(); i++) {
544 const FieldDescriptor* field = descriptor_->field(i);
545 if (has_bit_indices_[field->index()] < 0) {
546 has_bit_indices_[field->index()] = has_bit_index++;
547 }
548 }
549 }
550
392 for (int i = 0; i < descriptor->nested_type_count(); i++) { 551 for (int i = 0; i < descriptor->nested_type_count(); i++) {
393 nested_generators_[i].reset( 552 nested_generators_[i].reset(
394 new MessageGenerator(descriptor->nested_type(i), options)); 553 new MessageGenerator(descriptor->nested_type(i), options));
395 } 554 }
396 555
397 for (int i = 0; i < descriptor->enum_type_count(); i++) { 556 for (int i = 0; i < descriptor->enum_type_count(); i++) {
398 enum_generators_[i].reset( 557 enum_generators_[i].reset(
399 new EnumGenerator(descriptor->enum_type(i), options)); 558 new EnumGenerator(descriptor->enum_type(i), options));
400 } 559 }
401 560
(...skipping 12 matching lines...) Expand all
414 } 573 }
415 } 574 }
416 if (options.proto_h && descriptor->oneof_decl_count() > 0) { 575 if (options.proto_h && descriptor->oneof_decl_count() > 0) {
417 // Always make oneofs dependent. 576 // Always make oneofs dependent.
418 use_dependent_base_ = true; 577 use_dependent_base_ = true;
419 } 578 }
420 } 579 }
421 580
422 MessageGenerator::~MessageGenerator() {} 581 MessageGenerator::~MessageGenerator() {}
423 582
424 void MessageGenerator:: 583 size_t MessageGenerator::HasBitsSize() const {
425 FillMessageForwardDeclarations(map<string, const Descriptor*>* class_names) { 584 // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
426 (*class_names)[classname_] = descriptor_; 585 size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
586 if (descriptor_->field_count() == 0) {
587 // Zero-size arrays aren't technically allowed, and MSVC in particular
588 // doesn't like them. We still need to declare these arrays to make
589 // other code compile. Since this is an uncommon case, we'll just declare
590 // them with size 1 and waste some space. Oh well.
591 sizeof_has_bits = 4;
592 }
427 593
594 return sizeof_has_bits;
595 }
596
597 void MessageGenerator::Flatten(std::vector<MessageGenerator*>* list) {
428 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 598 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
429 // map entry message doesn't need forward declaration. Since map entry 599 nested_generators_[i]->Flatten(list);
430 // message cannot be a top level class, we just need to avoid calling 600 }
431 // GenerateForwardDeclaration here. 601 list->push_back(this);
432 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; 602 }
433 nested_generators_[i]->FillMessageForwardDeclarations(class_names); 603
604 void MessageGenerator::AddGenerators(
605 std::vector<EnumGenerator*>* enum_generators,
606 std::vector<ExtensionGenerator*>* extension_generators) {
607 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
608 enum_generators->push_back(enum_generators_[i].get());
609 }
610 for (int i = 0; i < descriptor_->extension_count(); i++) {
611 extension_generators->push_back(extension_generators_[i].get());
434 } 612 }
435 } 613 }
436 614
437 void MessageGenerator:: 615 void MessageGenerator::FillMessageForwardDeclarations(
438 FillEnumForwardDeclarations(map<string, const EnumDescriptor*>* enum_names) { 616 std::map<string, const Descriptor*>* class_names) {
439 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 617 if (IsMapEntryMessage(descriptor_)) return;
440 nested_generators_[i]->FillEnumForwardDeclarations(enum_names); 618 (*class_names)[classname_] = descriptor_;
441 }
442 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
443 enum_generators_[i]->FillForwardDeclaration(enum_names);
444 }
445 } 619 }
446 620
447 void MessageGenerator:: 621 void MessageGenerator::
448 GenerateEnumDefinitions(io::Printer* printer) {
449 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
450 nested_generators_[i]->GenerateEnumDefinitions(printer);
451 }
452
453 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
454 enum_generators_[i]->GenerateDefinition(printer);
455 }
456 }
457
458 void MessageGenerator::
459 GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
460 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
461 nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
462 }
463 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
464 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
465 }
466 }
467
468 void MessageGenerator::
469 GenerateDependentFieldAccessorDeclarations(io::Printer* printer) { 622 GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
470 for (int i = 0; i < descriptor_->field_count(); i++) { 623 for (int i = 0; i < descriptor_->field_count(); i++) {
471 const FieldDescriptor* field = descriptor_->field(i); 624 const FieldDescriptor* field = descriptor_->field(i);
472 625
473 PrintFieldComment(printer, field); 626 PrintFieldComment(printer, field);
474 627
475 map<string, string> vars; 628 std::map<string, string> vars;
476 SetCommonFieldVariables(field, &vars, options_); 629 SetCommonFieldVariables(field, &vars, options_);
477 630
478 if (use_dependent_base_ && IsFieldDependent(field)) { 631 if (use_dependent_base_ && IsFieldDependent(field)) {
479 // If the message is dependent, the inline clear_*() method will need 632 // If the message is dependent, the inline clear_*() method will need
480 // to delete the message type, so it must be in the dependent base 633 // to delete the message type, so it must be in the dependent base
481 // class. (See also GenerateFieldAccessorDeclarations.) 634 // class. (See also GenerateFieldAccessorDeclarations.)
482 printer->Print(vars, "$deprecated_attr$void clear_$name$();\n"); 635 printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
483 } 636 }
484 // Generate type-specific accessor declarations. 637 // Generate type-specific accessor declarations.
485 field_generators_.get(field).GenerateDependentAccessorDeclarations(printer); 638 field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
486 printer->Print("\n"); 639 printer->Print("\n");
487 } 640 }
488 } 641 }
489 642
490 void MessageGenerator:: 643 void MessageGenerator::
491 GenerateFieldAccessorDeclarations(io::Printer* printer) { 644 GenerateFieldAccessorDeclarations(io::Printer* printer) {
492 for (int i = 0; i < descriptor_->field_count(); i++) { 645 for (int i = 0; i < descriptor_->field_count(); i++) {
493 const FieldDescriptor* field = descriptor_->field(i); 646 const FieldDescriptor* field = descriptor_->field(i);
494 647
495 PrintFieldComment(printer, field); 648 PrintFieldComment(printer, field);
496 649
497 map<string, string> vars; 650 std::map<string, string> vars;
498 SetCommonFieldVariables(field, &vars, options_); 651 SetCommonFieldVariables(field, &vars, options_);
499 vars["constant_name"] = FieldConstantName(field); 652 vars["constant_name"] = FieldConstantName(field);
500 653
501 bool dependent_field = use_dependent_base_ && IsFieldDependent(field); 654 bool dependent_field = use_dependent_base_ && IsFieldDependent(field);
502 if (dependent_field && 655 if (dependent_field &&
503 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 656 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
504 !field->is_map()) { 657 !field->is_map()) {
505 // If this field is dependent, the dependent base class determines 658 // If this field is dependent, the dependent base class determines
506 // the message type from the derived class (which is a template 659 // the message type from the derived class (which is a template
507 // parameter). This typedef is for that: 660 // parameter). This typedef is for that:
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 void MessageGenerator:: 712 void MessageGenerator::
560 GenerateDependentFieldAccessorDefinitions(io::Printer* printer) { 713 GenerateDependentFieldAccessorDefinitions(io::Printer* printer) {
561 if (!use_dependent_base_) return; 714 if (!use_dependent_base_) return;
562 715
563 printer->Print("// $classname$\n\n", "classname", 716 printer->Print("// $classname$\n\n", "classname",
564 DependentBaseClassTemplateName(descriptor_)); 717 DependentBaseClassTemplateName(descriptor_));
565 718
566 for (int i = 0; i < descriptor_->field_count(); i++) { 719 for (int i = 0; i < descriptor_->field_count(); i++) {
567 const FieldDescriptor* field = descriptor_->field(i); 720 const FieldDescriptor* field = descriptor_->field(i);
568 721
722 if (field->options().weak()) continue;
723
569 PrintFieldComment(printer, field); 724 PrintFieldComment(printer, field);
570 725
571 // These functions are not really dependent: they are part of the 726 // These functions are not really dependent: they are part of the
572 // (non-dependent) derived class. However, they need to live outside 727 // (non-dependent) derived class. However, they need to live outside
573 // any #ifdef guards, so we treat them as if they were dependent. 728 // any #ifdef guards, so we treat them as if they were dependent.
574 // 729 //
575 // See the comment in FileGenerator::GenerateInlineFunctionDefinitions 730 // See the comment in FileGenerator::GenerateInlineFunctionDefinitions
576 // for a more complete explanation. 731 // for a more complete explanation.
577 if (use_dependent_base_ && IsFieldDependent(field)) { 732 if (use_dependent_base_ && IsFieldDependent(field)) {
578 map<string, string> vars; 733 std::map<string, string> vars;
579 SetCommonFieldVariables(field, &vars, options_); 734 SetCommonFieldVariables(field, &vars, options_);
580 vars["inline"] = "inline "; 735 vars["inline"] = "inline ";
581 if (field->containing_oneof()) { 736 if (field->containing_oneof()) {
582 vars["field_name"] = UnderscoresToCamelCase(field->name(), true); 737 vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
583 vars["oneof_name"] = field->containing_oneof()->name(); 738 vars["oneof_name"] = field->containing_oneof()->name();
584 vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); 739 vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
585 GenerateOneofMemberHasBits(field, vars, printer); 740 GenerateOneofMemberHasBits(field, vars, printer);
586 } else if (!field->is_repeated()) { 741 } else if (!field->is_repeated()) {
587 // There will be no header guard, so this always has to be inline. 742 // There will be no header guard, so this always has to be inline.
588 GenerateSingularFieldHasBits(field, vars, printer); 743 GenerateSingularFieldHasBits(field, vars, printer);
(...skipping 16 matching lines...) Expand all
605 } 760 }
606 761
607 // Generate has_$name$() and clear_has_$name$() functions for oneofs 762 // Generate has_$name$() and clear_has_$name$() functions for oneofs
608 // Similar to other has-bits, these must always be in the header if we 763 // Similar to other has-bits, these must always be in the header if we
609 // are using a dependent base class. 764 // are using a dependent base class.
610 GenerateOneofHasBits(printer, true /* is_inline */); 765 GenerateOneofHasBits(printer, true /* is_inline */);
611 } 766 }
612 767
613 void MessageGenerator:: 768 void MessageGenerator::
614 GenerateSingularFieldHasBits(const FieldDescriptor* field, 769 GenerateSingularFieldHasBits(const FieldDescriptor* field,
615 map<string, string> vars, 770 std::map<string, string> vars,
616 io::Printer* printer) { 771 io::Printer* printer) {
617 if (HasFieldPresence(descriptor_->file())) { 772 if (HasFieldPresence(descriptor_->file())) {
618 // N.B.: without field presence, we do not use has-bits or generate 773 // N.B.: without field presence, we do not use has-bits or generate
619 // has_$name$() methods. 774 // has_$name$() methods.
620 vars["has_array_index"] = SimpleItoa(field->index() / 32); 775 int has_bit_index = has_bit_indices_[field->index()];
621 vars["has_mask"] = StrCat(strings::Hex(1u << (field->index() % 32), 776 GOOGLE_CHECK_GE(has_bit_index, 0);
777
778 vars["has_array_index"] = SimpleItoa(has_bit_index / 32);
779 vars["has_mask"] = StrCat(strings::Hex(1u << (has_bit_index % 32),
622 strings::ZERO_PAD_8)); 780 strings::ZERO_PAD_8));
623 printer->Print(vars, 781 printer->Print(vars,
624 "$inline$" 782 "$inline$"
625 "bool $classname$::has_$name$() const {\n" 783 "bool $classname$::has_$name$() const {\n"
626 " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" 784 " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
627 "}\n" 785 "}\n"
628 "$inline$" 786 "$inline$"
629 "void $classname$::set_has_$name$() {\n" 787 "void $classname$::set_has_$name$() {\n"
630 " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" 788 " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
631 "}\n" 789 "}\n"
632 "$inline$" 790 "$inline$"
633 "void $classname$::clear_has_$name$() {\n" 791 "void $classname$::clear_has_$name$() {\n"
634 " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" 792 " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
635 "}\n"); 793 "}\n");
636 } else { 794 } else {
637 // Message fields have a has_$name$() method. 795 // Message fields have a has_$name$() method.
638 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 796 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
639 bool is_lazy = false; 797 bool is_lazy = false;
640 if (is_lazy) { 798 if (is_lazy) {
641 printer->Print(vars, 799 printer->Print(vars,
642 "$inline$" 800 "$inline$"
643 "bool $classname$::has_$name$() const {\n" 801 "bool $classname$::has_$name$() const {\n"
644 " return !$name$_.IsCleared();\n" 802 " return !$name$_.IsCleared();\n"
645 "}\n"); 803 "}\n");
646 } else { 804 } else {
647 printer->Print(vars, 805 printer->Print(
648 "$inline$" 806 vars,
649 "bool $classname$::has_$name$() const {\n" 807 "$inline$"
650 " return !_is_default_instance_ && $name$_ != NULL;\n" 808 "bool $classname$::has_$name$() const {\n"
651 "}\n"); 809 " return this != internal_default_instance() && $name$_ != NULL;\n"
810 "}\n");
652 } 811 }
653 } 812 }
654 } 813 }
655 } 814 }
656 815
657 void MessageGenerator:: 816 void MessageGenerator::
658 GenerateOneofHasBits(io::Printer* printer, bool is_inline) { 817 GenerateOneofHasBits(io::Printer* printer, bool is_inline) {
659 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 818 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
660 map<string, string> vars; 819 std::map<string, string> vars;
661 vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); 820 vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
662 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); 821 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
663 vars["cap_oneof_name"] = 822 vars["cap_oneof_name"] =
664 ToUpper(descriptor_->oneof_decl(i)->name()); 823 ToUpper(descriptor_->oneof_decl(i)->name());
665 vars["classname"] = classname_; 824 vars["classname"] = classname_;
666 vars["inline"] = (is_inline ? "inline " : ""); 825 vars["inline"] = (is_inline ? "inline " : "");
667 printer->Print( 826 printer->Print(
668 vars, 827 vars,
669 "$inline$" 828 "$inline$"
670 "bool $classname$::has_$oneof_name$() const {\n" 829 "bool $classname$::has_$oneof_name$() const {\n"
671 " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" 830 " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
672 "}\n" 831 "}\n"
673 "$inline$" 832 "$inline$"
674 "void $classname$::clear_has_$oneof_name$() {\n" 833 "void $classname$::clear_has_$oneof_name$() {\n"
675 " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" 834 " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
676 "}\n"); 835 "}\n");
677 } 836 }
678 } 837 }
679 838
680 void MessageGenerator:: 839 void MessageGenerator::
681 GenerateOneofMemberHasBits(const FieldDescriptor* field, 840 GenerateOneofMemberHasBits(const FieldDescriptor* field,
682 const map<string, string>& vars, 841 const std::map<string, string>& vars,
683 io::Printer* printer) { 842 io::Printer* printer) {
684 // Singular field in a oneof 843 // Singular field in a oneof
685 // N.B.: Without field presence, we do not use has-bits or generate 844 // N.B.: Without field presence, we do not use has-bits or generate
686 // has_$name$() methods, but oneofs still have set_has_$name$(). 845 // has_$name$() methods, but oneofs still have set_has_$name$().
687 // Oneofs also have has_$name$() but only as a private helper 846 // Oneofs also have has_$name$() but only as a private helper
688 // method, so that generated code is slightly cleaner (vs. comparing 847 // method, so that generated code is slightly cleaner (vs. comparing
689 // _oneof_case_[index] against a constant everywhere). 848 // _oneof_case_[index] against a constant everywhere).
690 printer->Print(vars, 849 printer->Print(vars,
691 "$inline$" 850 "$inline$"
692 "bool $classname$::has_$name$() const {\n" 851 "bool $classname$::has_$name$() const {\n"
693 " return $oneof_name$_case() == k$field_name$;\n" 852 " return $oneof_name$_case() == k$field_name$;\n"
694 "}\n"); 853 "}\n");
695 printer->Print(vars, 854 printer->Print(vars,
696 "$inline$" 855 "$inline$"
697 "void $classname$::set_has_$name$() {\n" 856 "void $classname$::set_has_$name$() {\n"
698 " _oneof_case_[$oneof_index$] = k$field_name$;\n" 857 " _oneof_case_[$oneof_index$] = k$field_name$;\n"
699 "}\n"); 858 "}\n");
700 } 859 }
701 860
702 void MessageGenerator:: 861 void MessageGenerator::
703 GenerateFieldClear(const FieldDescriptor* field, 862 GenerateFieldClear(const FieldDescriptor* field,
704 const map<string, string>& vars, 863 const std::map<string, string>& vars,
705 io::Printer* printer) { 864 io::Printer* printer) {
706 // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and 865 // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and
707 // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is 866 // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is
708 // set by the Generate*Definitions functions.) 867 // set by the Generate*Definitions functions.)
709 printer->Print(vars, 868 printer->Print(vars,
710 "$tmpl$" 869 "$tmpl$"
711 "$inline$" 870 "$inline$"
712 "void $dependent_classname$::clear_$name$() {\n"); 871 "void $dependent_classname$::clear_$name$() {\n");
713 872
714 printer->Indent(); 873 printer->Indent();
(...skipping 27 matching lines...) Expand all
742 901
743 void MessageGenerator:: 902 void MessageGenerator::
744 GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { 903 GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
745 printer->Print("// $classname$\n\n", "classname", classname_); 904 printer->Print("// $classname$\n\n", "classname", classname_);
746 905
747 for (int i = 0; i < descriptor_->field_count(); i++) { 906 for (int i = 0; i < descriptor_->field_count(); i++) {
748 const FieldDescriptor* field = descriptor_->field(i); 907 const FieldDescriptor* field = descriptor_->field(i);
749 908
750 PrintFieldComment(printer, field); 909 PrintFieldComment(printer, field);
751 910
752 map<string, string> vars; 911 std::map<string, string> vars;
753 SetCommonFieldVariables(field, &vars, options_); 912 SetCommonFieldVariables(field, &vars, options_);
754 vars["inline"] = is_inline ? "inline " : ""; 913 vars["inline"] = is_inline ? "inline " : "";
755 if (use_dependent_base_ && IsFieldDependent(field)) { 914 if (use_dependent_base_ && IsFieldDependent(field)) {
756 vars["tmpl"] = "template<class T>\n"; 915 vars["tmpl"] = "template<class T>\n";
757 vars["dependent_classname"] = 916 vars["dependent_classname"] =
758 DependentBaseClassTemplateName(descriptor_) + "<T>"; 917 DependentBaseClassTemplateName(descriptor_) + "<T>";
759 vars["this_message"] = "reinterpret_cast<T*>(this)->"; 918 vars["this_message"] = "reinterpret_cast<T*>(this)->";
760 vars["this_const_message"] = "reinterpret_cast<const T*>(this)->"; 919 vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
761 } else { 920 } else {
762 vars["tmpl"] = ""; 921 vars["tmpl"] = "";
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 } 957 }
799 958
800 if (!use_dependent_base_) { 959 if (!use_dependent_base_) {
801 // Generate has_$name$() and clear_has_$name$() functions for oneofs 960 // Generate has_$name$() and clear_has_$name$() functions for oneofs
802 // If we aren't using a dependent base, they can be with the other functions 961 // If we aren't using a dependent base, they can be with the other functions
803 // that are #ifdef-guarded. 962 // that are #ifdef-guarded.
804 GenerateOneofHasBits(printer, is_inline); 963 GenerateOneofHasBits(printer, is_inline);
805 } 964 }
806 } 965 }
807 966
808 // Helper for the code that emits the Clear() method.
809 static bool CanClearByZeroing(const FieldDescriptor* field) {
810 if (field->is_repeated() || field->is_extension()) return false;
811 switch (field->cpp_type()) {
812 case internal::WireFormatLite::CPPTYPE_ENUM:
813 return field->default_value_enum()->number() == 0;
814 case internal::WireFormatLite::CPPTYPE_INT32:
815 return field->default_value_int32() == 0;
816 case internal::WireFormatLite::CPPTYPE_INT64:
817 return field->default_value_int64() == 0;
818 case internal::WireFormatLite::CPPTYPE_UINT32:
819 return field->default_value_uint32() == 0;
820 case internal::WireFormatLite::CPPTYPE_UINT64:
821 return field->default_value_uint64() == 0;
822 case internal::WireFormatLite::CPPTYPE_FLOAT:
823 return field->default_value_float() == 0;
824 case internal::WireFormatLite::CPPTYPE_DOUBLE:
825 return field->default_value_double() == 0;
826 case internal::WireFormatLite::CPPTYPE_BOOL:
827 return field->default_value_bool() == false;
828 default:
829 return false;
830 }
831 }
832
833 void MessageGenerator:: 967 void MessageGenerator::
834 GenerateDependentBaseClassDefinition(io::Printer* printer) { 968 GenerateDependentBaseClassDefinition(io::Printer* printer) {
835 if (!use_dependent_base_) { 969 if (!use_dependent_base_) {
836 return; 970 return;
837 } 971 }
838 972
839 map<string, string> vars; 973 std::map<string, string> vars;
840 vars["classname"] = DependentBaseClassTemplateName(descriptor_); 974 vars["classname"] = DependentBaseClassTemplateName(descriptor_);
975 vars["full_name"] = descriptor_->full_name();
841 vars["superclass"] = SuperClassName(descriptor_, options_); 976 vars["superclass"] = SuperClassName(descriptor_, options_);
842 977
843 printer->Print(vars, 978 printer->Print(vars,
844 "template <class T>\n" 979 "template <class T>\n"
845 "class $classname$ : public $superclass$ {\n" 980 "class $classname$ : public $superclass$ "
981 "/* @@protoc_insertion_point(dep_base_class_definition:$full_name$) */ {\n"
846 " public:\n"); 982 " public:\n");
847 printer->Indent(); 983 printer->Indent();
848 984
849 printer->Print(vars, 985 printer->Print(vars,
850 "$classname$() {}\n" 986 "$classname$() {}\n"
851 "virtual ~$classname$() {}\n" 987 "virtual ~$classname$() {}\n"
852 "\n"); 988 "\n");
853 989
854 // Generate dependent accessor methods for all fields. 990 // Generate dependent accessor methods for all fields.
855 GenerateDependentFieldAccessorDeclarations(printer); 991 GenerateDependentFieldAccessorDeclarations(printer);
856 992
857 printer->Outdent(); 993 printer->Outdent();
858 printer->Print("};\n"); 994 printer->Print("};\n");
859 } 995 }
860 996
861 void MessageGenerator:: 997 void MessageGenerator::
862 GenerateClassDefinition(io::Printer* printer) { 998 GenerateClassDefinition(io::Printer* printer) {
863 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 999 if (IsMapEntryMessage(descriptor_)) return;
864 // map entry message doesn't need class definition. Since map entry message
865 // cannot be a top level class, we just need to avoid calling
866 // GenerateClassDefinition here.
867 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
868 nested_generators_[i]->GenerateClassDefinition(printer);
869 printer->Print("\n");
870 printer->Print(kThinSeparator);
871 printer->Print("\n");
872 }
873
874 if (use_dependent_base_) { 1000 if (use_dependent_base_) {
875 GenerateDependentBaseClassDefinition(printer); 1001 GenerateDependentBaseClassDefinition(printer);
876 printer->Print("\n"); 1002 printer->Print("\n");
877 } 1003 }
878 1004
879 map<string, string> vars; 1005 std::map<string, string> vars;
880 vars["classname"] = classname_; 1006 vars["classname"] = classname_;
1007 vars["full_name"] = descriptor_->full_name();
881 vars["field_count"] = SimpleItoa(descriptor_->field_count()); 1008 vars["field_count"] = SimpleItoa(descriptor_->field_count());
882 vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count()); 1009 vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
883 if (options_.dllexport_decl.empty()) { 1010 if (options_.dllexport_decl.empty()) {
884 vars["dllexport"] = ""; 1011 vars["dllexport"] = "";
885 } else { 1012 } else {
886 vars["dllexport"] = options_.dllexport_decl + " "; 1013 vars["dllexport"] = options_.dllexport_decl + " ";
887 } 1014 }
888 if (use_dependent_base_) { 1015 if (use_dependent_base_) {
889 vars["superclass"] = 1016 vars["superclass"] =
890 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; 1017 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
891 } else { 1018 } else {
892 vars["superclass"] = SuperClassName(descriptor_, options_); 1019 vars["superclass"] = SuperClassName(descriptor_, options_);
893 } 1020 }
894 printer->Print(vars, 1021 printer->Print(vars,
895 "class $dllexport$$classname$ : public $superclass$ {\n"); 1022 "class $dllexport$$classname$ : public $superclass$ "
1023 "/* @@protoc_insertion_point(class_definition:$full_name$) */ "
1024 "{\n");
896 printer->Annotate("classname", descriptor_); 1025 printer->Annotate("classname", descriptor_);
897 if (use_dependent_base_) { 1026 if (use_dependent_base_) {
898 printer->Print(vars, " friend class $superclass$;\n"); 1027 printer->Print(vars, " friend class $superclass$;\n");
899 } 1028 }
900 printer->Print(" public:\n"); 1029 printer->Print(" public:\n");
901 printer->Indent(); 1030 printer->Indent();
902 1031
903 printer->Print(vars, 1032 printer->Print(vars,
904 "$classname$();\n" 1033 "$classname$();\n"
905 "virtual ~$classname$();\n" 1034 "virtual ~$classname$();\n"
906 "\n" 1035 "\n"
907 "$classname$(const $classname$& from);\n" 1036 "$classname$(const $classname$& from);\n"
908 "\n" 1037 "\n"
909 "inline $classname$& operator=(const $classname$& from) {\n" 1038 "inline $classname$& operator=(const $classname$& from) {\n"
910 " CopyFrom(from);\n" 1039 " CopyFrom(from);\n"
911 " return *this;\n" 1040 " return *this;\n"
912 "}\n" 1041 "}\n"
913 "\n"); 1042 "\n");
914 1043
915 if (PreserveUnknownFields(descriptor_)) { 1044 if (PreserveUnknownFields(descriptor_)) {
916 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 1045 string type = UseUnknownFieldSet(descriptor_->file(), options_)
917 printer->Print( 1046 ? "::google::protobuf::UnknownFieldSet"
918 "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() cons t {\n" 1047 : "::std::string";
919 " return _internal_metadata_.unknown_fields();\n" 1048 printer->Print(
920 "}\n" 1049 "inline const $type$& unknown_fields() const {\n"
921 "\n" 1050 " return _internal_metadata_.unknown_fields();\n"
922 "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\ n" 1051 "}\n"
923 " return _internal_metadata_.mutable_unknown_fields();\n" 1052 "\n"
924 "}\n" 1053 "inline $type$* mutable_unknown_fields() {\n"
925 "\n"); 1054 " return _internal_metadata_.mutable_unknown_fields();\n"
926 } else { 1055 "}\n"
927 if (SupportsArenas(descriptor_)) { 1056 "\n",
928 printer->Print( 1057 "type", type );
929 "inline const ::std::string& unknown_fields() const {\n"
930 " return _unknown_fields_.Get(\n"
931 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\ n"
932 "}\n"
933 "\n"
934 "inline ::std::string* mutable_unknown_fields() {\n"
935 " return _unknown_fields_.Mutable(\n"
936 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n "
937 " GetArenaNoVirtual());\n"
938 "}\n"
939 "\n");
940 } else {
941 printer->Print(
942 "inline const ::std::string& unknown_fields() const {\n"
943 " return _unknown_fields_.GetNoArena(\n"
944 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\ n"
945 "}\n"
946 "\n"
947 "inline ::std::string* mutable_unknown_fields() {\n"
948 " return _unknown_fields_.MutableNoArena(\n"
949 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\ n"
950 "}\n"
951 "\n");
952 }
953 }
954 } 1058 }
955 1059
956 // N.B.: We exclude GetArena() when arena support is disabled, falling back on 1060 // N.B.: We exclude GetArena() when arena support is disabled, falling back on
957 // MessageLite's implementation which returns NULL rather than generating our 1061 // MessageLite's implementation which returns NULL rather than generating our
958 // own method which returns NULL, in order to reduce code size. 1062 // own method which returns NULL, in order to reduce code size.
959 if (SupportsArenas(descriptor_)) { 1063 if (SupportsArenas(descriptor_)) {
960 // virtual method version of GetArenaNoVirtual(), required for generic dispa tch given a 1064 // virtual method version of GetArenaNoVirtual(), required for generic dispa tch given a
961 // MessageLite* (e.g., in RepeatedField::AddAllocated()). 1065 // MessageLite* (e.g., in RepeatedField::AddAllocated()).
962 printer->Print( 1066 printer->Print(
963 "inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoV irtual(); }\n" 1067 "inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL {\n"
964 "inline void* GetMaybeArenaPointer() const {\n" 1068 " return GetArenaNoVirtual();\n"
1069 "}\n"
1070 "inline void* GetMaybeArenaPointer() const PROTOBUF_FINAL {\n"
965 " return MaybeArenaPtr();\n" 1071 " return MaybeArenaPtr();\n"
966 "}\n"); 1072 "}\n");
967 } 1073 }
968 1074
969 // Only generate this member if it's not disabled. 1075 // Only generate this member if it's not disabled.
970 if (HasDescriptorMethods(descriptor_->file(), options_) && 1076 if (HasDescriptorMethods(descriptor_->file(), options_) &&
971 !descriptor_->options().no_standard_descriptor_accessor()) { 1077 !descriptor_->options().no_standard_descriptor_accessor()) {
972 printer->Print(vars, 1078 printer->Print(vars,
973 "static const ::google::protobuf::Descriptor* descriptor();\n"); 1079 "static const ::google::protobuf::Descriptor* descriptor();\n");
974 } 1080 }
(...skipping 22 matching lines...) Expand all
997 printer->Print( 1103 printer->Print(
998 "$cap_oneof_name$_NOT_SET = 0,\n", 1104 "$cap_oneof_name$_NOT_SET = 0,\n",
999 "cap_oneof_name", 1105 "cap_oneof_name",
1000 ToUpper(descriptor_->oneof_decl(i)->name())); 1106 ToUpper(descriptor_->oneof_decl(i)->name()));
1001 printer->Outdent(); 1107 printer->Outdent();
1002 printer->Print( 1108 printer->Print(
1003 "};\n" 1109 "};\n"
1004 "\n"); 1110 "\n");
1005 } 1111 }
1006 1112
1007 if (!StaticInitializersForced(descriptor_->file(), options_)) { 1113 // TODO(gerbens) make this private, while still granting other protos access.
1008 printer->Print(vars, 1114 printer->Print(
1009 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" 1115 vars,
1010 "// Returns the internal default instance pointer. This function can\n"
1011 "// return NULL thus should not be used by the user. This is intended\n"
1012 "// for Protobuf internal code. Please use default_instance() declared\n"
1013 "// above instead.\n"
1014 "static inline const $classname$* internal_default_instance() {\n" 1116 "static inline const $classname$* internal_default_instance() {\n"
1015 " return default_instance_;\n" 1117 " return reinterpret_cast<const $classname$*>(\n"
1118 " &_$classname$_default_instance_);\n"
1016 "}\n" 1119 "}\n"
1017 "#endif\n"
1018 "\n"); 1120 "\n");
1019 }
1020 1121
1021 1122
1022 if (SupportsArenas(descriptor_)) { 1123 if (SupportsArenas(descriptor_)) {
1023 printer->Print(vars, 1124 printer->Print(vars,
1024 "void UnsafeArenaSwap($classname$* other);\n"); 1125 "void UnsafeArenaSwap($classname$* other);\n");
1025 } 1126 }
1026 1127
1027 if (IsAnyMessage(descriptor_)) { 1128 if (IsAnyMessage(descriptor_)) {
1028 printer->Print(vars, 1129 printer->Print(vars,
1029 "// implements Any -----------------------------------------------\n" 1130 "// implements Any -----------------------------------------------\n"
1030 "\n" 1131 "\n"
1031 "void PackFrom(const ::google::protobuf::Message& message);\n" 1132 "void PackFrom(const ::google::protobuf::Message& message);\n"
1032 "void PackFrom(const ::google::protobuf::Message& message,\n" 1133 "void PackFrom(const ::google::protobuf::Message& message,\n"
1033 " const ::std::string& type_url_prefix);\n" 1134 " const ::std::string& type_url_prefix);\n"
1034 "bool UnpackTo(::google::protobuf::Message* message) const;\n" 1135 "bool UnpackTo(::google::protobuf::Message* message) const;\n"
1035 "template<typename T> bool Is() const {\n" 1136 "template<typename T> bool Is() const {\n"
1036 " return _any_metadata_.Is<T>();\n" 1137 " return _any_metadata_.Is<T>();\n"
1037 "}\n" 1138 "}\n"
1038 "\n"); 1139 "\n");
1039 } 1140 }
1040 1141
1142 vars["new_final"] = " PROTOBUF_FINAL";
1143
1041 printer->Print(vars, 1144 printer->Print(vars,
1042 "GOOGLE_ATTRIBUTE_NOINLINE void Swap($classname$* other);\n" 1145 "GOOGLE_ATTRIBUTE_NOINLINE void Swap($classname$* other);\n"
1043 "\n" 1146 "\n"
1044 "// implements Message ----------------------------------------------\n" 1147 "// implements Message ----------------------------------------------\n"
1045 "\n" 1148 "\n"
1046 "inline $classname$* New() const { return New(NULL); }\n" 1149 "inline $classname$* New() const$new_final$ { return New(NULL); }\n"
1047 "\n" 1150 "\n"
1048 "$classname$* New(::google::protobuf::Arena* arena) const;\n"); 1151 "$classname$* New(::google::protobuf::Arena* arena) const$new_final$;\n");
1152
1153 // For instances that derive from Message (rather than MessageLite), some
1154 // methods are virtual and should be marked as final.
1155 string use_final = HasDescriptorMethods(descriptor_->file(), options_) ?
1156 " PROTOBUF_FINAL" : "";
1049 1157
1050 if (HasGeneratedMethods(descriptor_->file(), options_)) { 1158 if (HasGeneratedMethods(descriptor_->file(), options_)) {
1051 if (HasDescriptorMethods(descriptor_->file(), options_)) { 1159 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1052 printer->Print(vars, 1160 printer->Print(vars,
1053 "void CopyFrom(const ::google::protobuf::Message& from);\n" 1161 "void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;\ n"
1054 "void MergeFrom(const ::google::protobuf::Message& from);\n"); 1162 "void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; \n");
1055 } else { 1163 } else {
1056 printer->Print(vars, 1164 printer->Print(vars,
1057 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from) ;\n"); 1165 "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from) \n"
1166 " PROTOBUF_FINAL;\n");
1058 } 1167 }
1059 1168
1060 printer->Print(vars, 1169 vars["clear_final"] = " PROTOBUF_FINAL";
1061 "void CopyFrom(const $classname$& from);\n" 1170 vars["is_initialized_final"] = " PROTOBUF_FINAL";
1062 "void MergeFrom(const $classname$& from);\n" 1171 vars["merge_partial_final"] = " PROTOBUF_FINAL";
1063 "void Clear();\n" 1172
1064 "bool IsInitialized() const;\n" 1173 printer->Print(
1065 "\n" 1174 vars,
1066 "int ByteSize() const;\n" 1175 "void CopyFrom(const $classname$& from);\n"
1067 "bool MergePartialFromCodedStream(\n" 1176 "void MergeFrom(const $classname$& from);\n"
1068 " ::google::protobuf::io::CodedInputStream* input);\n" 1177 "void Clear()$clear_final$;\n"
1069 "void SerializeWithCachedSizes(\n" 1178 "bool IsInitialized() const$is_initialized_final$;\n"
1070 " ::google::protobuf::io::CodedOutputStream* output) const;\n"); 1179 "\n"
1180 "size_t ByteSizeLong() const PROTOBUF_FINAL;\n"
1181 "bool MergePartialFromCodedStream(\n"
1182 " ::google::protobuf::io::CodedInputStream* input)$merge_partial_fina l$;\n"
1183 "void SerializeWithCachedSizes(\n"
1184 " ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_F INAL;\n");
1071 // DiscardUnknownFields() is implemented in message.cc using reflections. We 1185 // DiscardUnknownFields() is implemented in message.cc using reflections. We
1072 // need to implement this function in generated code for messages. 1186 // need to implement this function in generated code for messages.
1073 if (!UseUnknownFieldSet(descriptor_->file(), options_)) { 1187 if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
1074 printer->Print( 1188 printer->Print(
1075 "void DiscardUnknownFields();\n"); 1189 "void DiscardUnknownFields()$final$;\n",
1190 "final", use_final);
1076 } 1191 }
1077 if (HasFastArraySerialization(descriptor_->file(), options_)) { 1192 if (HasFastArraySerialization(descriptor_->file(), options_)) {
1078 printer->Print( 1193 printer->Print(
1079 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::pr otobuf::uint8* output) const;\n"); 1194 "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
1080 } 1195 " bool deterministic, ::google::protobuf::uint8* target) const PROTOB UF_FINAL;\n"
1081 } 1196 "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::pr otobuf::uint8* output)\n"
1082 1197 " const PROTOBUF_FINAL {\n"
1083 // Check all FieldDescriptors including those in oneofs to estimate 1198 " return InternalSerializeWithCachedSizesToArray(false, output);\n"
1084 // whether ::std::string is likely to be used, and depending on that 1199 "}\n");
1085 // estimate, set uses_string_ to true or false. That contols
1086 // whether to force initialization of empty_string_ in SharedCtor().
1087 // It's often advantageous to do so to keep "is empty_string_
1088 // inited?" code from appearing all over the place.
1089 vector<const FieldDescriptor*> descriptors;
1090 for (int i = 0; i < descriptor_->field_count(); i++) {
1091 descriptors.push_back(descriptor_->field(i));
1092 }
1093 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1094 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1095 descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
1096 }
1097 }
1098 uses_string_ = false;
1099 if (PreserveUnknownFields(descriptor_) &&
1100 !UseUnknownFieldSet(descriptor_->file(), options_)) {
1101 uses_string_ = true;
1102 }
1103 for (int i = 0; i < descriptors.size(); i++) {
1104 const FieldDescriptor* field = descriptors[i];
1105 if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
1106 switch (field->options().ctype()) {
1107 default: uses_string_ = true; break;
1108 }
1109 } 1200 }
1110 } 1201 }
1111 1202
1112 printer->Print( 1203 printer->Print(
1113 "int GetCachedSize() const { return _cached_size_; }\n" 1204 "int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }\n"
1114 "private:\n" 1205 "private:\n"
1115 "void SharedCtor();\n" 1206 "void SharedCtor();\n"
1116 "void SharedDtor();\n" 1207 "void SharedDtor();\n"
1117 "void SetCachedSize(int size) const;\n" 1208 "void SetCachedSize(int size) const$final$;\n"
1118 "void InternalSwap($classname$* other);\n", 1209 "void InternalSwap($classname$* other);\n",
1119 "classname", classname_); 1210 "classname", classname_,
1211 "final", use_final);
1120 if (SupportsArenas(descriptor_)) { 1212 if (SupportsArenas(descriptor_)) {
1121 printer->Print( 1213 printer->Print(
1122 "protected:\n" 1214 "protected:\n"
1123 "explicit $classname$(::google::protobuf::Arena* arena);\n" 1215 "explicit $classname$(::google::protobuf::Arena* arena);\n"
1124 "private:\n" 1216 "private:\n"
1125 "static void ArenaDtor(void* object);\n" 1217 "static void ArenaDtor(void* object);\n"
1126 "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n", 1218 "inline void RegisterArenaDtor(::google::protobuf::Arena* arena);\n",
1127 "classname", classname_); 1219 "classname", classname_);
1128 } 1220 }
1129 1221
1130 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 1222 if (SupportsArenas(descriptor_)) {
1131 printer->Print( 1223 printer->Print(
1132 "private:\n" 1224 "private:\n"
1133 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n" 1225 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1134 " return _internal_metadata_.arena();\n" 1226 " return _internal_metadata_.arena();\n"
1135 "}\n" 1227 "}\n"
1136 "inline void* MaybeArenaPtr() const {\n" 1228 "inline void* MaybeArenaPtr() const {\n"
1137 " return _internal_metadata_.raw_arena_ptr();\n" 1229 " return _internal_metadata_.raw_arena_ptr();\n"
1138 "}\n" 1230 "}\n");
1139 "public:\n"
1140 "\n");
1141 } else { 1231 } else {
1142 printer->Print( 1232 printer->Print(
1143 "private:\n" 1233 "private:\n"
1144 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n" 1234 "inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
1145 " return _arena_ptr_;\n" 1235 " return NULL;\n"
1146 "}\n" 1236 "}\n"
1147 "inline ::google::protobuf::Arena* MaybeArenaPtr() const {\n" 1237 "inline void* MaybeArenaPtr() const {\n"
1148 " return _arena_ptr_;\n" 1238 " return NULL;\n"
1149 "}\n" 1239 "}\n");
1240 }
1241
1242 printer->Print(
1150 "public:\n" 1243 "public:\n"
1151 "\n"); 1244 "\n");
1245
1246 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1247 printer->Print(
1248 "::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;\n"
1249 "\n");
1250 } else {
1251 printer->Print(
1252 "::std::string GetTypeName() const PROTOBUF_FINAL;\n"
1253 "\n");
1152 } 1254 }
1153 1255
1154 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1155 printer->Print(
1156 "::google::protobuf::Metadata GetMetadata() const;\n"
1157 "\n");
1158 } else {
1159 printer->Print(
1160 "::std::string GetTypeName() const;\n"
1161 "\n");
1162 }
1163
1164 printer->Print( 1256 printer->Print(
1165 "// nested types ----------------------------------------------------\n" 1257 "// nested types ----------------------------------------------------\n"
1166 "\n"); 1258 "\n");
1167 1259
1168 // Import all nested message classes into this class's scope with typedefs. 1260 // Import all nested message classes into this class's scope with typedefs.
1169 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1261 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1170 const Descriptor* nested_type = descriptor_->nested_type(i); 1262 const Descriptor* nested_type = descriptor_->nested_type(i);
1171 if (!IsMapEntryMessage(nested_type)) { 1263 if (!IsMapEntryMessage(nested_type)) {
1172 printer->Print("typedef $nested_full_name$ $nested_name$;\n", 1264 printer->Print("typedef $nested_full_name$ $nested_name$;\n",
1173 "nested_name", nested_type->name(), 1265 "nested_name", nested_type->name(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 printer->Print(" private:\n"); 1300 printer->Print(" private:\n");
1209 printer->Indent(); 1301 printer->Indent();
1210 1302
1211 1303
1212 for (int i = 0; i < descriptor_->field_count(); i++) { 1304 for (int i = 0; i < descriptor_->field_count(); i++) {
1213 if (!descriptor_->field(i)->is_repeated()) { 1305 if (!descriptor_->field(i)->is_repeated()) {
1214 // set_has_***() generated in all proto1/2 code and in oneofs (only) for 1306 // set_has_***() generated in all proto1/2 code and in oneofs (only) for
1215 // messages without true field presence. 1307 // messages without true field presence.
1216 if (HasFieldPresence(descriptor_->file()) || 1308 if (HasFieldPresence(descriptor_->file()) ||
1217 descriptor_->field(i)->containing_oneof()) { 1309 descriptor_->field(i)->containing_oneof()) {
1218 printer->Print( 1310 printer->Print("void set_has_$name$();\n", "name",
1219 "inline void set_has_$name$();\n", 1311 FieldName(descriptor_->field(i)));
1220 "name", FieldName(descriptor_->field(i)));
1221 } 1312 }
1222 // clear_has_***() generated only for non-oneof fields 1313 // clear_has_***() generated only for non-oneof fields
1223 // in proto1/2. 1314 // in proto1/2.
1224 if (!descriptor_->field(i)->containing_oneof() && 1315 if (!descriptor_->field(i)->containing_oneof() &&
1225 HasFieldPresence(descriptor_->file())) { 1316 HasFieldPresence(descriptor_->file())) {
1226 printer->Print( 1317 printer->Print("void clear_has_$name$();\n", "name",
1227 "inline void clear_has_$name$();\n", 1318 FieldName(descriptor_->field(i)));
1228 "name", FieldName(descriptor_->field(i)));
1229 } 1319 }
1230 } 1320 }
1231 } 1321 }
1232 printer->Print("\n"); 1322 printer->Print("\n");
1233 1323
1234 // Generate oneof function declarations 1324 // Generate oneof function declarations
1235 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1325 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1236 printer->Print( 1326 printer->Print(
1237 "inline bool has_$oneof_name$() const;\n" 1327 "inline bool has_$oneof_name$() const;\n"
1238 "void clear_$oneof_name$();\n" 1328 "void clear_$oneof_name$();\n"
1239 "inline void clear_has_$oneof_name$();\n\n", 1329 "inline void clear_has_$oneof_name$();\n\n",
1240 "oneof_name", descriptor_->oneof_decl(i)->name()); 1330 "oneof_name", descriptor_->oneof_decl(i)->name());
1241 } 1331 }
1242 1332
1243 if (HasGeneratedMethods(descriptor_->file(), options_) && 1333 if (HasGeneratedMethods(descriptor_->file(), options_) &&
1244 !descriptor_->options().message_set_wire_format() && 1334 !descriptor_->options().message_set_wire_format() &&
1245 num_required_fields_ > 1) { 1335 num_required_fields_ > 1) {
1246 printer->Print( 1336 printer->Print(
1247 "// helper for ByteSize()\n" 1337 "// helper for ByteSizeLong()\n"
1248 "int RequiredFieldsByteSizeFallback() const;\n\n"); 1338 "size_t RequiredFieldsByteSizeFallback() const;\n\n");
1249 } 1339 }
1250 1340
1251 // Prepare decls for _cached_size_ and _has_bits_. Their position in the 1341 // Prepare decls for _cached_size_ and _has_bits_. Their position in the
1252 // output will be determined later. 1342 // output will be determined later.
1253 1343
1254 bool need_to_emit_cached_size = true; 1344 bool need_to_emit_cached_size = true;
1255 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. 1345 // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
1256 const string cached_size_decl = "mutable int _cached_size_;\n"; 1346 const string cached_size_decl = "mutable int _cached_size_;\n";
1257 1347
1258 // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields. 1348 const size_t sizeof_has_bits = HasBitsSize();
1259 size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
1260 if (descriptor_->field_count() == 0) {
1261 // Zero-size arrays aren't technically allowed, and MSVC in particular
1262 // doesn't like them. We still need to declare these arrays to make
1263 // other code compile. Since this is an uncommon case, we'll just declare
1264 // them with size 1 and waste some space. Oh well.
1265 sizeof_has_bits = 4;
1266 }
1267 const string has_bits_decl = sizeof_has_bits == 0 ? "" : 1349 const string has_bits_decl = sizeof_has_bits == 0 ? "" :
1268 "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n"; 1350 "::google::protobuf::internal::HasBits<" + SimpleItoa(sizeof_has_bits / 4) +
1269 1351 "> _has_bits_;\n";
1270 1352
1271 // To minimize padding, data members are divided into three sections: 1353 // To minimize padding, data members are divided into three sections:
1272 // (1) members assumed to align to 8 bytes 1354 // (1) members assumed to align to 8 bytes
1273 // (2) members corresponding to message fields, re-ordered to optimize 1355 // (2) members corresponding to message fields, re-ordered to optimize
1274 // alignment. 1356 // alignment.
1275 // (3) members assumed to align to 4 bytes. 1357 // (3) members assumed to align to 4 bytes.
1276 1358
1277 // Members assumed to align to 8 bytes: 1359 // Members assumed to align to 8 bytes:
1278 1360
1279 if (descriptor_->extension_range_count() > 0) { 1361 if (descriptor_->extension_range_count() > 0) {
1280 printer->Print( 1362 printer->Print(
1281 "::google::protobuf::internal::ExtensionSet _extensions_;\n" 1363 "::google::protobuf::internal::ExtensionSet _extensions_;\n"
1282 "\n"); 1364 "\n");
1283 } 1365 }
1284 1366
1285 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 1367 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1286 printer->Print( 1368 printer->Print(
1287 "::google::protobuf::internal::InternalMetadataWithArena _internal_metadat a_;\n"); 1369 "::google::protobuf::internal::InternalMetadataWithArena _internal_metadat a_;\n");
1288 } else { 1370 } else {
1289 printer->Print( 1371 printer->Print(
1290 "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n" 1372 "::google::protobuf::internal::InternalMetadataWithArenaLite "
1291 "::google::protobuf::Arena* _arena_ptr_;\n" 1373 "_internal_metadata_;\n");
1292 "\n");
1293 } 1374 }
1294 1375
1295 if (SupportsArenas(descriptor_)) { 1376 if (SupportsArenas(descriptor_)) {
1296 printer->Print( 1377 printer->Print(
1297 "friend class ::google::protobuf::Arena;\n" 1378 "friend class ::google::protobuf::Arena;\n"
1298 "typedef void InternalArenaConstructable_;\n" 1379 "typedef void InternalArenaConstructable_;\n"
1299 "typedef void DestructorSkippable_;\n"); 1380 "typedef void DestructorSkippable_;\n");
1300 } 1381 }
1301 1382
1302 if (HasFieldPresence(descriptor_->file())) { 1383 if (HasFieldPresence(descriptor_->file())) {
1303 // _has_bits_ is frequently accessed, so to reduce code size and improve 1384 // _has_bits_ is frequently accessed, so to reduce code size and improve
1304 // speed, it should be close to the start of the object. But, try not to 1385 // speed, it should be close to the start of the object. But, try not to
1305 // waste space:_has_bits_ by itself always makes sense if its size is a 1386 // waste space:_has_bits_ by itself always makes sense if its size is a
1306 // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together 1387 // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
1307 // will work well. 1388 // will work well.
1308 printer->Print(has_bits_decl.c_str()); 1389 printer->Print(has_bits_decl.c_str());
1309 if ((sizeof_has_bits % 8) != 0) { 1390 if ((sizeof_has_bits % 8) != 0) {
1310 printer->Print(cached_size_decl.c_str()); 1391 printer->Print(cached_size_decl.c_str());
1311 need_to_emit_cached_size = false; 1392 need_to_emit_cached_size = false;
1312 } 1393 }
1313 } else {
1314 // Without field presence, we need another way to disambiguate the default
1315 // instance, because the default instance's submessage fields (if any) store
1316 // pointers to the default instances of the submessages even when they
1317 // aren't present. Alternatives to this approach might be to (i) use a
1318 // tagged pointer on all message fields, setting a tag bit for "not really
1319 // present, just default instance"; or (ii) comparing |this| against the
1320 // return value from GeneratedMessageFactory::GetPrototype() in all
1321 // has_$field$() calls. However, both of these options are much more
1322 // expensive (in code size and CPU overhead) than just checking a field in
1323 // the message. Long-term, the best solution would be to rearchitect the
1324 // default instance design not to store pointers to submessage default
1325 // instances, and have reflection get those some other way; but that change
1326 // would have too much impact on proto2.
1327 printer->Print(
1328 "bool _is_default_instance_;\n");
1329 } 1394 }
1330 1395
1331 // Field members: 1396 // Field members:
1332 1397
1333 // List fields which doesn't belong to any oneof
1334 vector<const FieldDescriptor*> fields;
1335 hash_map<string, int> fieldname_to_chunk;
1336 for (int i = 0; i < descriptor_->field_count(); i++) {
1337 if (!descriptor_->field(i)->containing_oneof()) {
1338 const FieldDescriptor* field = descriptor_->field(i);
1339 fields.push_back(field);
1340 fieldname_to_chunk[FieldName(field)] = i / 8;
1341 }
1342 }
1343 OptimizePadding(&fields);
1344 // Emit some private and static members 1398 // Emit some private and static members
1345 runs_of_fields_ = vector< vector<string> >(1); 1399 for (int i = 0; i < optimized_order_.size(); ++i) {
1346 for (int i = 0; i < fields.size(); ++i) { 1400 const FieldDescriptor* field = optimized_order_[i];
1347 const FieldDescriptor* field = fields[i];
1348 const FieldGenerator& generator = field_generators_.get(field); 1401 const FieldGenerator& generator = field_generators_.get(field);
1349 generator.GenerateStaticMembers(printer); 1402 generator.GenerateStaticMembers(printer);
1350 generator.GeneratePrivateMembers(printer); 1403 generator.GeneratePrivateMembers(printer);
1351 if (CanClearByZeroing(field)) {
1352 const string& fieldname = FieldName(field);
1353 if (!runs_of_fields_.back().empty() &&
1354 (fieldname_to_chunk[runs_of_fields_.back().back()] !=
1355 fieldname_to_chunk[fieldname])) {
1356 runs_of_fields_.push_back(vector<string>());
1357 }
1358 runs_of_fields_.back().push_back(fieldname);
1359 } else if (!runs_of_fields_.back().empty()) {
1360 runs_of_fields_.push_back(vector<string>());
1361 }
1362 } 1404 }
1363 1405
1364 // For each oneof generate a union 1406 // For each oneof generate a union
1365 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1407 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1366 printer->Print( 1408 printer->Print(
1367 "union $camel_oneof_name$Union {\n" 1409 "union $camel_oneof_name$Union {\n"
1368 // explicit empty constructor is needed when union contains 1410 // explicit empty constructor is needed when union contains
1369 // ArenaStringPtr members for string fields. 1411 // ArenaStringPtr members for string fields.
1370 " $camel_oneof_name$Union() {}\n", 1412 " $camel_oneof_name$Union() {}\n",
1371 "camel_oneof_name", 1413 "camel_oneof_name",
(...skipping 29 matching lines...) Expand all
1401 1443
1402 // Generate _any_metadata_ for the Any type. 1444 // Generate _any_metadata_ for the Any type.
1403 if (IsAnyMessage(descriptor_)) { 1445 if (IsAnyMessage(descriptor_)) {
1404 printer->Print(vars, 1446 printer->Print(vars,
1405 "::google::protobuf::internal::AnyMetadata _any_metadata_;\n"); 1447 "::google::protobuf::internal::AnyMetadata _any_metadata_;\n");
1406 } 1448 }
1407 1449
1408 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as 1450 // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
1409 // friends so that they can access private static variables like 1451 // friends so that they can access private static variables like
1410 // default_instance_ and reflection_. 1452 // default_instance_ and reflection_.
1411 PrintHandlingOptionalStaticInitializers( 1453 printer->Print("friend void $dllexport_decl$ $initdefaultsname$_impl();\n",
1412 descriptor_->file(), options_, printer, 1454 // Vars.
1413 // With static initializers. 1455 "dllexport_decl", options_.dllexport_decl, "initdefaultsname",
1414 "friend void $dllexport_decl$ $adddescriptorsname$();\n", 1456 GlobalInitDefaultsName(descriptor_->file()->name()));
1415 // Without. 1457 printer->Print("friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
1416 "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", 1458 // Vars.
1417 // Vars. 1459 "dllexport_decl", options_.dllexport_decl,
1418 "dllexport_decl", options_.dllexport_decl, "adddescriptorsname", 1460 "adddescriptorsname",
1419 GlobalAddDescriptorsName(descriptor_->file()->name())); 1461 GlobalAddDescriptorsName(descriptor_->file()->name()));
1420 1462
1421 printer->Print( 1463 printer->Print(
1422 "friend void $assigndescriptorsname$();\n" 1464 "friend const ::google::protobuf::uint32* $offsetfunname$();\n"
1423 "friend void $shutdownfilename$();\n" 1465 "friend void $shutdownfilename$();\n"
1424 "\n", 1466 "\n",
1425 "assigndescriptorsname", 1467 "offsetfunname", GlobalOffsetTableName(descriptor_->file()->name()),
1426 GlobalAssignDescriptorsName(descriptor_->file()->name()), 1468 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
1427 "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
1428
1429 printer->Print(
1430 "void InitAsDefaultInstance();\n"
1431 "static $classname$* default_instance_;\n",
1432 "classname", classname_);
1433 1469
1434 printer->Outdent(); 1470 printer->Outdent();
1435 printer->Print(vars, "};"); 1471 printer->Print("};");
1436 GOOGLE_DCHECK(!need_to_emit_cached_size); 1472 GOOGLE_DCHECK(!need_to_emit_cached_size);
1437 } 1473 }
1438 1474
1439 void MessageGenerator:: 1475 void MessageGenerator::
1440 GenerateDependentInlineMethods(io::Printer* printer) { 1476 GenerateDependentInlineMethods(io::Printer* printer) {
1441 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1477 if (IsMapEntryMessage(descriptor_)) return;
1442 // map entry message doesn't need inline methods. Since map entry message 1478 for (int i = 0; i < descriptor_->field_count(); i++) {
1443 // cannot be a top level class, we just need to avoid calling 1479 if (descriptor_->field(i)->options().weak()) {
1444 // GenerateInlineMethods here. 1480 field_generators_.get(descriptor_->field(i))
1445 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; 1481 .GenerateDependentInlineAccessorDefinitions(printer);
1446 nested_generators_[i]->GenerateDependentInlineMethods(printer); 1482 }
1447 printer->Print(kThinSeparator);
1448 printer->Print("\n");
1449 } 1483 }
1450
1451 GenerateDependentFieldAccessorDefinitions(printer); 1484 GenerateDependentFieldAccessorDefinitions(printer);
1452 } 1485 }
1453 1486
1454 void MessageGenerator:: 1487 void MessageGenerator::
1455 GenerateInlineMethods(io::Printer* printer, bool is_inline) { 1488 GenerateInlineMethods(io::Printer* printer, bool is_inline) {
1456 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1489 if (IsMapEntryMessage(descriptor_)) return;
1457 // map entry message doesn't need inline methods. Since map entry message
1458 // cannot be a top level class, we just need to avoid calling
1459 // GenerateInlineMethods here.
1460 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1461 nested_generators_[i]->GenerateInlineMethods(printer, is_inline);
1462 printer->Print(kThinSeparator);
1463 printer->Print("\n");
1464 }
1465
1466 GenerateFieldAccessorDefinitions(printer, is_inline); 1490 GenerateFieldAccessorDefinitions(printer, is_inline);
1467 1491
1468 // Generate oneof_case() functions. 1492 // Generate oneof_case() functions.
1469 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1493 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1470 map<string, string> vars; 1494 std::map<string, string> vars;
1471 vars["class_name"] = classname_; 1495 vars["class_name"] = classname_;
1472 vars["camel_oneof_name"] = UnderscoresToCamelCase( 1496 vars["camel_oneof_name"] = UnderscoresToCamelCase(
1473 descriptor_->oneof_decl(i)->name(), true); 1497 descriptor_->oneof_decl(i)->name(), true);
1474 vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); 1498 vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
1475 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); 1499 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
1476 vars["inline"] = is_inline ? "inline " : ""; 1500 vars["inline"] = is_inline ? "inline " : "";
1477 printer->Print( 1501 printer->Print(
1478 vars, 1502 vars,
1479 "$inline$" 1503 "$inline$"
1480 "$class_name$::$camel_oneof_name$Case $class_name$::" 1504 "$class_name$::$camel_oneof_name$Case $class_name$::"
1481 "$oneof_name$_case() const {\n" 1505 "$oneof_name$_case() const {\n"
1482 " return $class_name$::$camel_oneof_name$Case(" 1506 " return $class_name$::$camel_oneof_name$Case("
1483 "_oneof_case_[$oneof_index$]);\n" 1507 "_oneof_case_[$oneof_index$]);\n"
1484 "}\n"); 1508 "}\n");
1485 } 1509 }
1486 } 1510 }
1487 1511
1488 void MessageGenerator:: 1512 void MessageGenerator::
1489 GenerateDescriptorDeclarations(io::Printer* printer) { 1513 GenerateDescriptorDeclarations(io::Printer* printer) {
1490 if (!IsMapEntryMessage(descriptor_)) {
1491 printer->Print(
1492 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
1493 "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
1494 " $name$_reflection_ = NULL;\n",
1495 "name", classname_);
1496 } else {
1497 printer->Print(
1498 "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
1499 "name", classname_);
1500 }
1501
1502 // Generate oneof default instance for reflection usage. 1514 // Generate oneof default instance for reflection usage.
1503 if (descriptor_->oneof_decl_count() > 0) { 1515 if (descriptor_->oneof_decl_count() > 0) {
1504 printer->Print("struct $name$OneofInstance {\n", 1516 printer->Print("struct $name$OneofInstance {\n",
1505 "name", classname_); 1517 "name", classname_);
1506 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1518 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1507 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 1519 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1508 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 1520 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1509 printer->Print(" "); 1521 printer->Print(" ");
1510 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 1522 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1511 (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && 1523 (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
1512 EffectiveStringCType(field) != FieldOptions::STRING)) { 1524 EffectiveStringCType(field) != FieldOptions::STRING)) {
1513 printer->Print("const "); 1525 printer->Print("const ");
1514 } 1526 }
1515 field_generators_.get(field).GeneratePrivateMembers(printer); 1527 field_generators_.get(field).GeneratePrivateMembers(printer);
1516 } 1528 }
1517 } 1529 }
1518 1530
1519 printer->Print("}* $name$_default_oneof_instance_ = NULL;\n", 1531 printer->Print("} $name$_default_oneof_instance_;\n", "name", classname_);
1520 "name", classname_);
1521 }
1522
1523 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1524 nested_generators_[i]->GenerateDescriptorDeclarations(printer);
1525 }
1526
1527 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1528 printer->Print(
1529 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
1530 "name", ClassName(descriptor_->enum_type(i), false));
1531 } 1532 }
1532 } 1533 }
1533 1534
1534 void MessageGenerator:: 1535 void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
1535 GenerateDescriptorInitializer(io::Printer* printer, int index) { 1536 int has_offset) {
1536 // TODO(kenton): Passing the index to this method is redundant; just use
1537 // descriptor_->index() instead.
1538 map<string, string> vars;
1539 vars["classname"] = classname_;
1540 vars["index"] = SimpleItoa(index);
1541
1542 // Obtain the descriptor from the parent's descriptor.
1543 if (descriptor_->containing_type() == NULL) {
1544 printer->Print(vars,
1545 "$classname$_descriptor_ = file->message_type($index$);\n");
1546 } else {
1547 vars["parent"] = ClassName(descriptor_->containing_type(), false);
1548 printer->Print(vars,
1549 "$classname$_descriptor_ = "
1550 "$parent$_descriptor_->nested_type($index$);\n");
1551 }
1552
1553 if (IsMapEntryMessage(descriptor_)) return; 1537 if (IsMapEntryMessage(descriptor_)) return;
1554 1538
1555 // Generate the offsets. 1539 std::map<string, string> vars;
1556 GenerateOffsets(printer);
1557 1540
1558 const bool pass_pool_and_factory = false; 1541 vars["classname"] = classname_;
1559 vars["fn"] = pass_pool_and_factory ? 1542 vars["offset"] = SimpleItoa(offset);
1560 "new ::google::protobuf::internal::GeneratedMessageReflection" : 1543 vars["has_bits_offsets"] = HasFieldPresence(descriptor_->file())
1561 "::google::protobuf::internal::GeneratedMessageReflection" 1544 ? SimpleItoa(offset + has_offset)
1562 "::NewGeneratedMessageReflection"; 1545 : "-1";
1563 // Construct the reflection object.
1564 printer->Print(vars,
1565 "$classname$_reflection_ =\n"
1566 " $fn$(\n"
1567 " $classname$_descriptor_,\n"
1568 " $classname$::default_instance_,\n"
1569 " $classname$_offsets_,\n");
1570 if (!HasFieldPresence(descriptor_->file())) {
1571 // If we don't have field presence, then _has_bits_ does not exist.
1572 printer->Print(vars,
1573 " -1,\n");
1574 } else {
1575 printer->Print(vars,
1576 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[ 0]),\n");
1577 }
1578
1579 // Unknown field offset: either points to the unknown field set if embedded
1580 // directly, or indicates that the unknown field set is stored as part of the
1581 // internal metadata if not.
1582 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1583 printer->Print(vars,
1584 " -1,\n");
1585 } else {
1586 printer->Print(vars,
1587 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1588 "$classname$, _unknown_fields_),\n");
1589 }
1590
1591 if (descriptor_->extension_range_count() > 0) {
1592 printer->Print(vars,
1593 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1594 "$classname$, _extensions_),\n");
1595 } else {
1596 // No extensions.
1597 printer->Print(vars,
1598 " -1,\n");
1599 }
1600
1601 if (descriptor_->oneof_decl_count() > 0) {
1602 printer->Print(vars,
1603 " $classname$_default_oneof_instance_,\n"
1604 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1605 "$classname$, _oneof_case_[0]),\n");
1606 }
1607
1608 if (pass_pool_and_factory) {
1609 printer->Print(
1610 " ::google::protobuf::DescriptorPool::generated_pool(),\n");
1611 printer->Print(vars,
1612 " ::google::protobuf::MessageFactory::generated_factory( ),\n");
1613 }
1614 1546
1615 printer->Print(vars, 1547 printer->Print(vars,
1616 " sizeof($classname$),\n"); 1548 "{ $offset$, $has_bits_offsets$, sizeof($classname$)},\n");
1617
1618 // Arena offset: either an offset to the metadata struct that contains the
1619 // arena pointer and unknown field set (in a space-efficient way) if we use
1620 // that implementation strategy, or an offset directly to the arena pointer if
1621 // not (because e.g. we don't have an unknown field set).
1622 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
1623 printer->Print(vars,
1624 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1625 "$classname$, _internal_metadata_),\n");
1626 } else {
1627 printer->Print(vars,
1628 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1629 "$classname$, _arena_),\n");
1630 }
1631
1632 // is_default_instance_ offset.
1633 if (HasFieldPresence(descriptor_->file())) {
1634 printer->Print(vars,
1635 " -1);\n");
1636 } else {
1637 printer->Print(vars,
1638 " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1639 "$classname$, _is_default_instance_));\n");
1640 }
1641
1642 // Handle nested types.
1643 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1644 nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
1645 }
1646
1647 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1648 enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
1649 }
1650 } 1549 }
1651 1550
1652 void MessageGenerator:: 1551 void MessageGenerator::
1653 GenerateTypeRegistrations(io::Printer* printer) { 1552 GenerateTypeRegistrations(io::Printer* printer) {
1654 // Register this message type with the message factory. 1553 // Register this message type with the message factory.
1655 if (!IsMapEntryMessage(descriptor_)) { 1554 if (IsMapEntryMessage(descriptor_)) {
1656 printer->Print( 1555 std::map<string, string> vars;
1657 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1658 " $classname$_descriptor_, &$classname$::default_instance());\n",
1659 "classname", classname_);
1660 }
1661 else {
1662 map<string, string> vars;
1663 CollectMapInfo(descriptor_, &vars); 1556 CollectMapInfo(descriptor_, &vars);
1664 vars["classname"] = classname_; 1557 vars["classname"] = classname_;
1665 1558
1666 const FieldDescriptor* val = descriptor_->FindFieldByName("value"); 1559 const FieldDescriptor* val = descriptor_->FindFieldByName("value");
1667 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && 1560 if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
1668 val->type() == FieldDescriptor::TYPE_ENUM) { 1561 val->type() == FieldDescriptor::TYPE_ENUM) {
1669 const EnumValueDescriptor* default_value = val->default_value_enum(); 1562 const EnumValueDescriptor* default_value = val->default_value_enum();
1670 vars["default_enum_value"] = Int32ToString(default_value->number()); 1563 vars["default_enum_value"] = Int32ToString(default_value->number());
1671 } else { 1564 } else {
1672 vars["default_enum_value"] = "0"; 1565 vars["default_enum_value"] = "0";
1673 } 1566 }
1674 1567
1675 printer->Print(vars, 1568 vars["index_in_metadata"] = SimpleItoa(index_in_metadata_);
1676 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1677 " $classname$_descriptor_,\n"
1678 " ::google::protobuf::internal::MapEntry<\n"
1679 " $key$,\n"
1680 " $val$,\n"
1681 " $key_wire_type$,\n"
1682 " $val_wire_type$,\n"
1683 " $default_enum_value$>::CreateDefaultInstance(\n"
1684 " $classname$_descriptor_));\n");
1685 }
1686 1569
1687 // Handle nested types. 1570 printer->Print(
1688 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1571 vars,
1689 nested_generators_[i]->GenerateTypeRegistrations(printer); 1572 "const ::google::protobuf::Descriptor* $classname$_descriptor = "
1573 "file_level_metadata[$index_in_metadata$].descriptor;\n"
1574 "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n "
1575 " $classname$_descriptor,\n"
1576 " ::google::protobuf::internal::MapEntry<\n"
1577 " $key$,\n"
1578 " $val$,\n"
1579 " $key_wire_type$,\n"
1580 " $val_wire_type$,\n"
1581 " $default_enum_value$>::CreateDefaultInstance(\n"
1582 " $classname$_descriptor));\n");
1690 } 1583 }
1691 } 1584 }
1692 1585
1693 void MessageGenerator:: 1586 void MessageGenerator::
1694 GenerateDefaultInstanceAllocator(io::Printer* printer) { 1587 GenerateDefaultInstanceAllocator(io::Printer* printer) {
1588 if (IsMapEntryMessage(descriptor_)) return;
1589
1695 // Construct the default instances of all fields, as they will be used 1590 // Construct the default instances of all fields, as they will be used
1696 // when creating the default instance of the entire message. 1591 // when creating the default instance of the entire message.
1697 for (int i = 0; i < descriptor_->field_count(); i++) { 1592 for (int i = 0; i < descriptor_->field_count(); i++) {
1698 field_generators_.get(descriptor_->field(i)) 1593 field_generators_.get(descriptor_->field(i))
1699 .GenerateDefaultInstanceAllocator(printer); 1594 .GenerateDefaultInstanceAllocator(printer);
1700 } 1595 }
1701 1596
1702 if (IsMapEntryMessage(descriptor_)) return;
1703
1704 // Construct the default instance. We can't call InitAsDefaultInstance() yet 1597 // Construct the default instance. We can't call InitAsDefaultInstance() yet
1705 // because we need to make sure all default instances that this one might 1598 // because we need to make sure all default instances that this one might
1706 // depend on are constructed first. 1599 // depend on are constructed first.
1707 printer->Print( 1600 printer->Print("_$classname$_default_instance_.DefaultConstruct();\n",
1708 "$classname$::default_instance_ = new $classname$();\n", 1601 "classname", classname_);
1709 "classname", classname_);
1710
1711 if ((descriptor_->oneof_decl_count() > 0) &&
1712 HasDescriptorMethods(descriptor_->file(), options_)) {
1713 printer->Print(
1714 "$classname$_default_oneof_instance_ = new $classname$OneofInstance();\n",
1715 "classname", classname_);
1716 }
1717
1718 // Handle nested types.
1719 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1720 nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
1721 }
1722
1723 } 1602 }
1724 1603
1725 void MessageGenerator:: 1604 void MessageGenerator::
1726 GenerateDefaultInstanceInitializer(io::Printer* printer) { 1605 GenerateDefaultInstanceInitializer(io::Printer* printer) {
1727 printer->Print( 1606 if (IsMapEntryMessage(descriptor_)) return;
1728 "$classname$::default_instance_->InitAsDefaultInstance();\n",
1729 "classname", classname_);
1730 1607
1731 // Register extensions. 1608 // The default instance needs all of its embedded message pointers
1732 for (int i = 0; i < descriptor_->extension_count(); i++) { 1609 // cross-linked to other default instances. We can't do this initialization
1733 extension_generators_[i]->GenerateRegistration(printer); 1610 // in the constructor because some other default instances may not have been
1734 } 1611 // constructed yet at that time.
1612 // TODO(kenton): Maybe all message fields (even for non-default messages)
1613 // should be initialized to point at default instances rather than NULL?
1614 for (int i = 0; i < descriptor_->field_count(); i++) {
1615 const FieldDescriptor* field = descriptor_->field(i);
1735 1616
1736 // Handle nested types. 1617 if (!field->is_repeated() &&
1737 for (int i = 0; i < descriptor_->nested_type_count(); i++) { 1618 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1738 // map entry message doesn't need to initialize default instance manually. 1619 (field->containing_oneof() == NULL ||
1739 // Since map entry message cannot be a top level class, we just need to 1620 HasDescriptorMethods(descriptor_->file(), options_))) {
1740 // avoid calling DefaultInstanceInitializer here. 1621 string name;
1741 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; 1622 if (field->containing_oneof()) {
1742 nested_generators_[i]->GenerateDefaultInstanceInitializer(printer); 1623 name = classname_ + "_default_oneof_instance_.";
1624 } else {
1625 name = "_" + classname_ + "_default_instance_.get_mutable()->";
1626 }
1627 name += FieldName(field);
1628 printer->Print(
1629 "$name$_ = const_cast< $type$*>(\n"
1630 " $type$::internal_default_instance());\n",
1631 // Vars.
1632 "name", name, "type", FieldMessageTypeName(field));
1633 } else if (field->containing_oneof() &&
1634 HasDescriptorMethods(descriptor_->file(), options_)) {
1635 field_generators_.get(descriptor_->field(i))
1636 .GenerateConstructorCode(printer);
1637 }
1743 } 1638 }
1744 } 1639 }
1745 1640
1746 void MessageGenerator:: 1641 void MessageGenerator::
1747 GenerateShutdownCode(io::Printer* printer) { 1642 GenerateShutdownCode(io::Printer* printer) {
1748 printer->Print( 1643 if (IsMapEntryMessage(descriptor_)) return;
1749 "delete $classname$::default_instance_;\n", 1644
1750 "classname", classname_); 1645 printer->Print("_$classname$_default_instance_.Shutdown();\n", "classname",
1646 classname_);
1751 1647
1752 if (HasDescriptorMethods(descriptor_->file(), options_)) { 1648 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1753 if (descriptor_->oneof_decl_count() > 0) { 1649 printer->Print("delete file_level_metadata[$index$].reflection;\n", "index",
1754 printer->Print( 1650 SimpleItoa(index_in_metadata_));
1755 "delete $classname$_default_oneof_instance_;\n",
1756 "classname", classname_);
1757 }
1758 printer->Print(
1759 "delete $classname$_reflection_;\n",
1760 "classname", classname_);
1761 } 1651 }
1762 1652
1763 // Handle default instances of fields. 1653 // Handle default instances of fields.
1764 for (int i = 0; i < descriptor_->field_count(); i++) { 1654 for (int i = 0; i < descriptor_->field_count(); i++) {
1765 field_generators_.get(descriptor_->field(i)) 1655 field_generators_.get(descriptor_->field(i))
1766 .GenerateShutdownCode(printer); 1656 .GenerateShutdownCode(printer);
1767 } 1657 }
1768
1769 // Handle nested types.
1770 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1771 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1772 nested_generators_[i]->GenerateShutdownCode(printer);
1773 }
1774 } 1658 }
1775 1659
1776 void MessageGenerator:: 1660 void MessageGenerator::
1777 GenerateClassMethods(io::Printer* printer) { 1661 GenerateClassMethods(io::Printer* printer) {
1662 if (IsMapEntryMessage(descriptor_)) return;
1663
1778 // mutable_unknown_fields wrapper function for LazyStringOutputStream 1664 // mutable_unknown_fields wrapper function for LazyStringOutputStream
1779 // callback. 1665 // callback.
1780 if (PreserveUnknownFields(descriptor_) && 1666 if (PreserveUnknownFields(descriptor_) &&
1781 !UseUnknownFieldSet(descriptor_->file(), options_)) { 1667 !UseUnknownFieldSet(descriptor_->file(), options_)) {
1782 printer->Print( 1668 printer->Print(
1783 "static ::std::string* MutableUnknownFieldsFor$classname$(\n" 1669 "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
1784 " $classname$* ptr) {\n" 1670 " $classname$* ptr) {\n"
1785 " return ptr->mutable_unknown_fields();\n" 1671 " return ptr->mutable_unknown_fields();\n"
1786 "}\n" 1672 "}\n"
1787 "\n", 1673 "\n",
(...skipping 10 matching lines...) Expand all
1798 " _any_metadata_.PackFrom(message, type_url_prefix);\n" 1684 " _any_metadata_.PackFrom(message, type_url_prefix);\n"
1799 "}\n" 1685 "}\n"
1800 "\n" 1686 "\n"
1801 "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\ n" 1687 "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\ n"
1802 " return _any_metadata_.UnpackTo(message);\n" 1688 " return _any_metadata_.UnpackTo(message);\n"
1803 "}\n" 1689 "}\n"
1804 "\n", 1690 "\n",
1805 "classname", classname_); 1691 "classname", classname_);
1806 } 1692 }
1807 1693
1808 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1809 enum_generators_[i]->GenerateMethods(printer);
1810 }
1811
1812 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1813 // map entry message doesn't need class methods. Since map entry message
1814 // cannot be a top level class, we just need to avoid calling
1815 // GenerateClassMethods here.
1816 if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
1817 nested_generators_[i]->GenerateClassMethods(printer);
1818 printer->Print("\n");
1819 printer->Print(kThinSeparator);
1820 printer->Print("\n");
1821 }
1822
1823 // Generate non-inline field definitions. 1694 // Generate non-inline field definitions.
1824 for (int i = 0; i < descriptor_->field_count(); i++) { 1695 for (int i = 0; i < descriptor_->field_count(); i++) {
1825 field_generators_.get(descriptor_->field(i)) 1696 field_generators_.get(descriptor_->field(i))
1826 .GenerateNonInlineAccessorDefinitions(printer); 1697 .GenerateNonInlineAccessorDefinitions(printer);
1827 } 1698 }
1828 1699
1829 // Generate field number constants. 1700 // Generate field number constants.
1830 printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"); 1701 printer->Print("#if !defined(_MSC_VER) || _MSC_VER >= 1900\n");
1831 for (int i = 0; i < descriptor_->field_count(); i++) { 1702 for (int i = 0; i < descriptor_->field_count(); i++) {
1832 const FieldDescriptor *field = descriptor_->field(i); 1703 const FieldDescriptor *field = descriptor_->field(i);
1833 printer->Print( 1704 printer->Print(
1834 "const int $classname$::$constant_name$;\n", 1705 "const int $classname$::$constant_name$;\n",
1835 "classname", ClassName(FieldScope(field), false), 1706 "classname", ClassName(FieldScope(field), false),
1836 "constant_name", FieldConstantName(field)); 1707 "constant_name", FieldConstantName(field));
1837 } 1708 }
1838 printer->Print( 1709 printer->Print(
1839 "#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n" 1710 "#endif // !defined(_MSC_VER) || _MSC_VER >= 1900\n"
1840 "\n"); 1711 "\n");
1841 1712
1842 // Define extension identifiers.
1843 for (int i = 0; i < descriptor_->extension_count(); i++) {
1844 extension_generators_[i]->GenerateDefinition(printer);
1845 }
1846
1847 GenerateStructors(printer); 1713 GenerateStructors(printer);
1848 printer->Print("\n"); 1714 printer->Print("\n");
1849 1715
1850 if (descriptor_->oneof_decl_count() > 0) { 1716 if (descriptor_->oneof_decl_count() > 0) {
1851 GenerateOneofClear(printer); 1717 GenerateOneofClear(printer);
1852 printer->Print("\n"); 1718 printer->Print("\n");
1853 } 1719 }
1854 1720
1855 if (HasGeneratedMethods(descriptor_->file(), options_)) { 1721 if (HasGeneratedMethods(descriptor_->file(), options_)) {
1856 GenerateClear(printer); 1722 GenerateClear(printer);
(...skipping 21 matching lines...) Expand all
1878 1744
1879 GenerateIsInitialized(printer); 1745 GenerateIsInitialized(printer);
1880 printer->Print("\n"); 1746 printer->Print("\n");
1881 } 1747 }
1882 1748
1883 GenerateSwap(printer); 1749 GenerateSwap(printer);
1884 printer->Print("\n"); 1750 printer->Print("\n");
1885 1751
1886 if (HasDescriptorMethods(descriptor_->file(), options_)) { 1752 if (HasDescriptorMethods(descriptor_->file(), options_)) {
1887 printer->Print( 1753 printer->Print(
1888 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" 1754 "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
1889 " protobuf_AssignDescriptorsOnce();\n" 1755 " protobuf_AssignDescriptorsOnce();\n"
1890 " ::google::protobuf::Metadata metadata;\n" 1756 " return file_level_metadata[$index$];\n"
1891 " metadata.descriptor = $classname$_descriptor_;\n" 1757 "}\n"
1892 " metadata.reflection = $classname$_reflection_;\n" 1758 "\n",
1893 " return metadata;\n" 1759 "classname", classname_, "index", SimpleItoa(index_in_metadata_));
1894 "}\n"
1895 "\n",
1896 "classname", classname_);
1897 } else { 1760 } else {
1898 printer->Print( 1761 printer->Print(
1899 "::std::string $classname$::GetTypeName() const {\n" 1762 "::std::string $classname$::GetTypeName() const {\n"
1900 " return \"$type_name$\";\n" 1763 " return \"$type_name$\";\n"
1901 "}\n" 1764 "}\n"
1902 "\n", 1765 "\n",
1903 "classname", classname_, 1766 "classname", classname_,
1904 "type_name", descriptor_->full_name()); 1767 "type_name", descriptor_->full_name());
1905 } 1768 }
1906 1769
1907 } 1770 }
1908 1771
1909 void MessageGenerator:: 1772 std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
1910 GenerateOffsets(io::Printer* printer) { 1773 io::Printer* printer) {
1911 printer->Print("static const int $classname$_offsets_[$field_count$] = {\n", 1774 if (IsMapEntryMessage(descriptor_)) return std::make_pair(0, 0);
1912 "classname", classname_, "field_count", 1775 std::map<string, string> variables;
1913 SimpleItoa(std::max(1, descriptor_->field_count() + 1776 variables["classname"] = classname_;
1914 descriptor_->oneof_decl_count())));
1915 printer->Indent();
1916 1777
1778 if (HasFieldPresence(descriptor_->file())) {
1779 printer->Print(
1780 variables,
1781 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_) ,\n");
1782 } else {
1783 printer->Print("~0u, // no _has_bits_\n");
1784 }
1785 printer->Print(variables,
1786 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1787 "_internal_metadata_),\n");
1788 if (descriptor_->extension_range_count() > 0) {
1789 printer->Print(
1790 variables,
1791 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _extensions _),\n");
1792 } else {
1793 printer->Print("~0u, // no _extensions_\n");
1794 }
1795 if (descriptor_->oneof_decl_count() > 0) {
1796 printer->Print(variables,
1797 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1798 "_oneof_case_[0]),\n");
1799 } else {
1800 printer->Print("~0u, // no _oneof_case_\n");
1801 }
1802
1803 const int kNumGenericOffsets = 4; // the number of fixed offsets above
1804 const size_t offsets = kNumGenericOffsets +
1805 descriptor_->field_count() +
1806 descriptor_->oneof_decl_count();
1807 size_t entries = offsets;
1917 for (int i = 0; i < descriptor_->field_count(); i++) { 1808 for (int i = 0; i < descriptor_->field_count(); i++) {
1918 const FieldDescriptor* field = descriptor_->field(i); 1809 const FieldDescriptor* field = descriptor_->field(i);
1919 if (field->containing_oneof()) { 1810 if (field->containing_oneof()) {
1920 printer->Print( 1811 printer->Print(
1921 "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" 1812 "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
1922 "$classname$_default_oneof_instance_, $name$_),\n", 1813 "(&$classname$_default_oneof_instance_), $name$_),\n",
1923 "classname", classname_, 1814 "classname", classname_, "name", FieldName(field));
1924 "name", FieldName(field));
1925 } else { 1815 } else {
1926 printer->Print( 1816 printer->Print(
1927 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " 1817 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1928 "$name$_),\n", 1818 "$name$_),\n",
1929 "classname", classname_, 1819 "classname", classname_,
1930 "name", FieldName(field)); 1820 "name", FieldName(field));
1931 } 1821 }
1932 } 1822 }
1933 1823
1934 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1824 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1935 const OneofDescriptor* oneof = descriptor_->oneof_decl(i); 1825 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1936 printer->Print( 1826 printer->Print(
1937 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", 1827 "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
1938 "classname", classname_, 1828 "classname", classname_,
1939 "name", oneof->name()); 1829 "name", oneof->name());
1940 } 1830 }
1941 1831
1942 printer->Outdent(); 1832 if (HasFieldPresence(descriptor_->file())) {
1943 printer->Print("};\n"); 1833 entries += has_bit_indices_.size();
1834 for (int i = 0; i < has_bit_indices_.size(); i++) {
1835 printer->Print("$index$,\n", "index", SimpleItoa(has_bit_indices_[i]));
1836 }
1837 }
1838
1839 return std::make_pair(entries, offsets);
1944 } 1840 }
1945 1841
1946 void MessageGenerator:: 1842 void MessageGenerator::
1947 GenerateSharedConstructorCode(io::Printer* printer) { 1843 GenerateSharedConstructorCode(io::Printer* printer) {
1948 printer->Print( 1844 printer->Print(
1949 "void $classname$::SharedCtor() {\n", 1845 "void $classname$::SharedCtor() {\n",
1950 "classname", classname_); 1846 "classname", classname_);
1951 printer->Indent(); 1847 printer->Indent();
1952 1848
1953 if (!HasFieldPresence(descriptor_->file())) { 1849 bool need_to_clear_cached_size = true;
1954 printer->Print( 1850 // We reproduce the logic used for laying out _cached_sized_ in the class
1955 " _is_default_instance_ = false;\n"); 1851 // definition, as to initialize it in-order.
1852 if (HasFieldPresence(descriptor_->file()) &&
1853 (HasBitsSize() % 8) != 0) {
1854 printer->Print("_cached_size_ = 0;\n");
1855 need_to_clear_cached_size = false;
1956 } 1856 }
1957 1857
1958 printer->Print(StrCat( 1858 // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer??
1959 uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "", 1859 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1960 "_cached_size_ = 0;\n").c_str()); 1860 if (HasDescriptorMethods(descriptor_->file(), options_) &&
1961 1861 IsMapEntryMessage(descriptor_->nested_type(i))) {
1962 if (PreserveUnknownFields(descriptor_) && 1862 printer->Print(
1963 !UseUnknownFieldSet(descriptor_->file(), options_)) { 1863 "const ::google::protobuf::Descriptor*& $type$_descriptor = "
1964 printer->Print( 1864 "file_level_metadata[$index$].descriptor;\n",
1965 "_unknown_fields_.UnsafeSetDefault(\n" 1865 "type", ClassName(descriptor_->nested_type(i), false), "index",
1966 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"); 1866 SimpleItoa(nested_generators_[i]->index_in_metadata_));
1967 }
1968
1969 for (int i = 0; i < descriptor_->field_count(); i++) {
1970 if (!descriptor_->field(i)->containing_oneof()) {
1971 field_generators_.get(descriptor_->field(i))
1972 .GenerateConstructorCode(printer);
1973 } 1867 }
1974 } 1868 }
1975 1869
1976 if (HasFieldPresence(descriptor_->file())) { 1870 std::vector<bool> processed(optimized_order_.size(), false);
1977 printer->Print( 1871 GenerateConstructorBody(printer, processed, false);
1978 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1979 }
1980 1872
1981 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1873 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1982 printer->Print( 1874 printer->Print(
1983 "clear_has_$oneof_name$();\n", 1875 "clear_has_$oneof_name$();\n",
1984 "oneof_name", descriptor_->oneof_decl(i)->name()); 1876 "oneof_name", descriptor_->oneof_decl(i)->name());
1985 } 1877 }
1986 1878
1879 if (need_to_clear_cached_size) {
1880 printer->Print("_cached_size_ = 0;\n");
1881 }
1882
1987 printer->Outdent(); 1883 printer->Outdent();
1988 printer->Print("}\n\n"); 1884 printer->Print("}\n\n");
1989 } 1885 }
1990 1886
1991 void MessageGenerator:: 1887 void MessageGenerator::
1992 GenerateSharedDestructorCode(io::Printer* printer) { 1888 GenerateSharedDestructorCode(io::Printer* printer) {
1993 printer->Print( 1889 printer->Print(
1994 "void $classname$::SharedDtor() {\n", 1890 "void $classname$::SharedDtor() {\n",
1995 "classname", classname_); 1891 "classname", classname_);
1996 printer->Indent(); 1892 printer->Indent();
1997 if (SupportsArenas(descriptor_)) { 1893 if (SupportsArenas(descriptor_)) {
1998 // Do nothing when the message is allocated in an arena. 1894 // Do nothing when the message is allocated in an arena.
1999 printer->Print( 1895 printer->Print(
2000 "if (GetArenaNoVirtual() != NULL) {\n" 1896 "::google::protobuf::Arena* arena = GetArenaNoVirtual();\n"
1897 "if (arena != NULL) {\n"
2001 " return;\n" 1898 " return;\n"
2002 "}\n" 1899 "}\n"
2003 "\n"); 1900 "\n");
2004 } 1901 }
2005 1902
2006 // Write the desctructor for _unknown_fields_ in lite runtime.
2007 if (PreserveUnknownFields(descriptor_) &&
2008 !UseUnknownFieldSet(descriptor_->file(), options_)) {
2009 if (SupportsArenas(descriptor_)) {
2010 printer->Print(
2011 "_unknown_fields_.Destroy(\n"
2012 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2013 " GetArenaNoVirtual());\n");
2014 } else {
2015 printer->Print(
2016 "_unknown_fields_.DestroyNoArena(\n"
2017 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n" );
2018 }
2019 }
2020
2021 // Write the destructors for each field except oneof members. 1903 // Write the destructors for each field except oneof members.
2022 for (int i = 0; i < descriptor_->field_count(); i++) { 1904 // optimized_order_ does not contain oneof fields.
2023 if (!descriptor_->field(i)->containing_oneof()) { 1905 for (int i = 0; i < optimized_order_.size(); i++) {
2024 field_generators_.get(descriptor_->field(i)) 1906 const FieldDescriptor* field = optimized_order_[i];
2025 .GenerateDestructorCode(printer); 1907 field_generators_.get(field).GenerateDestructorCode(printer);
2026 }
2027 } 1908 }
2028 1909
2029 // Generate code to destruct oneofs. Clearing should do the work. 1910 // Generate code to destruct oneofs. Clearing should do the work.
2030 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 1911 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2031 printer->Print( 1912 printer->Print(
2032 "if (has_$oneof_name$()) {\n" 1913 "if (has_$oneof_name$()) {\n"
2033 " clear_$oneof_name$();\n" 1914 " clear_$oneof_name$();\n"
2034 "}\n", 1915 "}\n",
2035 "oneof_name", descriptor_->oneof_decl(i)->name()); 1916 "oneof_name", descriptor_->oneof_decl(i)->name());
2036 } 1917 }
2037 1918
2038 PrintHandlingOptionalStaticInitializers(
2039 descriptor_->file(), options_, printer,
2040 // With static initializers.
2041 "if (this != default_instance_) {\n",
2042 // Without.
2043 "if (this != &default_instance()) {\n");
2044
2045 // We need to delete all embedded messages.
2046 // TODO(kenton): If we make unset messages point at default instances
2047 // instead of NULL, then it would make sense to move this code into
2048 // MessageFieldGenerator::GenerateDestructorCode().
2049 for (int i = 0; i < descriptor_->field_count(); i++) {
2050 const FieldDescriptor* field = descriptor_->field(i);
2051
2052 if (!field->is_repeated() &&
2053 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2054 // Skip oneof members
2055 if (!field->containing_oneof()) {
2056 printer->Print(
2057 " delete $name$_;\n",
2058 "name", FieldName(field));
2059 }
2060 }
2061 }
2062
2063 printer->Outdent(); 1919 printer->Outdent();
2064 printer->Print( 1920 printer->Print(
2065 " }\n"
2066 "}\n" 1921 "}\n"
2067 "\n"); 1922 "\n");
2068 } 1923 }
2069 1924
2070 void MessageGenerator:: 1925 void MessageGenerator::
2071 GenerateArenaDestructorCode(io::Printer* printer) { 1926 GenerateArenaDestructorCode(io::Printer* printer) {
2072 // Generate the ArenaDtor() method. Track whether any fields actually produced 1927 // Generate the ArenaDtor() method. Track whether any fields actually produced
2073 // code that needs to be called. 1928 // code that needs to be called.
2074 printer->Print( 1929 printer->Print(
2075 "void $classname$::ArenaDtor(void* object) {\n", 1930 "void $classname$::ArenaDtor(void* object) {\n",
2076 "classname", classname_); 1931 "classname", classname_);
2077 printer->Indent(); 1932 printer->Indent();
2078 1933
2079 // This code is placed inside a static method, rather than an ordinary one, 1934 // This code is placed inside a static method, rather than an ordinary one,
2080 // since that simplifies Arena's destructor list (ordinary function pointers 1935 // since that simplifies Arena's destructor list (ordinary function pointers
2081 // rather than member function pointers). _this is the object being 1936 // rather than member function pointers). _this is the object being
2082 // destructed. 1937 // destructed.
2083 printer->Print( 1938 printer->Print(
2084 "$classname$* _this = reinterpret_cast< $classname$* >(object);\n" 1939 "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
2085 // avoid an "unused variable" warning in case no fields have dtor code. 1940 // avoid an "unused variable" warning in case no fields have dtor code.
2086 "(void)_this;\n", 1941 "(void)_this;\n",
2087 "classname", classname_); 1942 "classname", classname_);
2088 1943
2089 bool need_registration = false; 1944 bool need_registration = false;
2090 for (int i = 0; i < descriptor_->field_count(); i++) { 1945 // Process non-oneof fields first.
2091 if (field_generators_.get(descriptor_->field(i)) 1946 for (int i = 0; i < optimized_order_.size(); i++) {
1947 const FieldDescriptor* field = optimized_order_[i];
1948 if (field_generators_.get(field)
2092 .GenerateArenaDestructorCode(printer)) { 1949 .GenerateArenaDestructorCode(printer)) {
2093 need_registration = true; 1950 need_registration = true;
2094 } 1951 }
2095 } 1952 }
1953
1954 // Process oneof fields.
1955 //
1956 // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything
1957 // and returns false for oneof fields.
1958 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1959 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1960
1961 for (int j = 0; j < oneof->field_count(); j++) {
1962 const FieldDescriptor* field = oneof->field(j);
1963 if (field_generators_.get(field)
1964 .GenerateArenaDestructorCode(printer)) {
1965 need_registration = true;
1966 }
1967 }
1968 }
1969
2096 printer->Outdent(); 1970 printer->Outdent();
2097 printer->Print( 1971 printer->Print(
2098 "}\n"); 1972 "}\n");
2099 1973
2100 if (need_registration) { 1974 if (need_registration) {
2101 printer->Print( 1975 printer->Print(
2102 "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* a rena) {\n" 1976 "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* a rena) {\n"
2103 " if (arena != NULL) {\n" 1977 " if (arena != NULL) {\n"
2104 " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" 1978 " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
2105 " }\n" 1979 " }\n"
2106 "}\n", 1980 "}\n",
2107 "classname", classname_); 1981 "classname", classname_);
2108 } else { 1982 } else {
2109 printer->Print( 1983 printer->Print(
2110 "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) { \n" 1984 "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) { \n"
2111 "}\n", 1985 "}\n",
2112 "classname", classname_); 1986 "classname", classname_);
2113 } 1987 }
2114 } 1988 }
2115 1989
1990 void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
1991 std::vector<bool> processed,
1992 bool copy_constructor) const {
1993 const FieldDescriptor* last_start = NULL;
1994 // RunMap maps from fields that start each run to the number of fields in that
1995 // run. This is optimized for the common case that there are very few runs in
1996 // a message and that most of the eligible fields appear together.
1997 typedef hash_map<const FieldDescriptor*, size_t> RunMap;
1998 RunMap runs;
1999
2000 for (int i = 0; i < optimized_order_.size(); ++i) {
2001 const FieldDescriptor* field = optimized_order_[i];
2002 if ((copy_constructor && IsPOD(field)) ||
2003 (!copy_constructor && CanConstructByZeroing(field, options_))) {
2004 if (last_start == NULL) {
2005 last_start = field;
2006 }
2007
2008 runs[last_start]++;
2009 } else {
2010 last_start = NULL;
2011 }
2012 }
2013
2014 string pod_template;
2015 if (copy_constructor) {
2016 pod_template =
2017 "::memcpy(&$first$_, &from.$first$_,\n"
2018 " reinterpret_cast<char*>(&$last$_) -\n"
2019 " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n";
2020 } else {
2021 pod_template =
2022 "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n"
2023 " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n";
2024 }
2025
2026 for (int i = 0; i < optimized_order_.size(); ++i) {
2027 if (processed[i]) {
2028 continue;
2029 }
2030
2031 const FieldDescriptor* field = optimized_order_[i];
2032 RunMap::const_iterator it = runs.find(field);
2033
2034 // We only apply the memset technique to runs of more than one field, as
2035 // assignment is better than memset for generated code clarity.
2036 if (it != runs.end() && it->second > 1) {
2037 // Use a memset, then skip run_length fields.
2038 const size_t run_length = it->second;
2039 const string first_field_name = FieldName(field);
2040 const string last_field_name =
2041 FieldName(optimized_order_[i + run_length - 1]);
2042
2043 printer->Print(pod_template.c_str(),
2044 "first", first_field_name,
2045 "last", last_field_name);
2046
2047 i += run_length - 1;
2048 // ++i at the top of the loop.
2049 } else {
2050 if (copy_constructor) {
2051 field_generators_.get(field).GenerateCopyConstructorCode(printer);
2052 } else {
2053 field_generators_.get(field).GenerateConstructorCode(printer);
2054 }
2055 }
2056 }
2057 }
2058
2116 void MessageGenerator:: 2059 void MessageGenerator::
2117 GenerateStructors(io::Printer* printer) { 2060 GenerateStructors(io::Printer* printer) {
2118 string superclass; 2061 string superclass;
2119 if (use_dependent_base_) { 2062 if (use_dependent_base_) {
2120 superclass = 2063 superclass =
2121 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; 2064 DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
2122 } else { 2065 } else {
2123 superclass = SuperClassName(descriptor_, options_); 2066 superclass = SuperClassName(descriptor_, options_);
2124 } 2067 }
2125 string initializer_with_arena = superclass + "()"; 2068 string initializer_with_arena = superclass + "()";
2126 2069
2127 if (descriptor_->extension_range_count() > 0) { 2070 if (descriptor_->extension_range_count() > 0) {
2128 initializer_with_arena += ",\n _extensions_(arena)"; 2071 initializer_with_arena += ",\n _extensions_(arena)";
2129 } 2072 }
2130 2073
2131 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 2074 initializer_with_arena += ",\n _internal_metadata_(arena)";
2132 initializer_with_arena += ",\n _internal_metadata_(arena)";
2133 } else {
2134 initializer_with_arena += ",\n _arena_ptr_(arena)";
2135 }
2136 2075
2137 // Initialize member variables with arena constructor. 2076 // Initialize member variables with arena constructor.
2138 for (int i = 0; i < descriptor_->field_count(); i++) { 2077 for (int i = 0; i < optimized_order_.size(); i++) {
2139 bool has_arena_constructor = descriptor_->field(i)->is_repeated(); 2078 const FieldDescriptor* field = optimized_order_[i];
2079
2080 bool has_arena_constructor = field->is_repeated();
2140 if (has_arena_constructor) { 2081 if (has_arena_constructor) {
2141 initializer_with_arena += string(",\n ") + 2082 initializer_with_arena += string(",\n ") +
2142 FieldName(descriptor_->field(i)) + string("_(arena)"); 2083 FieldName(field) + string("_(arena)");
2143 } 2084 }
2144 } 2085 }
2145 2086
2146 if (IsAnyMessage(descriptor_)) { 2087 if (IsAnyMessage(descriptor_)) {
2147 initializer_with_arena += ",\n _any_metadata_(&type_url, &value_)"; 2088 initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)";
2148 } 2089 }
2149 2090
2150 string initializer_null; 2091 string initializer_null;
2151 initializer_null = (UseUnknownFieldSet(descriptor_->file(), options_) ? 2092 initializer_null = ", _internal_metadata_(NULL)";
2152 ", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)");
2153 if (IsAnyMessage(descriptor_)) { 2093 if (IsAnyMessage(descriptor_)) {
2154 initializer_null += ", _any_metadata_(&type_url_, &value_)"; 2094 initializer_null += ", _any_metadata_(&type_url_, &value_)";
2155 } 2095 }
2156 2096
2157 printer->Print( 2097 printer->Print(
2158 "$classname$::$classname$()\n" 2098 "$classname$::$classname$()\n"
2159 " : $superclass$()$initializer$ {\n" 2099 " : $superclass$()$initializer$ {\n"
2100 " if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {\n"
2101 " $initdefaultsname$();\n"
2102 " }\n"
2160 " SharedCtor();\n" 2103 " SharedCtor();\n"
2161 " // @@protoc_insertion_point(constructor:$full_name$)\n" 2104 " // @@protoc_insertion_point(constructor:$full_name$)\n"
2162 "}\n", 2105 "}\n",
2163 "classname", classname_, 2106 "classname", classname_, "superclass", superclass, "full_name",
2164 "superclass", superclass, 2107 descriptor_->full_name(), "initializer", initializer_null,
2165 "full_name", descriptor_->full_name(), 2108 "initdefaultsname", GlobalInitDefaultsName(descriptor_->file()->name()));
2166 "initializer", initializer_null);
2167 2109
2168 if (SupportsArenas(descriptor_)) { 2110 if (SupportsArenas(descriptor_)) {
2169 printer->Print( 2111 printer->Print(
2170 "\n"
2171 "$classname$::$classname$(::google::protobuf::Arena* arena)\n" 2112 "$classname$::$classname$(::google::protobuf::Arena* arena)\n"
2172 " : $initializer$ {\n" 2113 " : $initializer$ {\n"
2114 // When arenas are used it's safe to assume we have finished
2115 // static init time (protos with arenas are unsafe during static init)
2116 "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
2117 " $initdefaultsname$();\n"
2118 "#endif // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
2173 " SharedCtor();\n" 2119 " SharedCtor();\n"
2174 " RegisterArenaDtor(arena);\n" 2120 " RegisterArenaDtor(arena);\n"
2175 " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" 2121 " // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
2176 "}\n", 2122 "}\n",
2177 "initializer", initializer_with_arena, 2123 "initializer", initializer_with_arena, "classname", classname_,
2178 "classname", classname_, 2124 "superclass", superclass, "full_name", descriptor_->full_name(),
2179 "superclass", superclass, 2125 "initdefaultsname",
2180 "full_name", descriptor_->full_name()); 2126 GlobalInitDefaultsName(descriptor_->file()->name()));
2181 } 2127 }
2182 2128
2183 printer->Print(
2184 "\n"
2185 "void $classname$::InitAsDefaultInstance() {\n",
2186 "classname", classname_);
2187
2188 if (!HasFieldPresence(descriptor_->file())) {
2189 printer->Print(
2190 " _is_default_instance_ = true;\n");
2191 }
2192
2193 // The default instance needs all of its embedded message pointers
2194 // cross-linked to other default instances. We can't do this initialization
2195 // in the constructor because some other default instances may not have been
2196 // constructed yet at that time.
2197 // TODO(kenton): Maybe all message fields (even for non-default messages)
2198 // should be initialized to point at default instances rather than NULL?
2199 for (int i = 0; i < descriptor_->field_count(); i++) {
2200 const FieldDescriptor* field = descriptor_->field(i);
2201
2202 if (!field->is_repeated() &&
2203 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
2204 (field->containing_oneof() == NULL ||
2205 HasDescriptorMethods(descriptor_->file(), options_))) {
2206 string name;
2207 if (field->containing_oneof()) {
2208 name = classname_ + "_default_oneof_instance_->";
2209 }
2210 name += FieldName(field);
2211 PrintHandlingOptionalStaticInitializers(
2212 descriptor_->file(), options_, printer,
2213 // With static initializers.
2214 " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
2215 // Without.
2216 " $name$_ = const_cast< $type$*>(\n"
2217 " $type$::internal_default_instance());\n",
2218 // Vars.
2219 "name", name, "type", FieldMessageTypeName(field));
2220 } else if (field->containing_oneof() &&
2221 HasDescriptorMethods(descriptor_->file(), options_)) {
2222 field_generators_.get(descriptor_->field(i))
2223 .GenerateConstructorCode(printer);
2224 }
2225 }
2226 printer->Print(
2227 "}\n"
2228 "\n");
2229
2230 // Generate the copy constructor. 2129 // Generate the copy constructor.
2231 printer->Print( 2130 printer->Print(
2232 "$classname$::$classname$(const $classname$& from)\n" 2131 "$classname$::$classname$(const $classname$& from)\n"
2233 " : $superclass$()", 2132 " : $superclass$()",
2234 "classname", classname_, 2133 "classname", classname_,
2235 "superclass", superclass, 2134 "superclass", superclass,
2236 "full_name", descriptor_->full_name()); 2135 "full_name", descriptor_->full_name());
2237 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 2136 printer->Indent();
2137 printer->Indent();
2138 printer->Indent();
2139
2140 printer->Print(
2141 ",\n_internal_metadata_(NULL)");
2142
2143 if (HasFieldPresence(descriptor_->file())) {
2144 printer->Print(",\n_has_bits_(from._has_bits_)");
2145 }
2146
2147 bool need_to_emit_cached_size = true;
2148 const string cached_size_decl = ",\n_cached_size_(0)";
2149 // We reproduce the logic used for laying out _cached_sized_ in the class
2150 // definition, as to initialize it in-order.
2151 if (HasFieldPresence(descriptor_->file()) &&
2152 (HasBitsSize() % 8) != 0) {
2153 printer->Print(cached_size_decl.c_str());
2154 need_to_emit_cached_size = false;
2155 }
2156
2157 std::vector<bool> processed(optimized_order_.size(), false);
2158 for (int i = 0; i < optimized_order_.size(); ++i) {
2159 const FieldDescriptor* field = optimized_order_[i];
2160
2161 if (!(field->is_repeated() && !(field->is_map()))
2162 ) {
2163 continue;
2164 }
2165
2166 processed[i] = true;
2167 printer->Print(",\n$name$_(from.$name$_)",
2168 "name", FieldName(field));
2169 }
2170
2171 if (need_to_emit_cached_size) {
2172 printer->Print(cached_size_decl.c_str());
2173 need_to_emit_cached_size = false;
2174 }
2175
2176 if (IsAnyMessage(descriptor_)) {
2177 printer->Print(",\n_any_metadata_(&type_url_, &value_)");
2178 }
2179
2180 printer->Outdent();
2181 printer->Outdent();
2182 printer->Print(" {\n");
2183
2184 printer->Print(
2185 "_internal_metadata_.MergeFrom(from._internal_metadata_);\n");
2186
2187 if (descriptor_->extension_range_count() > 0) {
2188 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
2189 }
2190
2191 // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer??
2192 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
2193 if (HasDescriptorMethods(descriptor_->file(), options_) &&
2194 IsMapEntryMessage(descriptor_->nested_type(i))) {
2195 printer->Print(
2196 "const ::google::protobuf::Descriptor*& $type$_descriptor = "
2197 "file_level_metadata[$index$].descriptor;\n",
2198 "type", ClassName(descriptor_->nested_type(i), false), "index",
2199 SimpleItoa(nested_generators_[i]->index_in_metadata_));
2200 }
2201 }
2202
2203 GenerateConstructorBody(printer, processed, true);
2204
2205 // Copy oneof fields. Oneof field requires oneof case check.
2206 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
2238 printer->Print( 2207 printer->Print(
2239 ",\n _internal_metadata_(NULL)"); 2208 "clear_has_$oneofname$();\n"
2240 } else if (!UseUnknownFieldSet(descriptor_->file(), options_)) { 2209 "switch (from.$oneofname$_case()) {\n",
2241 printer->Print(",\n _arena_ptr_(NULL)"); 2210 "oneofname", descriptor_->oneof_decl(i)->name());
2211 printer->Indent();
2212 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2213 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2214 printer->Print(
2215 "case k$field_name$: {\n",
2216 "field_name", UnderscoresToCamelCase(field->name(), true));
2217 printer->Indent();
2218 field_generators_.get(field).GenerateMergingCode(printer);
2219 printer->Print(
2220 "break;\n");
2221 printer->Outdent();
2222 printer->Print(
2223 "}\n");
2224 }
2225 printer->Print(
2226 "case $cap_oneof_name$_NOT_SET: {\n"
2227 " break;\n"
2228 "}\n",
2229 "oneof_index",
2230 SimpleItoa(descriptor_->oneof_decl(i)->index()),
2231 "cap_oneof_name",
2232 ToUpper(descriptor_->oneof_decl(i)->name()));
2233 printer->Outdent();
2234 printer->Print(
2235 "}\n");
2242 } 2236 }
2243 if (IsAnyMessage(descriptor_)) { 2237
2244 printer->Print(",\n _any_metadata_(&type_url_, &value_)"); 2238 printer->Outdent();
2245 }
2246 printer->Print(" {\n");
2247 printer->Print( 2239 printer->Print(
2248 " SharedCtor();\n"
2249 " MergeFrom(from);\n"
2250 " // @@protoc_insertion_point(copy_constructor:$full_name$)\n" 2240 " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
2251 "}\n" 2241 "}\n"
2252 "\n", 2242 "\n",
2253 "classname", classname_,
2254 "superclass", superclass,
2255 "full_name", descriptor_->full_name()); 2243 "full_name", descriptor_->full_name());
2256 2244
2257 // Generate the shared constructor code. 2245 // Generate the shared constructor code.
2258 GenerateSharedConstructorCode(printer); 2246 GenerateSharedConstructorCode(printer);
2259 2247
2260 // Generate the destructor. 2248 // Generate the destructor.
2261 printer->Print( 2249 printer->Print(
2262 "$classname$::~$classname$() {\n" 2250 "$classname$::~$classname$() {\n"
2263 " // @@protoc_insertion_point(destructor:$full_name$)\n" 2251 " // @@protoc_insertion_point(destructor:$full_name$)\n"
2264 " SharedDtor();\n" 2252 " SharedDtor();\n"
(...skipping 16 matching lines...) Expand all
2281 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 2269 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
2282 " _cached_size_ = size;\n" 2270 " _cached_size_ = size;\n"
2283 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 2271 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
2284 "}\n", 2272 "}\n",
2285 "classname", classname_); 2273 "classname", classname_);
2286 2274
2287 // Only generate this member if it's not disabled. 2275 // Only generate this member if it's not disabled.
2288 if (HasDescriptorMethods(descriptor_->file(), options_) && 2276 if (HasDescriptorMethods(descriptor_->file(), options_) &&
2289 !descriptor_->options().no_standard_descriptor_accessor()) { 2277 !descriptor_->options().no_standard_descriptor_accessor()) {
2290 printer->Print( 2278 printer->Print(
2291 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" 2279 "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
2292 " protobuf_AssignDescriptorsOnce();\n" 2280 " protobuf_AssignDescriptorsOnce();\n"
2293 " return $classname$_descriptor_;\n" 2281 " return file_level_metadata[$index$].descriptor;\n"
2294 "}\n" 2282 "}\n"
2295 "\n", 2283 "\n",
2296 "classname", classname_, 2284 "index", SimpleItoa(index_in_metadata_), "classname", classname_);
2297 "adddescriptorsname",
2298 GlobalAddDescriptorsName(descriptor_->file()->name()));
2299 } 2285 }
2300 2286
2301 printer->Print( 2287 printer->Print(
2302 "const $classname$& $classname$::default_instance() {\n", 2288 "const $classname$& $classname$::default_instance() {\n"
2303 "classname", classname_); 2289 " $initdefaultsname$();\n"
2304 2290 " return *internal_default_instance();\n"
2305 PrintHandlingOptionalStaticInitializers( 2291 "}\n\n",
2306 descriptor_->file(), options_, printer, 2292 "classname", classname_, "initdefaultsname",
2307 // With static initializers. 2293 GlobalInitDefaultsName(descriptor_->file()->name()));
2308 " if (default_instance_ == NULL) $adddescriptorsname$();\n",
2309 // Without.
2310 " $adddescriptorsname$();\n",
2311 // Vars.
2312 "adddescriptorsname",
2313 GlobalAddDescriptorsName(descriptor_->file()->name()));
2314
2315 printer->Print(
2316 " return *default_instance_;\n"
2317 "}\n"
2318 "\n"
2319 "$classname$* $classname$::default_instance_ = NULL;\n"
2320 "\n",
2321 "classname", classname_);
2322 2294
2323 if (SupportsArenas(descriptor_)) { 2295 if (SupportsArenas(descriptor_)) {
2324 printer->Print( 2296 printer->Print(
2325 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n " 2297 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n "
2326 " return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n" 2298 " return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n"
2327 "}\n", 2299 "}\n",
2328 "classname", classname_); 2300 "classname", classname_);
2329 } else { 2301 } else {
2330 printer->Print( 2302 printer->Print(
2331 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n " 2303 "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n "
(...skipping 24 matching lines...) Expand all
2356 "void $classname$::Clear() {\n" 2328 "void $classname$::Clear() {\n"
2357 "// @@protoc_insertion_point(message_clear_start:$full_name$)\n", 2329 "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
2358 "classname", classname_, "full_name", descriptor_->full_name()); 2330 "classname", classname_, "full_name", descriptor_->full_name());
2359 printer->Indent(); 2331 printer->Indent();
2360 2332
2361 // Step 1: Extensions 2333 // Step 1: Extensions
2362 if (descriptor_->extension_range_count() > 0) { 2334 if (descriptor_->extension_range_count() > 0) {
2363 printer->Print("_extensions_.Clear();\n"); 2335 printer->Print("_extensions_.Clear();\n");
2364 } 2336 }
2365 2337
2366 // Step 2: Everything but extensions, repeateds, unions. 2338 int last_i = -1;
2367 // These are handled in chunks of 8. The first chunk is 2339 for (int i = 0; i < optimized_order_.size(); ) {
2368 // the non-extensions-non-repeateds-non-unions in 2340 // Detect infinite loops.
2369 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7), 2341 GOOGLE_CHECK_NE(i, last_i);
2370 // and the second chunk is the same for 2342 last_i = i;
2371 // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
2372 // etc.
2373 set<int> step2_indices;
2374 hash_map<string, int> fieldname_to_chunk;
2375 hash_map<int, string> memsets_for_chunk;
2376 hash_map<int, int> memset_field_count_for_chunk;
2377 hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk
2378 hash_map<int, uint32> fields_mask_for_chunk;
2379 for (int i = 0; i < descriptor_->field_count(); i++) {
2380 const FieldDescriptor* field = descriptor_->field(i);
2381 if (!field->is_repeated() && !field->containing_oneof()) {
2382 step2_indices.insert(i);
2383 int chunk = i / 8;
2384 fieldname_to_chunk[FieldName(field)] = chunk;
2385 fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
2386 }
2387 }
2388 2343
2389 // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0. 2344 // Step 2: Repeated fields don't use _has_bits_; emit code to clear them
2390 // The generated code uses two macros to help it clear runs of fields: 2345 // here.
2391 // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the 2346 for (; i < optimized_order_.size(); i++) {
2392 // positions of two fields in the Message. 2347 const FieldDescriptor* field = optimized_order_[i];
2393 // ZR_ zeroes a non-empty range of fields via memset. 2348 const FieldGenerator& generator = field_generators_.get(field);
2394 const char* macros = 2349
2395 "#if defined(__clang__)\n" 2350 if (!field->is_repeated()) {
2396 "#define ZR_HELPER_(f) \\\n" 2351 break;
2397 " _Pragma(\"clang diagnostic push\") \\\n"
2398 " _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
2399 " __builtin_offsetof($classname$, f) \\\n"
2400 " _Pragma(\"clang diagnostic pop\")\n"
2401 "#else\n"
2402 "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
2403 " &reinterpret_cast<$classname$*>(16)->f)\n"
2404 "#endif\n\n"
2405 "#define ZR_(first, last) do {\\\n"
2406 " ::memset(&first, 0,\\\n"
2407 " ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
2408 "} while (0)\n\n";
2409 for (int i = 0; i < runs_of_fields_.size(); i++) {
2410 const vector<string>& run = runs_of_fields_[i];
2411 if (run.size() < 2) continue;
2412 const string& first_field_name = run[0];
2413 const string& last_field_name = run.back();
2414 int chunk = fieldname_to_chunk[run[0]];
2415 memsets_for_chunk[chunk].append(
2416 "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
2417 for (int j = 0; j < run.size(); j++) {
2418 GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
2419 handled.insert(run[j]);
2420 }
2421 memset_field_count_for_chunk[chunk] += run.size();
2422 }
2423 const bool macros_are_needed = handled.size() > 0;
2424 if (macros_are_needed) {
2425 printer->Outdent();
2426 printer->Print(macros,
2427 "classname", classname_);
2428 printer->Indent();
2429 }
2430 // Step 2b: Finish step 2, ignoring fields handled in step 2a.
2431 int last_index = -1;
2432 bool chunk_block_in_progress = false;
2433 for (int i = 0; i < descriptor_->field_count(); i++) {
2434 if (step2_indices.count(i) == 0) continue;
2435 const FieldDescriptor* field = descriptor_->field(i);
2436 const string fieldname = FieldName(field);
2437 if (i / 8 != last_index / 8 || last_index < 0) {
2438 // End previous chunk, if there was one.
2439 if (chunk_block_in_progress) {
2440 printer->Outdent();
2441 printer->Print("}\n");
2442 chunk_block_in_progress = false;
2443 } 2352 }
2444 // Start chunk.
2445 const string& memsets = memsets_for_chunk[i / 8];
2446 uint32 mask = fields_mask_for_chunk[i / 8];
2447 int count = popcnt(mask);
2448 GOOGLE_DCHECK_GE(count, 1);
2449 if (count == 1 ||
2450 (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
2451 // No "if" here because the chunk is trivial.
2452 } else {
2453 if (HasFieldPresence(descriptor_->file())) {
2454 printer->Print(
2455 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
2456 "index", SimpleItoa(i / 8 * 8),
2457 "mask", SimpleItoa(mask));
2458 printer->Indent();
2459 chunk_block_in_progress = true;
2460 }
2461 }
2462 printer->Print(memsets.c_str());
2463 }
2464 last_index = i;
2465 if (handled.count(fieldname) > 0) continue;
2466 2353
2467 // It's faster to just overwrite primitive types, but we should
2468 // only clear strings and messages if they were set.
2469 // TODO(kenton): Let the CppFieldGenerator decide this somehow.
2470 bool should_check_bit =
2471 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
2472 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
2473
2474 bool have_enclosing_if = false;
2475 if (should_check_bit &&
2476 // If no field presence, then always clear strings/messages as well.
2477 HasFieldPresence(descriptor_->file())) {
2478 printer->Print("if (has_$name$()) {\n", "name", fieldname);
2479 printer->Indent();
2480 have_enclosing_if = true;
2481 }
2482
2483 if (use_dependent_base_ && IsFieldDependent(field)) {
2484 printer->Print("clear_$name$();\n", "name", fieldname);
2485 } else {
2486 field_generators_.get(field).GenerateClearingCode(printer);
2487 }
2488
2489 if (have_enclosing_if) {
2490 printer->Outdent();
2491 printer->Print("}\n");
2492 }
2493 }
2494
2495 if (chunk_block_in_progress) {
2496 printer->Outdent();
2497 printer->Print("}\n");
2498 }
2499 if (macros_are_needed) {
2500 printer->Outdent();
2501 printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n");
2502 printer->Indent();
2503 }
2504
2505 // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
2506 for (int i = 0; i < descriptor_->field_count(); i++) {
2507 const FieldDescriptor* field = descriptor_->field(i);
2508
2509 if (field->is_repeated()) {
2510 if (use_dependent_base_ && IsFieldDependent(field)) { 2354 if (use_dependent_base_ && IsFieldDependent(field)) {
2511 printer->Print("clear_$name$();\n", "name", FieldName(field)); 2355 printer->Print("clear_$name$();\n", "name", FieldName(field));
2512 } else { 2356 } else {
2513 field_generators_.get(field).GenerateClearingCode(printer); 2357 generator.GenerateMessageClearingCode(printer);
2358 }
2359 }
2360
2361 // Step 3: Greedily seek runs of fields that can be cleared by
2362 // memset-to-0.
2363 int last_chunk = -1;
2364 int last_chunk_start = -1;
2365 int last_chunk_end = -1;
2366 uint32 last_chunk_mask = 0;
2367
2368 int memset_run_start = -1;
2369 int memset_run_end = -1;
2370 for (; i < optimized_order_.size(); i++) {
2371 const FieldDescriptor* field = optimized_order_[i];
2372
2373 if (!CanInitializeByZeroing(field)) {
2374 break;
2375 }
2376
2377 // "index" defines where in the _has_bits_ the field appears.
2378 // "i" is our loop counter within optimized_order_.
2379 int index = HasFieldPresence(descriptor_->file()) ?
2380 has_bit_indices_[field->index()] : 0;
2381 int chunk = index / 8;
2382
2383 if (last_chunk == -1) {
2384 last_chunk = chunk;
2385 last_chunk_start = i;
2386 } else if (chunk != last_chunk) {
2387 // Emit the fields for this chunk so far.
2388 break;
2389 }
2390
2391 if (memset_run_start == -1) {
2392 memset_run_start = i;
2393 }
2394
2395 memset_run_end = i;
2396 last_chunk_end = i;
2397 last_chunk_mask |= static_cast<uint32>(1) << (index % 32);
2398 }
2399
2400 // Step 4: Non-repeated, non-zero initializable fields.
2401 for (; i < optimized_order_.size(); i++) {
2402 const FieldDescriptor* field = optimized_order_[i];
2403 if (field->is_repeated() || CanInitializeByZeroing(field)) {
2404 break;
2405 }
2406
2407 // "index" defines where in the _has_bits_ the field appears.
2408 // "i" is our loop counter within optimized_order_.
2409 int index = HasFieldPresence(descriptor_->file()) ?
2410 has_bit_indices_[field->index()] : 0;
2411 int chunk = index / 8;
2412
2413 if (last_chunk == -1) {
2414 last_chunk = chunk;
2415 last_chunk_start = i;
2416 } else if (chunk != last_chunk) {
2417 // Emit the fields for this chunk so far.
2418 break;
2419 }
2420
2421 last_chunk_end = i;
2422 last_chunk_mask |= static_cast<uint32>(1) << (index % 32);
2423 }
2424
2425 if (last_chunk != -1) {
2426 GOOGLE_DCHECK_NE(-1, last_chunk_start);
2427 GOOGLE_DCHECK_NE(-1, last_chunk_end);
2428 GOOGLE_DCHECK_NE(0, last_chunk_mask);
2429
2430 const int count = popcnt(last_chunk_mask);
2431 const bool have_outer_if = HasFieldPresence(descriptor_->file()) &&
2432 (last_chunk_start != last_chunk_end);
2433
2434 if (have_outer_if) {
2435 // Check (up to) 8 has_bits at a time if we have more than one field in
2436 // this chunk. Due to field layout ordering, we may check
2437 // _has_bits_[last_chunk * 8 / 32] multiple times.
2438 GOOGLE_DCHECK_LE(2, count);
2439 GOOGLE_DCHECK_GE(8, count);
2440
2441 printer->Print(
2442 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
2443 "index", SimpleItoa(last_chunk * 8),
2444 "mask", SimpleItoa(last_chunk_mask));
2445 printer->Indent();
2446 }
2447
2448 if (memset_run_start != -1) {
2449 if (memset_run_start == memset_run_end) {
2450 // For clarity, do not memset a single field.
2451 const FieldGenerator& generator =
2452 field_generators_.get(optimized_order_[memset_run_start]);
2453 generator.GenerateMessageClearingCode(printer);
2454 } else {
2455 const string first_field_name =
2456 FieldName(optimized_order_[memset_run_start]);
2457 const string last_field_name =
2458 FieldName(optimized_order_[memset_run_end]);
2459
2460 printer->Print(
2461 "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n"
2462 " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n",
2463 "first", first_field_name,
2464 "last", last_field_name);
2465 }
2466
2467 // Advance last_chunk_start to skip over the fields we zeroed/memset.
2468 last_chunk_start = memset_run_end + 1;
2469 }
2470
2471 // Go back and emit clears for each of the fields we processed.
2472 for (int j = last_chunk_start; j <= last_chunk_end; j++) {
2473 const FieldDescriptor* field = optimized_order_[j];
2474 const string fieldname = FieldName(field);
2475 const FieldGenerator& generator = field_generators_.get(field);
2476
2477 // It's faster to just overwrite primitive types, but we should only
2478 // clear strings and messages if they were set.
2479 //
2480 // TODO(kenton): Let the CppFieldGenerator decide this somehow.
2481 bool should_check_bit =
2482 field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
2483 field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
2484
2485 bool have_enclosing_if = false;
2486 if (should_check_bit &&
2487 // If no field presence, then always clear strings/messages as well.
2488 HasFieldPresence(descriptor_->file())) {
2489 printer->Print("if (has_$name$()) {\n", "name", fieldname);
2490 printer->Indent();
2491 have_enclosing_if = true;
2492 }
2493
2494 generator.GenerateMessageClearingCode(printer);
2495
2496 if (have_enclosing_if) {
2497 printer->Outdent();
2498 printer->Print("}\n");
2499 }
2500 }
2501
2502 if (have_outer_if) {
2503 printer->Outdent();
2504 printer->Print("}\n");
2514 } 2505 }
2515 } 2506 }
2516 } 2507 }
2517 2508
2518 // Step 4: Unions. 2509 // Step 4: Unions.
2519 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 2510 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2520 printer->Print( 2511 printer->Print(
2521 "clear_$oneof_name$();\n", 2512 "clear_$oneof_name$();\n",
2522 "oneof_name", descriptor_->oneof_decl(i)->name()); 2513 "oneof_name", descriptor_->oneof_decl(i)->name());
2523 } 2514 }
2524 2515
2525 if (HasFieldPresence(descriptor_->file())) { 2516 if (HasFieldPresence(descriptor_->file())) {
2526 // Step 5: Everything else. 2517 // Step 5: Everything else.
2527 printer->Print( 2518 printer->Print("_has_bits_.Clear();\n");
2528 "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
2529 } 2519 }
2530 2520
2531 if (PreserveUnknownFields(descriptor_)) { 2521 if (PreserveUnknownFields(descriptor_)) {
2532 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 2522 printer->Print("_internal_metadata_.Clear();\n");
2533 printer->Print(
2534 "if (_internal_metadata_.have_unknown_fields()) {\n"
2535 " mutable_unknown_fields()->Clear();\n"
2536 "}\n");
2537 } else {
2538 if (SupportsArenas(descriptor_)) {
2539 printer->Print(
2540 "_unknown_fields_.ClearToEmpty(\n"
2541 " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
2542 " GetArenaNoVirtual());\n");
2543 } else {
2544 printer->Print(
2545 "_unknown_fields_.ClearToEmptyNoArena(\n"
2546 " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n" );
2547 }
2548 }
2549 } 2523 }
2550 2524
2551 printer->Outdent(); 2525 printer->Outdent();
2552 printer->Print("}\n"); 2526 printer->Print("}\n");
2553 } 2527 }
2554 2528
2555 void MessageGenerator:: 2529 void MessageGenerator::
2556 GenerateOneofClear(io::Printer* printer) { 2530 GenerateOneofClear(io::Printer* printer) {
2557 // Generated function clears the active field and union case (e.g. foo_case_). 2531 // Generated function clears the active field and union case (e.g. foo_case_).
2558 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 2532 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2559 map<string, string> oneof_vars; 2533 std::map<string, string> oneof_vars;
2560 oneof_vars["classname"] = classname_; 2534 oneof_vars["classname"] = classname_;
2561 oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name(); 2535 oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
2562 oneof_vars["full_name"] = descriptor_->full_name(); 2536 oneof_vars["full_name"] = descriptor_->full_name();
2563 string message_class; 2537 string message_class;
2564 2538
2565 printer->Print(oneof_vars, 2539 printer->Print(oneof_vars,
2566 "void $classname$::clear_$oneofname$() {\n" 2540 "void $classname$::clear_$oneofname$() {\n"
2567 "// @@protoc_insertion_point(one_of_clear_start:" 2541 "// @@protoc_insertion_point(one_of_clear_start:"
2568 "$full_name$)\n"); 2542 "$full_name$)\n");
2569 printer->Indent(); 2543 printer->Indent();
2570 printer->Print(oneof_vars, 2544 printer->Print(oneof_vars,
2571 "switch($oneofname$_case()) {\n"); 2545 "switch ($oneofname$_case()) {\n");
2572 printer->Indent(); 2546 printer->Indent();
2573 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 2547 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2574 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 2548 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2575 printer->Print( 2549 printer->Print(
2576 "case k$field_name$: {\n", 2550 "case k$field_name$: {\n",
2577 "field_name", UnderscoresToCamelCase(field->name(), true)); 2551 "field_name", UnderscoresToCamelCase(field->name(), true));
2578 printer->Indent(); 2552 printer->Indent();
2579 // We clear only allocated objects in oneofs 2553 // We clear only allocated objects in oneofs
2580 if (!IsStringOrMessage(field)) { 2554 if (!IsStringOrMessage(field)) {
2581 printer->Print( 2555 printer->Print(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2615 // Generate the Swap member function. This is a lightweight wrapper around 2589 // Generate the Swap member function. This is a lightweight wrapper around
2616 // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory 2590 // UnsafeArenaSwap() / MergeFrom() with temporaries, depending on the memory
2617 // ownership situation: swapping across arenas or between an arena and a 2591 // ownership situation: swapping across arenas or between an arena and a
2618 // heap requires copying. 2592 // heap requires copying.
2619 printer->Print( 2593 printer->Print(
2620 "GOOGLE_ATTRIBUTE_NOINLINE void $classname$::Swap($classname$* other) {\ n" 2594 "GOOGLE_ATTRIBUTE_NOINLINE void $classname$::Swap($classname$* other) {\ n"
2621 " if (other == this) return;\n" 2595 " if (other == this) return;\n"
2622 " if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n" 2596 " if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n"
2623 " InternalSwap(other);\n" 2597 " InternalSwap(other);\n"
2624 " } else {\n" 2598 " } else {\n"
2625 " $classname$ temp;\n" 2599 " $classname$* temp = New(GetArenaNoVirtual());\n"
2626 " temp.MergeFrom(*this);\n" 2600 " temp->MergeFrom(*other);\n"
2627 " CopyFrom(*other);\n" 2601 " other->CopyFrom(*this);\n"
2628 " other->CopyFrom(temp);\n" 2602 " InternalSwap(temp);\n"
2603 " if (GetArenaNoVirtual() == NULL) {\n"
2604 " delete temp;\n"
2605 " }\n"
2629 " }\n" 2606 " }\n"
2630 "}\n" 2607 "}\n"
2631 "void $classname$::UnsafeArenaSwap($classname$* other) {\n" 2608 "void $classname$::UnsafeArenaSwap($classname$* other) {\n"
2632 " if (other == this) return;\n" 2609 " if (other == this) return;\n"
2633 " GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n" 2610 " GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n"
2634 " InternalSwap(other);\n" 2611 " InternalSwap(other);\n"
2635 "}\n", 2612 "}\n",
2636 "classname", classname_); 2613 "classname", classname_);
2637 } else { 2614 } else {
2638 printer->Print( 2615 printer->Print(
2639 "void $classname$::Swap($classname$* other) {\n" 2616 "void $classname$::Swap($classname$* other) {\n"
2640 " if (other == this) return;\n" 2617 " if (other == this) return;\n"
2641 " InternalSwap(other);\n" 2618 " InternalSwap(other);\n"
2642 "}\n", 2619 "}\n",
2643 "classname", classname_); 2620 "classname", classname_);
2644 } 2621 }
2645 2622
2646 // Generate the UnsafeArenaSwap member function. 2623 // Generate the UnsafeArenaSwap member function.
2647 printer->Print("void $classname$::InternalSwap($classname$* other) {\n", 2624 printer->Print("void $classname$::InternalSwap($classname$* other) {\n",
2648 "classname", classname_); 2625 "classname", classname_);
2649 printer->Indent(); 2626 printer->Indent();
2650 2627
2651 if (HasGeneratedMethods(descriptor_->file(), options_)) { 2628 if (HasGeneratedMethods(descriptor_->file(), options_)) {
2652 for (int i = 0; i < descriptor_->field_count(); i++) { 2629 for (int i = 0; i < optimized_order_.size(); i++) {
2653 const FieldDescriptor* field = descriptor_->field(i); 2630 // optimized_order_ does not contain oneof fields, but the field
2631 // generators for these fields do not emit swapping code on their own.
2632 const FieldDescriptor* field = optimized_order_[i];
2654 field_generators_.get(field).GenerateSwappingCode(printer); 2633 field_generators_.get(field).GenerateSwappingCode(printer);
2655 } 2634 }
2656 2635
2657 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 2636 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2658 printer->Print( 2637 printer->Print(
2659 "std::swap($oneof_name$_, other->$oneof_name$_);\n" 2638 "std::swap($oneof_name$_, other->$oneof_name$_);\n"
2660 "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", 2639 "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
2661 "oneof_name", descriptor_->oneof_decl(i)->name(), 2640 "oneof_name", descriptor_->oneof_decl(i)->name(),
2662 "i", SimpleItoa(i)); 2641 "i", SimpleItoa(i));
2663 } 2642 }
2664 2643
2665 if (HasFieldPresence(descriptor_->file())) { 2644 if (HasFieldPresence(descriptor_->file())) {
2666 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) { 2645 for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
2667 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", 2646 printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
2668 "i", SimpleItoa(i)); 2647 "i", SimpleItoa(i));
2669 } 2648 }
2670 } 2649 }
2671 2650
2672 // Ignore PreserveUnknownFields here - always swap internal_metadata as it 2651 if (PreserveUnknownFields(descriptor_)) {
2673 // may contain more than just unknown fields. 2652 printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n") ;
2674 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2675 printer->Print(
2676 "_internal_metadata_.Swap(&other->_internal_metadata_);\n");
2677 } else {
2678 printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
2679 } 2653 }
2680 2654
2681 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); 2655 printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
2682 if (descriptor_->extension_range_count() > 0) { 2656 if (descriptor_->extension_range_count() > 0) {
2683 printer->Print("_extensions_.Swap(&other->_extensions_);\n"); 2657 printer->Print("_extensions_.Swap(&other->_extensions_);\n");
2684 } 2658 }
2685 } else { 2659 } else {
2686 printer->Print("GetReflection()->Swap(this, other);"); 2660 printer->Print("GetReflection()->Swap(this, other);");
2687 } 2661 }
2688 2662
2689 printer->Outdent(); 2663 printer->Outdent();
2690 printer->Print("}\n"); 2664 printer->Print("}\n");
2691 } 2665 }
2692 2666
2693 void MessageGenerator:: 2667 void MessageGenerator::
2694 GenerateMergeFrom(io::Printer* printer) { 2668 GenerateMergeFrom(io::Printer* printer) {
2695 if (HasDescriptorMethods(descriptor_->file(), options_)) { 2669 if (HasDescriptorMethods(descriptor_->file(), options_)) {
2696 // Generate the generalized MergeFrom (aka that which takes in the Message 2670 // Generate the generalized MergeFrom (aka that which takes in the Message
2697 // base class as a parameter). 2671 // base class as a parameter).
2698 printer->Print( 2672 printer->Print(
2699 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\ n" 2673 "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\ n"
2700 "// @@protoc_insertion_point(generalized_merge_from_start:" 2674 "// @@protoc_insertion_point(generalized_merge_from_start:"
2701 "$full_name$)\n" 2675 "$full_name$)\n"
2702 " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n", 2676 " GOOGLE_DCHECK_NE(&from, this);\n",
2703 "classname", classname_, "full_name", descriptor_->full_name()); 2677 "classname", classname_, "full_name", descriptor_->full_name());
2704 printer->Indent(); 2678 printer->Indent();
2705 2679
2706 // Cast the message to the proper type. If we find that the message is 2680 // Cast the message to the proper type. If we find that the message is
2707 // *not* of the proper type, we can still call Merge via the reflection 2681 // *not* of the proper type, we can still call Merge via the reflection
2708 // system, as the GOOGLE_CHECK above ensured that we have the same descripto r 2682 // system, as the GOOGLE_CHECK above ensured that we have the same descripto r
2709 // for each message. 2683 // for each message.
2710 printer->Print( 2684 printer->Print(
2711 "const $classname$* source = \n" 2685 "const $classname$* source =\n"
2712 " ::google::protobuf::internal::DynamicCastToGenerated<const $classname $>(\n" 2686 " ::google::protobuf::internal::DynamicCastToGenerated<const $classname $>(\n"
2713 " &from);\n" 2687 " &from);\n"
2714 "if (source == NULL) {\n" 2688 "if (source == NULL) {\n"
2715 "// @@protoc_insertion_point(generalized_merge_from_cast_fail:" 2689 "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
2716 "$full_name$)\n" 2690 "$full_name$)\n"
2717 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" 2691 " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
2718 "} else {\n" 2692 "} else {\n"
2719 "// @@protoc_insertion_point(generalized_merge_from_cast_success:" 2693 "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
2720 "$full_name$)\n" 2694 "$full_name$)\n"
2721 " MergeFrom(*source);\n" 2695 " MergeFrom(*source);\n"
(...skipping 11 matching lines...) Expand all
2733 "}\n" 2707 "}\n"
2734 "\n", 2708 "\n",
2735 "classname", classname_); 2709 "classname", classname_);
2736 } 2710 }
2737 2711
2738 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and ca st. 2712 // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and ca st.
2739 printer->Print( 2713 printer->Print(
2740 "void $classname$::MergeFrom(const $classname$& from) {\n" 2714 "void $classname$::MergeFrom(const $classname$& from) {\n"
2741 "// @@protoc_insertion_point(class_specific_merge_from_start:" 2715 "// @@protoc_insertion_point(class_specific_merge_from_start:"
2742 "$full_name$)\n" 2716 "$full_name$)\n"
2743 " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n", 2717 " GOOGLE_DCHECK_NE(&from, this);\n",
2744 "classname", classname_, "full_name", descriptor_->full_name()); 2718 "classname", classname_, "full_name", descriptor_->full_name());
2745 printer->Indent(); 2719 printer->Indent();
2746 2720
2747 // Merge Repeated fields. These fields do not require a 2721 if (descriptor_->extension_range_count() > 0) {
2748 // check as we can simply iterate over them. 2722 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
2749 for (int i = 0; i < descriptor_->field_count(); ++i) { 2723 }
2750 const FieldDescriptor* field = descriptor_->field(i);
2751 2724
2752 if (field->is_repeated()) { 2725 printer->Print(
2753 field_generators_.get(field).GenerateMergingCode(printer); 2726 "_internal_metadata_.MergeFrom(from._internal_metadata_);\n");
2727
2728 int last_i = -1;
2729 for (int i = 0; i < optimized_order_.size(); ) {
2730 // Detect infinite loops.
2731 GOOGLE_CHECK_NE(i, last_i);
2732 last_i = i;
2733
2734 // Merge Repeated fields. These fields do not require a
2735 // check as we can simply iterate over them.
2736 for (; i < optimized_order_.size(); i++) {
2737 const FieldDescriptor* field = optimized_order_[i];
2738 if (!field->is_repeated()) {
2739 break;
2740 }
2741
2742 const FieldGenerator& generator = field_generators_.get(field);
2743 generator.GenerateMergingCode(printer);
2744 }
2745
2746 // Merge Optional and Required fields (after a _has_bit check).
2747 int last_chunk = -1;
2748 int last_chunk_start = -1;
2749 int last_chunk_end = -1;
2750 uint32 last_chunk_mask = 0;
2751 for (; i < optimized_order_.size(); i++) {
2752 const FieldDescriptor* field = optimized_order_[i];
2753 if (field->is_repeated()) {
2754 break;
2755 }
2756
2757 // "index" defines where in the _has_bits_ the field appears.
2758 // "i" is our loop counter within optimized_order_.
2759 int index = HasFieldPresence(descriptor_->file()) ?
2760 has_bit_indices_[field->index()] : 0;
2761 int chunk = index / 8;
2762
2763 if (last_chunk == -1) {
2764 last_chunk = chunk;
2765 last_chunk_start = i;
2766 } else if (chunk != last_chunk) {
2767 // Emit the fields for this chunk so far.
2768 break;
2769 }
2770
2771 last_chunk_end = i;
2772 last_chunk_mask |= static_cast<uint32>(1) << (index % 32);
2773 }
2774
2775 if (last_chunk != -1) {
2776 GOOGLE_DCHECK_NE(-1, last_chunk_start);
2777 GOOGLE_DCHECK_NE(-1, last_chunk_end);
2778 GOOGLE_DCHECK_NE(0, last_chunk_mask);
2779
2780 const int count = popcnt(last_chunk_mask);
2781 const bool have_outer_if = HasFieldPresence(descriptor_->file()) &&
2782 (last_chunk_start != last_chunk_end);
2783
2784 if (have_outer_if) {
2785 // Check (up to) 8 has_bits at a time if we have more than one field in
2786 // this chunk. Due to field layout ordering, we may check
2787 // _has_bits_[last_chunk * 8 / 32] multiple times.
2788 GOOGLE_DCHECK_LE(2, count);
2789 GOOGLE_DCHECK_GE(8, count);
2790
2791 printer->Print(
2792 "if (from._has_bits_[$index$ / 32] & $mask$u) {\n",
2793 "index", SimpleItoa(last_chunk * 8),
2794 "mask", SimpleItoa(last_chunk_mask));
2795 printer->Indent();
2796 }
2797
2798 // Go back and emit clears for each of the fields we processed.
2799 for (int j = last_chunk_start; j <= last_chunk_end; j++) {
2800 const FieldDescriptor* field = optimized_order_[j];
2801 const FieldGenerator& generator = field_generators_.get(field);
2802
2803 bool have_enclosing_if = false;
2804 if (HasFieldPresence(descriptor_->file())) {
2805 printer->Print(
2806 "if (from.has_$name$()) {\n",
2807 "name", FieldName(field));
2808 printer->Indent();
2809 have_enclosing_if = true;
2810 } else {
2811 // Merge semantics without true field presence: primitive fields are
2812 // merged only if non-zero (numeric) or non-empty (string).
2813 have_enclosing_if = EmitFieldNonDefaultCondition(
2814 printer, "from.", field);
2815 }
2816
2817 generator.GenerateMergingCode(printer);
2818
2819 if (have_enclosing_if) {
2820 printer->Outdent();
2821 printer->Print("}\n");
2822 }
2823 }
2824
2825 if (have_outer_if) {
2826 printer->Outdent();
2827 printer->Print("}\n");
2828 }
2754 } 2829 }
2755 } 2830 }
2756 2831
2757 // Merge oneof fields. Oneof field requires oneof case check. 2832 // Merge oneof fields. Oneof field requires oneof case check.
2758 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { 2833 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
2759 printer->Print( 2834 printer->Print(
2760 "switch (from.$oneofname$_case()) {\n", 2835 "switch (from.$oneofname$_case()) {\n",
2761 "oneofname", descriptor_->oneof_decl(i)->name()); 2836 "oneofname", descriptor_->oneof_decl(i)->name());
2762 printer->Indent(); 2837 printer->Indent();
2763 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 2838 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
(...skipping 13 matching lines...) Expand all
2777 "case $cap_oneof_name$_NOT_SET: {\n" 2852 "case $cap_oneof_name$_NOT_SET: {\n"
2778 " break;\n" 2853 " break;\n"
2779 "}\n", 2854 "}\n",
2780 "cap_oneof_name", 2855 "cap_oneof_name",
2781 ToUpper(descriptor_->oneof_decl(i)->name())); 2856 ToUpper(descriptor_->oneof_decl(i)->name()));
2782 printer->Outdent(); 2857 printer->Outdent();
2783 printer->Print( 2858 printer->Print(
2784 "}\n"); 2859 "}\n");
2785 } 2860 }
2786 2861
2787 // Merge Optional and Required fields (after a _has_bit check).
2788 int last_index = -1;
2789
2790 for (int i = 0; i < descriptor_->field_count(); ++i) {
2791 const FieldDescriptor* field = descriptor_->field(i);
2792
2793 if (!field->is_repeated() && !field->containing_oneof()) {
2794 if (HasFieldPresence(descriptor_->file())) {
2795 // See above in GenerateClear for an explanation of this.
2796 if (i / 8 != last_index / 8 || last_index < 0) {
2797 if (last_index >= 0) {
2798 printer->Outdent();
2799 printer->Print("}\n");
2800 }
2801 printer->Print(
2802 "if (from._has_bits_[$index$ / 32] & "
2803 "(0xffu << ($index$ % 32))) {\n",
2804 "index", SimpleItoa(field->index()));
2805 printer->Indent();
2806 }
2807 }
2808
2809 last_index = i;
2810
2811 bool have_enclosing_if = false;
2812 if (HasFieldPresence(descriptor_->file())) {
2813 printer->Print(
2814 "if (from.has_$name$()) {\n",
2815 "name", FieldName(field));
2816 printer->Indent();
2817 have_enclosing_if = true;
2818 } else {
2819 // Merge semantics without true field presence: primitive fields are
2820 // merged only if non-zero (numeric) or non-empty (string).
2821 have_enclosing_if = EmitFieldNonDefaultCondition(
2822 printer, "from.", field);
2823 }
2824
2825 field_generators_.get(field).GenerateMergingCode(printer);
2826
2827 if (have_enclosing_if) {
2828 printer->Outdent();
2829 printer->Print("}\n");
2830 }
2831 }
2832 }
2833
2834 if (HasFieldPresence(descriptor_->file()) &&
2835 last_index >= 0) {
2836 printer->Outdent();
2837 printer->Print("}\n");
2838 }
2839
2840 if (descriptor_->extension_range_count() > 0) {
2841 printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
2842 }
2843
2844 if (PreserveUnknownFields(descriptor_)) {
2845 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
2846 printer->Print(
2847 "if (from._internal_metadata_.have_unknown_fields()) {\n"
2848 " mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"
2849 "}\n");
2850 } else {
2851 printer->Print(
2852 "if (!from.unknown_fields().empty()) {\n"
2853 " mutable_unknown_fields()->append(from.unknown_fields());\n"
2854 "}\n");
2855 }
2856 }
2857
2858 printer->Outdent(); 2862 printer->Outdent();
2859 printer->Print("}\n"); 2863 printer->Print("}\n");
2860 } 2864 }
2861 2865
2862 void MessageGenerator:: 2866 void MessageGenerator::
2863 GenerateCopyFrom(io::Printer* printer) { 2867 GenerateCopyFrom(io::Printer* printer) {
2864 if (HasDescriptorMethods(descriptor_->file(), options_)) { 2868 if (HasDescriptorMethods(descriptor_->file(), options_)) {
2865 // Generate the generalized CopyFrom (aka that which takes in the Message 2869 // Generate the generalized CopyFrom (aka that which takes in the Message
2866 // base class as a parameter). 2870 // base class as a parameter).
2867 printer->Print( 2871 printer->Print(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 2903
2900 void MessageGenerator:: 2904 void MessageGenerator::
2901 GenerateMergeFromCodedStream(io::Printer* printer) { 2905 GenerateMergeFromCodedStream(io::Printer* printer) {
2902 if (descriptor_->options().message_set_wire_format()) { 2906 if (descriptor_->options().message_set_wire_format()) {
2903 // Special-case MessageSet. 2907 // Special-case MessageSet.
2904 printer->Print( 2908 printer->Print(
2905 "bool $classname$::MergePartialFromCodedStream(\n" 2909 "bool $classname$::MergePartialFromCodedStream(\n"
2906 " ::google::protobuf::io::CodedInputStream* input) {\n", 2910 " ::google::protobuf::io::CodedInputStream* input) {\n",
2907 "classname", classname_); 2911 "classname", classname_);
2908 2912
2909 PrintHandlingOptionalStaticInitializers( 2913 printer->Print(
2910 descriptor_->file(), options_, printer, 2914 " return _extensions_.ParseMessageSet(input, "
2911 // With static initializers. 2915 "internal_default_instance(),\n"
2912 " return _extensions_.ParseMessageSet(input, default_instance_,\n"
2913 " mutable_unknown_fields());\n",
2914 // Without.
2915 " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
2916 " mutable_unknown_fields());\n", 2916 " mutable_unknown_fields());\n",
2917 // Vars. 2917 // Vars.
2918 "classname", classname_); 2918 "classname", classname_);
2919 2919
2920 printer->Print( 2920 printer->Print(
2921 "}\n"); 2921 "}\n");
2922 return; 2922 return;
2923 } 2923 }
2924 2924
2925 printer->Print( 2925 printer->Print(
2926 "bool $classname$::MergePartialFromCodedStream(\n" 2926 "bool $classname$::MergePartialFromCodedStream(\n"
2927 " ::google::protobuf::io::CodedInputStream* input) {\n" 2927 " ::google::protobuf::io::CodedInputStream* input) {\n"
2928 "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\ n" 2928 "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\ n"
2929 " ::google::protobuf::uint32 tag;\n", 2929 " ::google::protobuf::uint32 tag;\n",
2930 "classname", classname_); 2930 "classname", classname_);
2931 2931
2932 if (PreserveUnknownFields(descriptor_) && 2932 if (PreserveUnknownFields(descriptor_) &&
2933 !UseUnknownFieldSet(descriptor_->file(), options_)) { 2933 !UseUnknownFieldSet(descriptor_->file(), options_)) {
2934 // Use LazyStringOutputString to avoid initializing unknown fields string 2934 // Use LazyStringOutputString to avoid initializing unknown fields string
2935 // unless it is actually needed. For the same reason, disable eager refresh 2935 // unless it is actually needed. For the same reason, disable eager refresh
2936 // on the CodedOutputStream. 2936 // on the CodedOutputStream.
2937 printer->Print( 2937 printer->Print(
2938 " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n " 2938 " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n "
2939 " ::google::protobuf::internal::NewPermanentCallback(\n" 2939 " NewPermanentCallback(\n"
2940 " &MutableUnknownFieldsFor$classname$, this));\n" 2940 " &MutableUnknownFieldsFor$classname$, this));\n"
2941 " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n" 2941 " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
2942 " &unknown_fields_string, false);\n", 2942 " &unknown_fields_string, false);\n",
2943 "classname", classname_); 2943 "classname", classname_);
2944 } 2944 }
2945 2945
2946 printer->Print( 2946 printer->Print(
2947 " // @@protoc_insertion_point(parse_start:$full_name$)\n", 2947 " // @@protoc_insertion_point(parse_start:$full_name$)\n",
2948 "full_name", descriptor_->full_name()); 2948 "full_name", descriptor_->full_name());
2949 2949
2950 printer->Indent(); 2950 printer->Indent();
2951 printer->Print("for (;;) {\n"); 2951 printer->Print("for (;;) {\n");
2952 printer->Indent(); 2952 printer->Indent();
2953 2953
2954 google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields( 2954 std::vector<const FieldDescriptor*> ordered_fields =
2955 SortFieldsByNumber(descriptor_)); 2955 SortFieldsByNumber(descriptor_);
2956 uint32 maxtag = descriptor_->field_count() == 0 ? 0 : 2956 uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
2957 WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]); 2957 WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
2958 const int kCutoff0 = 127; // fits in 1-byte varint 2958 const int kCutoff0 = 127; // fits in 1-byte varint
2959 const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint 2959 const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint
2960
2961 // We need to capture the last tag when parsing if this is a Group type, as
2962 // our caller will verify (via CodedInputStream::LastTagWas) that the correct
2963 // closing tag was received.
2964 bool capture_last_tag = false;
2965 const Descriptor* parent = descriptor_->containing_type();
2966 if (parent) {
2967 for (int i = 0; i < parent->field_count(); i++) {
2968 const FieldDescriptor* field = parent->field(i);
2969 if (field->type() == FieldDescriptor::TYPE_GROUP &&
2970 field->message_type() == descriptor_) {
2971 capture_last_tag = true;
2972 break;
2973 }
2974 }
2975 }
2976
2977 for (int i = 0; i < descriptor_->file()->extension_count(); i++) {
2978 const FieldDescriptor* field = descriptor_->file()->extension(i);
2979 if (field->type() == FieldDescriptor::TYPE_GROUP &&
2980 field->message_type() == descriptor_) {
2981 capture_last_tag = true;
2982 break;
2983 }
2984 }
2985
2960 printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = " 2986 printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
2961 "input->ReadTagWithCutoff($max$);\n" 2987 "input->ReadTagWithCutoff$lasttag$($max$u);\n"
2962 "tag = p.first;\n" 2988 "tag = p.first;\n"
2963 "if (!p.second) goto handle_unusual;\n", 2989 "if (!p.second) goto handle_unusual;\n",
2964 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 : 2990 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
2965 (maxtag <= kCutoff1 ? kCutoff1 : 2991 (maxtag <= kCutoff1 ? kCutoff1 :
2966 maxtag))); 2992 maxtag)),
2993 "lasttag", !capture_last_tag ? "NoLastTag" : "");
2994
2967 if (descriptor_->field_count() > 0) { 2995 if (descriptor_->field_count() > 0) {
2968 // We don't even want to print the switch() if we have no fields because 2996 // We don't even want to print the switch() if we have no fields because
2969 // MSVC dislikes switch() statements that contain only a default value. 2997 // MSVC dislikes switch() statements that contain only a default value.
2970 2998
2971 // Note: If we just switched on the tag rather than the field number, we 2999 // Note: If we just switched on the tag rather than the field number, we
2972 // could avoid the need for the if() to check the wire type at the beginning 3000 // could avoid the need for the if() to check the wire type at the beginning
2973 // of each case. However, this is actually a bit slower in practice as it 3001 // of each case. However, this is actually a bit slower in practice as it
2974 // creates a jump table that is 8x larger and sparser, and meanwhile the 3002 // creates a jump table that is 8x larger and sparser, and meanwhile the
2975 // if()s are highly predictable. 3003 // if()s are highly predictable.
3004 //
3005 // Historically, we inserted checks to peek at the next tag on the wire and
3006 // jump directly to the next case statement. While this avoids the jump
3007 // table that the switch uses, it greatly increases code size (20-60%) and
3008 // inserts branches that may fail (especially for real world protos that
3009 // interleave--in field number order--hot and cold fields). Loadtests
3010 // confirmed that removing this optimization is performance neutral.
2976 printer->Print("switch (::google::protobuf::internal::WireFormatLite::" 3011 printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
2977 "GetTagFieldNumber(tag)) {\n"); 3012 "GetTagFieldNumber(tag)) {\n");
2978 3013
2979 printer->Indent(); 3014 printer->Indent();
2980 3015
2981 // Find repeated messages and groups now, to simplify what follows. 3016 // Find repeated messages and groups now, to simplify what follows.
2982 hash_set<int> fields_with_parse_loop; 3017 hash_set<int> fields_with_parse_loop;
2983 for (int i = 0; i < descriptor_->field_count(); i++) { 3018 for (int i = 0; i < ordered_fields.size(); i++) {
2984 const FieldDescriptor* field = ordered_fields[i]; 3019 const FieldDescriptor* field = ordered_fields[i];
2985 if (field->is_repeated() && 3020 if (field->is_repeated() &&
2986 (field->type() == FieldDescriptor::TYPE_MESSAGE || 3021 (field->type() == FieldDescriptor::TYPE_MESSAGE ||
2987 field->type() == FieldDescriptor::TYPE_GROUP)) { 3022 field->type() == FieldDescriptor::TYPE_GROUP)) {
2988 fields_with_parse_loop.insert(i); 3023 fields_with_parse_loop.insert(i);
2989 } 3024 }
2990 } 3025 }
2991 3026
2992 // need_label is true if we generated "goto parse_$name$" while handling the 3027 for (int i = 0; i < ordered_fields.size(); i++) {
2993 // previous field.
2994 bool need_label = false;
2995 for (int i = 0; i < descriptor_->field_count(); i++) {
2996 const FieldDescriptor* field = ordered_fields[i]; 3028 const FieldDescriptor* field = ordered_fields[i];
2997 const bool loops = fields_with_parse_loop.count(i) > 0; 3029 const bool loops = fields_with_parse_loop.count(i) > 0;
2998 const bool next_field_loops = fields_with_parse_loop.count(i + 1) > 0;
2999 3030
3000 PrintFieldComment(printer, field); 3031 PrintFieldComment(printer, field);
3001 3032
3002 printer->Print( 3033 printer->Print(
3003 "case $number$: {\n", 3034 "case $number$: {\n",
3004 "number", SimpleItoa(field->number())); 3035 "number", SimpleItoa(field->number()));
3005 printer->Indent(); 3036 printer->Indent();
3006 const FieldGenerator& field_generator = field_generators_.get(field); 3037 const FieldGenerator& field_generator = field_generators_.get(field);
3007 3038
3008 // Emit code to parse the common, expected case. 3039 // Emit code to parse the common, expected case.
3009 printer->Print("if (tag == $commontag$) {\n", 3040 printer->Print("if (tag == $commontag$u) {\n",
3010 "commontag", SimpleItoa(WireFormat::MakeTag(field))); 3041 "commontag", SimpleItoa(WireFormat::MakeTag(field)));
3011 3042
3012 if (need_label ||
3013 (field->is_repeated() && !field->is_packed() && !loops)) {
3014 printer->Print(
3015 " parse_$name$:\n",
3016 "name", field->name());
3017 }
3018 if (loops) { 3043 if (loops) {
3019 printer->Print( 3044 printer->Print(" DO_(input->IncrementRecursionDepth());\n");
3020 " DO_(input->IncrementRecursionDepth());\n"
3021 " parse_loop_$name$:\n",
3022 "name", field->name());
3023 } 3045 }
3024 3046
3025 printer->Indent(); 3047 printer->Indent();
3026 if (field->is_packed()) { 3048 if (field->is_packed()) {
3027 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 3049 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3028 } else { 3050 } else {
3029 field_generator.GenerateMergeFromCodedStream(printer); 3051 field_generator.GenerateMergeFromCodedStream(printer);
3030 } 3052 }
3031 printer->Outdent(); 3053 printer->Outdent();
3032 3054
3033 // Emit code to parse unexpectedly packed or unpacked values. 3055 // Emit code to parse unexpectedly packed or unpacked values.
3034 if (field->is_packed()) { 3056 if (field->is_packed()) {
3035 internal::WireFormatLite::WireType wiretype = 3057 internal::WireFormatLite::WireType wiretype =
3036 WireFormat::WireTypeForFieldType(field->type()); 3058 WireFormat::WireTypeForFieldType(field->type());
3037 printer->Print("} else if (tag == $uncommontag$) {\n", 3059 printer->Print("} else if (tag == $uncommontag$u) {\n",
3038 "uncommontag", SimpleItoa( 3060 "uncommontag", SimpleItoa(
3039 internal::WireFormatLite::MakeTag( 3061 internal::WireFormatLite::MakeTag(
3040 field->number(), wiretype))); 3062 field->number(), wiretype)));
3041 printer->Indent(); 3063 printer->Indent();
3042 field_generator.GenerateMergeFromCodedStream(printer); 3064 field_generator.GenerateMergeFromCodedStream(printer);
3043 printer->Outdent(); 3065 printer->Outdent();
3044 } else if (field->is_packable() && !field->is_packed()) { 3066 } else if (field->is_packable() && !field->is_packed()) {
3045 internal::WireFormatLite::WireType wiretype = 3067 internal::WireFormatLite::WireType wiretype =
3046 internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED; 3068 internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
3047 printer->Print("} else if (tag == $uncommontag$) {\n", 3069 printer->Print("} else if (tag == $uncommontag$u) {\n",
3048 "uncommontag", SimpleItoa( 3070 "uncommontag", SimpleItoa(
3049 internal::WireFormatLite::MakeTag( 3071 internal::WireFormatLite::MakeTag(
3050 field->number(), wiretype))); 3072 field->number(), wiretype)));
3051 printer->Indent(); 3073 printer->Indent();
3052 field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 3074 field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
3053 printer->Outdent(); 3075 printer->Outdent();
3054 } 3076 }
3055 3077
3056 printer->Print( 3078 printer->Print(
3057 "} else {\n" 3079 "} else {\n"
3058 " goto handle_unusual;\n" 3080 " goto handle_unusual;\n"
3059 "}\n"); 3081 "}\n");
3060 3082
3061 // switch() is slow since it can't be predicted well. Insert some if()s 3083 // For repeated messages/groups, we need to decrement recursion depth.
3062 // here that attempt to predict the next tag.
3063 // For non-packed repeated fields, expect the same tag again.
3064 if (loops) { 3084 if (loops) {
3065 printer->Print( 3085 printer->Print(
3066 "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n", 3086 "input->UnsafeDecrementRecursionDepth();\n");
3067 "tag", SimpleItoa(WireFormat::MakeTag(field)),
3068 "name", field->name());
3069 } else if (field->is_repeated() && !field->is_packed()) {
3070 printer->Print(
3071 "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
3072 "tag", SimpleItoa(WireFormat::MakeTag(field)),
3073 "name", field->name());
3074 }
3075
3076 // Have we emitted "if (input->ExpectTag($next_tag$)) ..." yet?
3077 bool emitted_goto_next_tag = false;
3078
3079 // For repeated messages/groups, we need to decrement recursion depth,
3080 // unless the next tag is also for a repeated message/group.
3081 if (loops) {
3082 if (next_field_loops) {
3083 const FieldDescriptor* next_field = ordered_fields[i + 1];
3084 printer->Print(
3085 "if (input->ExpectTag($next_tag$)) goto parse_loop_$next_name$;\n",
3086 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3087 "next_name", next_field->name());
3088 emitted_goto_next_tag = true;
3089 }
3090 printer->Print(
3091 "input->UnsafeDecrementRecursionDepth();\n");
3092 }
3093
3094 // If there are more fields, expect the next one.
3095 need_label = false;
3096 if (!emitted_goto_next_tag) {
3097 if (i + 1 == descriptor_->field_count()) {
3098 // Expect EOF.
3099 // TODO(kenton): Expect group end-tag?
3100 printer->Print(
3101 "if (input->ExpectAtEnd()) goto success;\n");
3102 } else {
3103 const FieldDescriptor* next_field = ordered_fields[i + 1];
3104 printer->Print(
3105 "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
3106 "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
3107 "next_name", next_field->name());
3108 need_label = true;
3109 }
3110 } 3087 }
3111 3088
3112 printer->Print( 3089 printer->Print(
3113 "break;\n"); 3090 "break;\n");
3114 3091
3115 printer->Outdent(); 3092 printer->Outdent();
3116 printer->Print("}\n\n"); 3093 printer->Print("}\n\n");
3117 } 3094 }
3118 3095
3119 printer->Print("default: {\n"); 3096 printer->Print("default: {\n");
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 } else { 3129 } else {
3153 printer->Print( 3130 printer->Print(
3154 "($start$u <= tag && tag < $end$u)", 3131 "($start$u <= tag && tag < $end$u)",
3155 "start", SimpleItoa(start_tag), 3132 "start", SimpleItoa(start_tag),
3156 "end", SimpleItoa(end_tag)); 3133 "end", SimpleItoa(end_tag));
3157 } 3134 }
3158 } 3135 }
3159 printer->Print(") {\n"); 3136 printer->Print(") {\n");
3160 if (PreserveUnknownFields(descriptor_)) { 3137 if (PreserveUnknownFields(descriptor_)) {
3161 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 3138 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3162 PrintHandlingOptionalStaticInitializers( 3139 printer->Print(
3163 descriptor_->file(), options_, printer, 3140 " DO_(_extensions_.ParseField(tag, input, "
3164 // With static initializers. 3141 "internal_default_instance(),\n"
3165 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3166 " mutable_unknown_fields()));\n",
3167 // Without.
3168 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3169 " mutable_unknown_fields()));\n"); 3142 " mutable_unknown_fields()));\n");
3170 } else { 3143 } else {
3171 PrintHandlingOptionalStaticInitializers( 3144 printer->Print(
3172 descriptor_->file(), options_, printer, 3145 " DO_(_extensions_.ParseField(tag, input, "
3173 // With static initializers. 3146 "internal_default_instance(),\n"
3174 " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
3175 " &unknown_fields_stream));\n",
3176 // Without.
3177 " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
3178 " &unknown_fields_stream));\n"); 3147 " &unknown_fields_stream));\n");
3179 } 3148 }
3180 } else { 3149 } else {
3181 PrintHandlingOptionalStaticInitializers( 3150 printer->Print(
3182 descriptor_->file(), options_, printer,
3183 // With static initializers. 3151 // With static initializers.
3184 " DO_(_extensions_.ParseField(tag, input, default_instance_);\n", 3152 " DO_(_extensions_.ParseField(tag, input, "
3185 // Without. 3153 "internal_default_instance());\n");
3186 " DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
3187 } 3154 }
3188 printer->Print( 3155 printer->Print(
3189 " continue;\n" 3156 " continue;\n"
3190 "}\n"); 3157 "}\n");
3191 } 3158 }
3192 3159
3193 // We really don't recognize this tag. Skip it. 3160 // We really don't recognize this tag. Skip it.
3194 if (PreserveUnknownFields(descriptor_)) { 3161 if (PreserveUnknownFields(descriptor_)) {
3195 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 3162 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3196 printer->Print( 3163 printer->Print(
(...skipping 24 matching lines...) Expand all
3221 "success:\n" 3188 "success:\n"
3222 " // @@protoc_insertion_point(parse_success:$full_name$)\n" 3189 " // @@protoc_insertion_point(parse_success:$full_name$)\n"
3223 " return true;\n" 3190 " return true;\n"
3224 "failure:\n" 3191 "failure:\n"
3225 " // @@protoc_insertion_point(parse_failure:$full_name$)\n" 3192 " // @@protoc_insertion_point(parse_failure:$full_name$)\n"
3226 " return false;\n" 3193 " return false;\n"
3227 "#undef DO_\n" 3194 "#undef DO_\n"
3228 "}\n", "full_name", descriptor_->full_name()); 3195 "}\n", "full_name", descriptor_->full_name());
3229 } 3196 }
3230 3197
3198 void MessageGenerator::GenerateSerializeOneofFields(
3199 io::Printer* printer, const std::vector<const FieldDescriptor*>& fields,
3200 bool to_array) {
3201 GOOGLE_CHECK(!fields.empty());
3202 if (fields.size() == 1) {
3203 GenerateSerializeOneField(printer, fields[0], to_array);
3204 return;
3205 }
3206 // We have multiple mutually exclusive choices. Emit a switch statement.
3207 const OneofDescriptor* oneof = fields[0]->containing_oneof();
3208 printer->Print(
3209 "switch ($oneofname$_case()) {\n",
3210 "oneofname", oneof->name());
3211 printer->Indent();
3212 for (int i = 0; i < fields.size(); i++) {
3213 const FieldDescriptor* field = fields[i];
3214 printer->Print(
3215 "case k$field_name$:\n",
3216 "field_name", UnderscoresToCamelCase(field->name(), true));
3217 printer->Indent();
3218 if (to_array) {
3219 field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
3220 printer);
3221 } else {
3222 field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
3223 }
3224 printer->Print(
3225 "break;\n");
3226 printer->Outdent();
3227 }
3228 printer->Outdent();
3229 // Doing nothing is an option.
3230 printer->Print(
3231 " default: ;\n"
3232 "}\n");
3233 }
3234
3231 void MessageGenerator::GenerateSerializeOneField( 3235 void MessageGenerator::GenerateSerializeOneField(
3232 io::Printer* printer, const FieldDescriptor* field, bool to_array) { 3236 io::Printer* printer, const FieldDescriptor* field, bool to_array) {
3233 PrintFieldComment(printer, field); 3237 PrintFieldComment(printer, field);
3234 3238
3235 bool have_enclosing_if = false; 3239 bool have_enclosing_if = false;
3236 if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) { 3240 if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) {
3237 printer->Print( 3241 printer->Print(
3238 "if (has_$name$()) {\n", 3242 "if (has_$name$()) {\n",
3239 "name", FieldName(field)); 3243 "name", FieldName(field));
3240 printer->Indent(); 3244 printer->Indent();
(...skipping 12 matching lines...) Expand all
3253 if (have_enclosing_if) { 3257 if (have_enclosing_if) {
3254 printer->Outdent(); 3258 printer->Outdent();
3255 printer->Print("}\n"); 3259 printer->Print("}\n");
3256 } 3260 }
3257 printer->Print("\n"); 3261 printer->Print("\n");
3258 } 3262 }
3259 3263
3260 void MessageGenerator::GenerateSerializeOneExtensionRange( 3264 void MessageGenerator::GenerateSerializeOneExtensionRange(
3261 io::Printer* printer, const Descriptor::ExtensionRange* range, 3265 io::Printer* printer, const Descriptor::ExtensionRange* range,
3262 bool to_array) { 3266 bool to_array) {
3263 map<string, string> vars; 3267 std::map<string, string> vars;
3264 vars["start"] = SimpleItoa(range->start); 3268 vars["start"] = SimpleItoa(range->start);
3265 vars["end"] = SimpleItoa(range->end); 3269 vars["end"] = SimpleItoa(range->end);
3266 printer->Print(vars, 3270 printer->Print(vars,
3267 "// Extension range [$start$, $end$)\n"); 3271 "// Extension range [$start$, $end$)\n");
3268 if (to_array) { 3272 if (to_array) {
3269 printer->Print(vars, 3273 printer->Print(vars,
3270 "target = _extensions_.SerializeWithCachedSizesToArray(\n" 3274 "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
3271 " $start$, $end$, target);\n\n"); 3275 " $start$, $end$, false, target);\n\n");
3272 } else { 3276 } else {
3273 printer->Print(vars, 3277 printer->Print(vars,
3274 "_extensions_.SerializeWithCachedSizes(\n" 3278 "_extensions_.SerializeWithCachedSizes(\n"
3275 " $start$, $end$, output);\n\n"); 3279 " $start$, $end$, output);\n\n");
3276 } 3280 }
3277 } 3281 }
3278 3282
3279 void MessageGenerator:: 3283 void MessageGenerator::
3280 GenerateSerializeWithCachedSizes(io::Printer* printer) { 3284 GenerateSerializeWithCachedSizes(io::Printer* printer) {
3281 if (descriptor_->options().message_set_wire_format()) { 3285 if (descriptor_->options().message_set_wire_format()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3313 printer->Outdent(); 3317 printer->Outdent();
3314 printer->Print( 3318 printer->Print(
3315 "}\n"); 3319 "}\n");
3316 } 3320 }
3317 3321
3318 void MessageGenerator:: 3322 void MessageGenerator::
3319 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { 3323 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
3320 if (descriptor_->options().message_set_wire_format()) { 3324 if (descriptor_->options().message_set_wire_format()) {
3321 // Special-case MessageSet. 3325 // Special-case MessageSet.
3322 printer->Print( 3326 printer->Print(
3323 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\ n" 3327 "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesT oArray(\n"
3324 " ::google::protobuf::uint8* target) const {\n" 3328 " bool deterministic, ::google::protobuf::uint8* target) const {\n"
3325 " target =\n" 3329 " target = _extensions_."
3326 " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n", 3330 "InternalSerializeMessageSetWithCachedSizesToArray(\n"
3331 " deterministic, target);\n",
3327 "classname", classname_); 3332 "classname", classname_);
3328 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); 3333 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3329 printer->Print( 3334 printer->Print(
3330 " target = ::google::protobuf::internal::WireFormat::\n" 3335 " target = ::google::protobuf::internal::WireFormat::\n"
3331 " SerializeUnknownMessageSetItemsToArray(\n" 3336 " SerializeUnknownMessageSetItemsToArray(\n"
3332 " unknown_fields(), target);\n"); 3337 " unknown_fields(), target);\n");
3333 printer->Print( 3338 printer->Print(
3334 " return target;\n" 3339 " return target;\n"
3335 "}\n"); 3340 "}\n");
3336 return; 3341 return;
3337 } 3342 }
3338 3343
3339 printer->Print( 3344 printer->Print(
3340 "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 3345 "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToA rray(\n"
3341 " ::google::protobuf::uint8* target) const {\n", 3346 " bool deterministic, ::google::protobuf::uint8* target) const {\n",
3342 "classname", classname_); 3347 "classname", classname_);
3343 printer->Indent(); 3348 printer->Indent();
3344 3349
3350 printer->Print("(void)deterministic; // Unused\n");
3345 printer->Print( 3351 printer->Print(
3346 "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n", 3352 "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
3347 "full_name", descriptor_->full_name()); 3353 "full_name", descriptor_->full_name());
3348 3354
3349 GenerateSerializeWithCachedSizesBody(printer, true); 3355 GenerateSerializeWithCachedSizesBody(printer, true);
3350 3356
3351 printer->Print( 3357 printer->Print(
3352 "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n", 3358 "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
3353 "full_name", descriptor_->full_name()); 3359 "full_name", descriptor_->full_name());
3354 3360
3355 printer->Outdent(); 3361 printer->Outdent();
3356 printer->Print( 3362 printer->Print(
3357 " return target;\n" 3363 " return target;\n"
3358 "}\n"); 3364 "}\n");
3359 } 3365 }
3360 3366
3361 void MessageGenerator:: 3367 void MessageGenerator::
3362 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { 3368 GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
3363 google::protobuf::scoped_array<const FieldDescriptor * > ordered_fields( 3369 // If there are multiple fields in a row from the same oneof then we
3364 SortFieldsByNumber(descriptor_)); 3370 // coalesce them and emit a switch statement. This is more efficient
3371 // because it lets the C++ compiler know this is a "at most one can happen"
3372 // situation. If we emitted "if (has_x()) ...; if (has_y()) ..." the C++
3373 // compiler's emitted code might check has_y() even when has_x() is true.
3374 class LazySerializerEmitter {
3375 public:
3376 LazySerializerEmitter(MessageGenerator* mg, io::Printer* printer,
3377 bool to_array)
3378 : mg_(mg),
3379 printer_(printer),
3380 to_array_(to_array),
3381 eager_(!HasFieldPresence(mg->descriptor_->file())) {}
3365 3382
3366 vector<const Descriptor::ExtensionRange*> sorted_extensions; 3383 ~LazySerializerEmitter() { Flush(); }
3384
3385 // If conditions allow, try to accumulate a run of fields from the same
3386 // oneof, and handle them at the next Flush().
3387 void Emit(const FieldDescriptor* field) {
3388 if (eager_ || MustFlush(field)) {
3389 Flush();
3390 }
3391 if (field->containing_oneof() == NULL) {
3392 mg_->GenerateSerializeOneField(printer_, field, to_array_);
3393 } else {
3394 v_.push_back(field);
3395 }
3396 }
3397
3398 void Flush() {
3399 if (!v_.empty()) {
3400 mg_->GenerateSerializeOneofFields(printer_, v_, to_array_);
3401 v_.clear();
3402 }
3403 }
3404
3405 private:
3406 // If we have multiple fields in v_ then they all must be from the same
3407 // oneof. Would adding field to v_ break that invariant?
3408 bool MustFlush(const FieldDescriptor* field) {
3409 return !v_.empty() &&
3410 v_[0]->containing_oneof() != field->containing_oneof();
3411 }
3412
3413 MessageGenerator* mg_;
3414 io::Printer* printer_;
3415 const bool to_array_;
3416 const bool eager_;
3417 std::vector<const FieldDescriptor*> v_;
3418 };
3419
3420 std::vector<const FieldDescriptor*> ordered_fields =
3421 SortFieldsByNumber(descriptor_);
3422
3423 std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
3367 for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 3424 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
3368 sorted_extensions.push_back(descriptor_->extension_range(i)); 3425 sorted_extensions.push_back(descriptor_->extension_range(i));
3369 } 3426 }
3370 std::sort(sorted_extensions.begin(), sorted_extensions.end(), 3427 std::sort(sorted_extensions.begin(), sorted_extensions.end(),
3371 ExtensionRangeSorter()); 3428 ExtensionRangeSorter());
3372 3429
3373 // Merge the fields and the extension ranges, both sorted by field number. 3430 // Merge the fields and the extension ranges, both sorted by field number.
3374 int i, j; 3431 {
3375 for (i = 0, j = 0; 3432 LazySerializerEmitter e(this, printer, to_array);
3376 i < descriptor_->field_count() || j < sorted_extensions.size(); 3433 int i, j;
3377 ) { 3434 for (i = 0, j = 0;
3378 if (i == descriptor_->field_count()) { 3435 i < ordered_fields.size() || j < sorted_extensions.size();) {
3379 GenerateSerializeOneExtensionRange(printer, 3436 if (i == descriptor_->field_count()) {
3380 sorted_extensions[j++], 3437 e.Flush();
3381 to_array); 3438 GenerateSerializeOneExtensionRange(printer,
3382 } else if (j == sorted_extensions.size()) { 3439 sorted_extensions[j++],
3383 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 3440 to_array);
3384 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { 3441 } else if (j == sorted_extensions.size()) {
3385 GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 3442 e.Emit(ordered_fields[i++]);
3386 } else { 3443 } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
3387 GenerateSerializeOneExtensionRange(printer, 3444 e.Emit(ordered_fields[i++]);
3388 sorted_extensions[j++], 3445 } else {
3389 to_array); 3446 e.Flush();
3447 GenerateSerializeOneExtensionRange(printer,
3448 sorted_extensions[j++],
3449 to_array);
3450 }
3390 } 3451 }
3391 } 3452 }
3392 3453
3393 if (PreserveUnknownFields(descriptor_)) { 3454 if (PreserveUnknownFields(descriptor_)) {
3394 if (UseUnknownFieldSet(descriptor_->file(), options_)) { 3455 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3395 printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n"); 3456 printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n");
3396 printer->Indent(); 3457 printer->Indent();
3397 if (to_array) { 3458 if (to_array) {
3398 printer->Print( 3459 printer->Print(
3399 "target = " 3460 "target = "
3400 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsT oArray(\n" 3461 "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsT oArray(\n"
3401 " unknown_fields(), target);\n"); 3462 " unknown_fields(), target);\n");
3402 } else { 3463 } else {
3403 printer->Print( 3464 printer->Print(
3404 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" 3465 "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
3405 " unknown_fields(), output);\n"); 3466 " unknown_fields(), output);\n");
3406 } 3467 }
3407 printer->Outdent(); 3468 printer->Outdent();
3408 3469
3409 printer->Print( 3470 printer->Print(
3410 "}\n"); 3471 "}\n");
3411 } else { 3472 } else {
3412 printer->Print( 3473 printer->Print(
3413 "output->WriteRaw(unknown_fields().data(),\n" 3474 "output->WriteRaw(unknown_fields().data(),\n"
3414 " static_cast<int>(unknown_fields().size()));\n"); 3475 " static_cast<int>(unknown_fields().size()));\n");
3415 } 3476 }
3416 } 3477 }
3417 } 3478 }
3418 3479
3419 static vector<uint32> RequiredFieldsBitMask(const Descriptor* desc) { 3480 std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const {
3420 vector<uint32> result; 3481 const int array_size = HasBitsSize();
3421 uint32 mask = 0; 3482 std::vector<uint32> masks(array_size, 0);
3422 for (int i = 0; i < desc->field_count(); i++) { 3483
3423 if (i > 0 && i % 32 == 0) { 3484 for (int i = 0; i < descriptor_->field_count(); i++) {
3424 result.push_back(mask); 3485 const FieldDescriptor* field = descriptor_->field(i);
3425 mask = 0; 3486 if (!field->is_required()) {
3487 continue;
3426 } 3488 }
3427 if (desc->field(i)->is_required()) { 3489
3428 mask |= (1 << (i & 31)); 3490 const int has_bit_index = has_bit_indices_[field->index()];
3429 } 3491 masks[has_bit_index / 32] |=
3492 static_cast<uint32>(1) << (has_bit_index % 32);
3430 } 3493 }
3431 if (mask != 0) { 3494 return masks;
3432 result.push_back(mask);
3433 }
3434 return result;
3435 } 3495 }
3436 3496
3437 // Create an expression that evaluates to 3497 // Create an expression that evaluates to
3438 // "for all i, (_has_bits_[i] & masks[i]) == masks[i]" 3498 // "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
3439 // masks is allowed to be shorter than _has_bits_, but at least one element of 3499 // masks is allowed to be shorter than _has_bits_, but at least one element of
3440 // masks must be non-zero. 3500 // masks must be non-zero.
3441 static string ConditionalToCheckBitmasks(const vector<uint32>& masks) { 3501 static string ConditionalToCheckBitmasks(const std::vector<uint32>& masks) {
3442 vector<string> parts; 3502 std::vector<string> parts;
3443 for (int i = 0; i < masks.size(); i++) { 3503 for (int i = 0; i < masks.size(); i++) {
3444 if (masks[i] == 0) continue; 3504 if (masks[i] == 0) continue;
3445 string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8)); 3505 string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
3446 // Each xor evaluates to 0 if the expected bits are present. 3506 // Each xor evaluates to 0 if the expected bits are present.
3447 parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")")); 3507 parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
3448 } 3508 }
3449 GOOGLE_CHECK(!parts.empty()); 3509 GOOGLE_CHECK(!parts.empty());
3450 // If we have multiple parts, each expected to be 0, then bitwise-or them. 3510 // If we have multiple parts, each expected to be 0, then bitwise-or them.
3451 string result = parts.size() == 1 ? parts[0] : 3511 string result = parts.size() == 1 ? parts[0] :
3452 StrCat("(", Join(parts, "\n | "), ")"); 3512 StrCat("(", Join(parts, "\n | "), ")");
3453 return result + " == 0"; 3513 return result + " == 0";
3454 } 3514 }
3455 3515
3456 void MessageGenerator:: 3516 void MessageGenerator::
3457 GenerateByteSize(io::Printer* printer) { 3517 GenerateByteSize(io::Printer* printer) {
3458 if (descriptor_->options().message_set_wire_format()) { 3518 if (descriptor_->options().message_set_wire_format()) {
3459 // Special-case MessageSet. 3519 // Special-case MessageSet.
3460 printer->Print( 3520 printer->Print(
3461 "int $classname$::ByteSize() const {\n" 3521 "size_t $classname$::ByteSizeLong() const {\n"
3462 "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" 3522 "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
3463 " int total_size = _extensions_.MessageSetByteSize();\n", 3523 " size_t total_size = _extensions_.MessageSetByteSize();\n",
3464 "classname", classname_, "full_name", descriptor_->full_name()); 3524 "classname", classname_, "full_name", descriptor_->full_name());
3465 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); 3525 GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
3466 printer->Print( 3526 printer->Print(
3467 "if (_internal_metadata_.have_unknown_fields()) {\n" 3527 "if (_internal_metadata_.have_unknown_fields()) {\n"
3468 " total_size += ::google::protobuf::internal::WireFormat::\n" 3528 " total_size += ::google::protobuf::internal::WireFormat::\n"
3469 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n" 3529 " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"
3470 "}\n"); 3530 "}\n");
3471 printer->Print( 3531 printer->Print(
3532 " int cached_size = ::google::protobuf::internal::ToCachedSize(total_size );\n"
3472 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 3533 " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3473 " _cached_size_ = total_size;\n" 3534 " _cached_size_ = cached_size;\n"
3474 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 3535 " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3475 " return total_size;\n" 3536 " return total_size;\n"
3476 "}\n"); 3537 "}\n");
3477 return; 3538 return;
3478 } 3539 }
3479 3540
3480 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) { 3541 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3481 // Emit a function (rarely used, we hope) that handles the required fields 3542 // Emit a function (rarely used, we hope) that handles the required fields
3482 // by checking for each one individually. 3543 // by checking for each one individually.
3483 printer->Print( 3544 printer->Print(
3484 "int $classname$::RequiredFieldsByteSizeFallback() const {\n" 3545 "size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
3485 "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:" 3546 "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
3486 "$full_name$)\n", 3547 "$full_name$)\n",
3487 "classname", classname_, "full_name", descriptor_->full_name()); 3548 "classname", classname_, "full_name", descriptor_->full_name());
3488 printer->Indent(); 3549 printer->Indent();
3489 printer->Print("int total_size = 0;\n"); 3550 printer->Print("size_t total_size = 0;\n");
3490 for (int i = 0; i < descriptor_->field_count(); i++) { 3551 for (int i = 0; i < optimized_order_.size(); i++) {
3491 const FieldDescriptor* field = descriptor_->field(i); 3552 const FieldDescriptor* field = optimized_order_[i];
3492 if (field->is_required()) { 3553 if (field->is_required()) {
3493 printer->Print("\n" 3554 printer->Print("\n"
3494 "if (has_$name$()) {\n", 3555 "if (has_$name$()) {\n",
3495 "name", FieldName(field)); 3556 "name", FieldName(field));
3496 printer->Indent(); 3557 printer->Indent();
3497 PrintFieldComment(printer, field); 3558 PrintFieldComment(printer, field);
3498 field_generators_.get(field).GenerateByteSize(printer); 3559 field_generators_.get(field).GenerateByteSize(printer);
3499 printer->Outdent(); 3560 printer->Outdent();
3500 printer->Print("}\n"); 3561 printer->Print("}\n");
3501 } 3562 }
3502 } 3563 }
3503 printer->Print("\n" 3564 printer->Print("\n"
3504 "return total_size;\n"); 3565 "return total_size;\n");
3505 printer->Outdent(); 3566 printer->Outdent();
3506 printer->Print("}\n"); 3567 printer->Print("}\n");
3507 } 3568 }
3508 3569
3509 printer->Print( 3570 printer->Print(
3510 "int $classname$::ByteSize() const {\n" 3571 "size_t $classname$::ByteSizeLong() const {\n"
3511 "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n", 3572 "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
3512 "classname", classname_, "full_name", descriptor_->full_name()); 3573 "classname", classname_, "full_name", descriptor_->full_name());
3513 printer->Indent(); 3574 printer->Indent();
3514 printer->Print( 3575 printer->Print(
3515 "int total_size = 0;\n" 3576 "size_t total_size = 0;\n"
3516 "\n"); 3577 "\n");
3517 3578
3579 if (descriptor_->extension_range_count() > 0) {
3580 printer->Print(
3581 "total_size += _extensions_.ByteSize();\n"
3582 "\n");
3583 }
3584
3585 if (PreserveUnknownFields(descriptor_)) {
3586 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3587 printer->Print(
3588 "if (_internal_metadata_.have_unknown_fields()) {\n"
3589 " total_size +=\n"
3590 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( \n"
3591 " unknown_fields());\n"
3592 "}\n");
3593 } else {
3594 printer->Print(
3595 "total_size += unknown_fields().size();\n"
3596 "\n");
3597 }
3598 }
3599
3518 // Handle required fields (if any). We expect all of them to be 3600 // Handle required fields (if any). We expect all of them to be
3519 // present, so emit one conditional that checks for that. If they are all 3601 // present, so emit one conditional that checks for that. If they are all
3520 // present then the fast path executes; otherwise the slow path executes. 3602 // present then the fast path executes; otherwise the slow path executes.
3521 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) { 3603 if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) {
3522 // The fast path works if all required fields are present. 3604 // The fast path works if all required fields are present.
3523 vector<uint32> masks_for_has_bits = RequiredFieldsBitMask(descriptor_); 3605 const std::vector<uint32> masks_for_has_bits = RequiredFieldsBitMask();
3524 printer->Print((string("if (") + 3606 printer->Print((string("if (") +
3525 ConditionalToCheckBitmasks(masks_for_has_bits) + 3607 ConditionalToCheckBitmasks(masks_for_has_bits) +
3526 ") { // All required fields are present.\n").c_str()); 3608 ") { // All required fields are present.\n").c_str());
3527 printer->Indent(); 3609 printer->Indent();
3528 for (int i = 0; i < descriptor_->field_count(); i++) { 3610 // Oneof fields cannot be required, so optimized_order_ contains all of the
3529 const FieldDescriptor* field = descriptor_->field(i); 3611 // fields that we need to potentially emit.
3612 for (int i = 0; i < optimized_order_.size(); i++) {
3613 const FieldDescriptor* field = optimized_order_[i];
3530 if (!field->is_required()) continue; 3614 if (!field->is_required()) continue;
3531 PrintFieldComment(printer, field); 3615 PrintFieldComment(printer, field);
3532 field_generators_.get(field).GenerateByteSize(printer); 3616 field_generators_.get(field).GenerateByteSize(printer);
3533 printer->Print("\n"); 3617 printer->Print("\n");
3534 } 3618 }
3535 printer->Outdent(); 3619 printer->Outdent();
3536 printer->Print("} else {\n" // the slow path 3620 printer->Print("} else {\n" // the slow path
3537 " total_size += RequiredFieldsByteSizeFallback();\n" 3621 " total_size += RequiredFieldsByteSizeFallback();\n"
3538 "}\n"); 3622 "}\n");
3539 } else { 3623 } else {
3540 // num_required_fields_ <= 1: no need to be tricky 3624 // num_required_fields_ <= 1: no need to be tricky
3541 for (int i = 0; i < descriptor_->field_count(); i++) { 3625 for (int i = 0; i < optimized_order_.size(); i++) {
3542 const FieldDescriptor* field = descriptor_->field(i); 3626 const FieldDescriptor* field = optimized_order_[i];
3543 if (!field->is_required()) continue; 3627 if (!field->is_required()) continue;
3544 PrintFieldComment(printer, field); 3628 PrintFieldComment(printer, field);
3545 printer->Print("if (has_$name$()) {\n", 3629 printer->Print("if (has_$name$()) {\n",
3546 "name", FieldName(field)); 3630 "name", FieldName(field));
3547 printer->Indent(); 3631 printer->Indent();
3548 field_generators_.get(field).GenerateByteSize(printer); 3632 field_generators_.get(field).GenerateByteSize(printer);
3549 printer->Outdent(); 3633 printer->Outdent();
3550 printer->Print("}\n"); 3634 printer->Print("}\n");
3551 } 3635 }
3552 } 3636 }
3553 3637
3554 // Handle optional fields (worry below about repeateds, oneofs, etc.). 3638 int last_i = -1;
3555 // These are handled in chunks of 8. The first chunk is 3639 for (int i = 0; i < optimized_order_.size(); ) {
3556 // the non-requireds-non-repeateds-non-unions-non-extensions in 3640 // Detect infinite loops.
3557 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7), 3641 GOOGLE_CHECK_NE(i, last_i);
3558 // and the second chunk is the same for 3642 last_i = i;
3559 // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15), 3643
3560 // etc. 3644 // Skip required fields.
3561 hash_map<int, uint32> fields_mask_for_chunk; 3645 for (; i < optimized_order_.size() &&
3562 for (int i = 0; i < descriptor_->field_count(); i++) { 3646 optimized_order_[i]->is_required(); i++) {
3563 const FieldDescriptor* field = descriptor_->field(i);
3564 if (!field->is_required() && !field->is_repeated() &&
3565 !field->containing_oneof()) {
3566 fields_mask_for_chunk[i / 8] |= static_cast<uint32>(1) << (i % 32);
3567 } 3647 }
3568 }
3569 3648
3570 int last_index = -1; 3649 // Handle repeated fields.
3571 bool chunk_block_in_progress = false; 3650 for (; i < optimized_order_.size(); i++) {
3572 for (int i = 0; i < descriptor_->field_count(); i++) { 3651 const FieldDescriptor* field = optimized_order_[i];
3573 const FieldDescriptor* field = descriptor_->field(i); 3652 if (!field->is_repeated()) {
3574 if (!field->is_required() && !field->is_repeated() && 3653 break;
3575 !field->containing_oneof()) { 3654 }
3576 // See above in GenerateClear for an explanation of this. 3655
3577 // TODO(kenton): Share code? Unclear how to do so without 3656 PrintFieldComment(printer, field);
3578 // over-engineering. 3657 const FieldGenerator& generator = field_generators_.get(field);
3579 if (i / 8 != last_index / 8 || last_index < 0) { 3658 generator.GenerateByteSize(printer);
3580 // End previous chunk, if there was one. 3659 printer->Print("\n");
3581 if (chunk_block_in_progress) { 3660 }
3661
3662 // Handle optional (non-repeated/oneof) fields.
3663 //
3664 // These are handled in chunks of 8. The first chunk is
3665 // the non-requireds-non-repeateds-non-unions-non-extensions in
3666 // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
3667 // and the second chunk is the same for
3668 // descriptor_->field(8), descriptor_->field(9), ...
3669 // descriptor_->field(15),
3670 // etc.
3671 int last_chunk = -1;
3672 int last_chunk_start = -1;
3673 int last_chunk_end = -1;
3674 uint32 last_chunk_mask = 0;
3675 for (; i < optimized_order_.size(); i++) {
3676 const FieldDescriptor* field = optimized_order_[i];
3677 if (field->is_repeated() || field->is_required()) {
3678 break;
3679 }
3680
3681 // "index" defines where in the _has_bits_ the field appears.
3682 // "i" is our loop counter within optimized_order_.
3683 int index = HasFieldPresence(descriptor_->file()) ?
3684 has_bit_indices_[field->index()] : 0;
3685 int chunk = index / 8;
3686
3687 if (last_chunk == -1) {
3688 last_chunk = chunk;
3689 last_chunk_start = i;
3690 } else if (chunk != last_chunk) {
3691 // Emit the fields for this chunk so far.
3692 break;
3693 }
3694
3695 last_chunk_end = i;
3696 last_chunk_mask |= static_cast<uint32>(1) << (index % 32);
3697 }
3698
3699 if (last_chunk != -1) {
3700 GOOGLE_DCHECK_NE(-1, last_chunk_start);
3701 GOOGLE_DCHECK_NE(-1, last_chunk_end);
3702 GOOGLE_DCHECK_NE(0, last_chunk_mask);
3703
3704 const int count = popcnt(last_chunk_mask);
3705 const bool have_outer_if = HasFieldPresence(descriptor_->file()) &&
3706 (last_chunk_start != last_chunk_end);
3707
3708 if (have_outer_if) {
3709 // Check (up to) 8 has_bits at a time if we have more than one field in
3710 // this chunk. Due to field layout ordering, we may check
3711 // _has_bits_[last_chunk * 8 / 32] multiple times.
3712 GOOGLE_DCHECK_LE(2, count);
3713 GOOGLE_DCHECK_GE(8, count);
3714
3715 printer->Print(
3716 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
3717 "index", SimpleItoa(last_chunk * 8),
3718 "mask", SimpleItoa(last_chunk_mask));
3719 printer->Indent();
3720 }
3721
3722 // Go back and emit checks for each of the fields we processed.
3723 for (int j = last_chunk_start; j <= last_chunk_end; j++) {
3724 const FieldDescriptor* field = optimized_order_[j];
3725 const FieldGenerator& generator = field_generators_.get(field);
3726
3727 PrintFieldComment(printer, field);
3728
3729 bool have_enclosing_if = false;
3730 if (HasFieldPresence(descriptor_->file())) {
3731 printer->Print(
3732 "if (has_$name$()) {\n",
3733 "name", FieldName(field));
3734 printer->Indent();
3735 have_enclosing_if = true;
3736 } else {
3737 // Without field presence: field is serialized only if it has a
3738 // non-default value.
3739 have_enclosing_if = EmitFieldNonDefaultCondition(
3740 printer, "this->", field);
3741 }
3742
3743 generator.GenerateByteSize(printer);
3744
3745 if (have_enclosing_if) {
3582 printer->Outdent(); 3746 printer->Outdent();
3583 printer->Print("}\n"); 3747 printer->Print(
3584 chunk_block_in_progress = false; 3748 "}\n"
3585 } 3749 "\n");
3586 // Start chunk.
3587 uint32 mask = fields_mask_for_chunk[i / 8];
3588 int count = popcnt(mask);
3589 GOOGLE_DCHECK_GE(count, 1);
3590 if (count == 1) {
3591 // No "if" here because the chunk is trivial.
3592 } else {
3593 if (HasFieldPresence(descriptor_->file())) {
3594 printer->Print(
3595 "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
3596 "index", SimpleItoa(i),
3597 "mask", SimpleItoa(mask));
3598 printer->Indent();
3599 chunk_block_in_progress = true;
3600 }
3601 } 3750 }
3602 } 3751 }
3603 last_index = i;
3604 3752
3605 PrintFieldComment(printer, field); 3753 if (have_outer_if) {
3606
3607 bool have_enclosing_if = false;
3608 if (HasFieldPresence(descriptor_->file())) {
3609 printer->Print(
3610 "if (has_$name$()) {\n",
3611 "name", FieldName(field));
3612 printer->Indent();
3613 have_enclosing_if = true;
3614 } else {
3615 // Without field presence: field is serialized only if it has a
3616 // non-default value.
3617 have_enclosing_if = EmitFieldNonDefaultCondition(
3618 printer, "this->", field);
3619 }
3620
3621 field_generators_.get(field).GenerateByteSize(printer);
3622
3623 if (have_enclosing_if) {
3624 printer->Outdent(); 3754 printer->Outdent();
3625 printer->Print( 3755 printer->Print("}\n");
3626 "}\n"
3627 "\n");
3628 } 3756 }
3629 } 3757 }
3630 } 3758 }
3631 3759
3632 if (chunk_block_in_progress) {
3633 printer->Outdent();
3634 printer->Print("}\n");
3635 }
3636
3637 // Repeated fields don't use _has_bits_ so we count them in a separate
3638 // pass.
3639 for (int i = 0; i < descriptor_->field_count(); i++) {
3640 const FieldDescriptor* field = descriptor_->field(i);
3641
3642 if (field->is_repeated()) {
3643 PrintFieldComment(printer, field);
3644 field_generators_.get(field).GenerateByteSize(printer);
3645 printer->Print("\n");
3646 }
3647 }
3648
3649 // Fields inside a oneof don't use _has_bits_ so we count them in a separate 3760 // Fields inside a oneof don't use _has_bits_ so we count them in a separate
3650 // pass. 3761 // pass.
3651 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { 3762 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
3652 printer->Print( 3763 printer->Print(
3653 "switch ($oneofname$_case()) {\n", 3764 "switch ($oneofname$_case()) {\n",
3654 "oneofname", descriptor_->oneof_decl(i)->name()); 3765 "oneofname", descriptor_->oneof_decl(i)->name());
3655 printer->Indent(); 3766 printer->Indent();
3656 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { 3767 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
3657 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); 3768 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
3658 PrintFieldComment(printer, field); 3769 PrintFieldComment(printer, field);
(...skipping 12 matching lines...) Expand all
3671 "case $cap_oneof_name$_NOT_SET: {\n" 3782 "case $cap_oneof_name$_NOT_SET: {\n"
3672 " break;\n" 3783 " break;\n"
3673 "}\n", 3784 "}\n",
3674 "cap_oneof_name", 3785 "cap_oneof_name",
3675 ToUpper(descriptor_->oneof_decl(i)->name())); 3786 ToUpper(descriptor_->oneof_decl(i)->name()));
3676 printer->Outdent(); 3787 printer->Outdent();
3677 printer->Print( 3788 printer->Print(
3678 "}\n"); 3789 "}\n");
3679 } 3790 }
3680 3791
3681 if (descriptor_->extension_range_count() > 0) {
3682 printer->Print(
3683 "total_size += _extensions_.ByteSize();\n"
3684 "\n");
3685 }
3686
3687 if (PreserveUnknownFields(descriptor_)) {
3688 if (UseUnknownFieldSet(descriptor_->file(), options_)) {
3689 printer->Print(
3690 "if (_internal_metadata_.have_unknown_fields()) {\n"
3691 " total_size +=\n"
3692 " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( \n"
3693 " unknown_fields());\n"
3694 "}\n");
3695 } else {
3696 printer->Print(
3697 "total_size += unknown_fields().size();\n"
3698 "\n");
3699 }
3700 }
3701
3702 // We update _cached_size_ even though this is a const method. In theory, 3792 // We update _cached_size_ even though this is a const method. In theory,
3703 // this is not thread-compatible, because concurrent writes have undefined 3793 // this is not thread-compatible, because concurrent writes have undefined
3704 // results. In practice, since any concurrent writes will be writing the 3794 // results. In practice, since any concurrent writes will be writing the
3705 // exact same value, it works on all common processors. In a future version 3795 // exact same value, it works on all common processors. In a future version
3706 // of C++, _cached_size_ should be made into an atomic<int>. 3796 // of C++, _cached_size_ should be made into an atomic<int>.
3707 printer->Print( 3797 printer->Print(
3798 "int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n "
3708 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 3799 "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
3709 "_cached_size_ = total_size;\n" 3800 "_cached_size_ = cached_size;\n"
3710 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 3801 "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
3711 "return total_size;\n"); 3802 "return total_size;\n");
3712 3803
3713 printer->Outdent(); 3804 printer->Outdent();
3714 printer->Print("}\n"); 3805 printer->Print("}\n");
3715 } 3806 }
3716 3807
3717 void MessageGenerator:: 3808 void MessageGenerator::
3718 GenerateIsInitialized(io::Printer* printer) { 3809 GenerateIsInitialized(io::Printer* printer) {
3719 printer->Print( 3810 printer->Print(
3720 "bool $classname$::IsInitialized() const {\n", 3811 "bool $classname$::IsInitialized() const {\n",
3721 "classname", classname_); 3812 "classname", classname_);
3722 printer->Indent(); 3813 printer->Indent();
3723 3814
3815 if (descriptor_->extension_range_count() > 0) {
3816 printer->Print(
3817 "if (!_extensions_.IsInitialized()) {\n"
3818 " return false;\n"
3819 "}\n\n");
3820 }
3821
3724 if (HasFieldPresence(descriptor_->file())) { 3822 if (HasFieldPresence(descriptor_->file())) {
3725 // Check that all required fields in this message are set. We can do this 3823 // Check that all required fields in this message are set. We can do this
3726 // most efficiently by checking 32 "has bits" at a time. 3824 // most efficiently by checking 32 "has bits" at a time.
3727 int has_bits_array_size = (descriptor_->field_count() + 31) / 32; 3825 const std::vector<uint32> masks = RequiredFieldsBitMask();
3728 for (int i = 0; i < has_bits_array_size; i++) {
3729 uint32 mask = 0;
3730 for (int bit = 0; bit < 32; bit++) {
3731 int index = i * 32 + bit;
3732 if (index >= descriptor_->field_count()) break;
3733 const FieldDescriptor* field = descriptor_->field(index);
3734 3826
3735 if (field->is_required()) { 3827 for (int i = 0; i < masks.size(); i++) {
3736 mask |= 1 << bit; 3828 uint32 mask = masks[i];
3737 } 3829 if (mask == 0) {
3830 continue;
3738 } 3831 }
3739 3832
3740 if (mask != 0) { 3833 // TODO(ckennelly): Consider doing something similar to ByteSizeLong(),
3741 printer->Print( 3834 // where we check all of the required fields in a single branch (assuming
3742 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", 3835 // that we aren't going to benefit from early termination).
3743 "i", SimpleItoa(i), 3836 printer->Print(
3744 "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8))); 3837 "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
3745 } 3838 "i", SimpleItoa(i),
3839 "mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
3746 } 3840 }
3747 } 3841 }
3748 3842
3749 // Now check that all embedded messages are initialized. 3843 // Now check that all non-oneof embedded messages are initialized.
3750 printer->Print("\n"); 3844 for (int i = 0; i < optimized_order_.size(); i++) {
3751 for (int i = 0; i < descriptor_->field_count(); i++) { 3845 const FieldDescriptor* field = optimized_order_[i];
3752 const FieldDescriptor* field = descriptor_->field(i); 3846 // TODO(ckennelly): Push this down into a generator?
3753 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 3847 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
3754 !ShouldIgnoreRequiredFieldCheck(field, options_) && 3848 !ShouldIgnoreRequiredFieldCheck(field, options_) &&
3755 HasRequiredFields(field->message_type(), options_)) { 3849 HasRequiredFields(field->message_type(), options_)) {
3756 if (field->is_repeated()) { 3850 if (field->is_repeated()) {
3757 printer->Print( 3851 printer->Print(
3758 "if (!::google::protobuf::internal::AllAreInitialized(this->$name$())) " 3852 "if (!::google::protobuf::internal::AllAreInitialized(this->$name$())) "
3759 " return false;\n", 3853 " return false;\n",
3760 "name", FieldName(field)); 3854 "name", FieldName(field));
3761 } else { 3855 } else {
3762 if (field->options().weak() || !field->containing_oneof()) { 3856 GOOGLE_CHECK(field->options().weak() || !field->containing_oneof());
3857 // For weak fields, use the data member (::google::protobuf::Message*) i nstead
3858 // of the getter to avoid a link dependency on the weak message type
3859 // which is only forward declared.
3860 printer->Print(
3861 "if (has_$name$()) {\n"
3862 " if (!this->$name$_->IsInitialized()) return false;\n"
3863 "}\n",
3864 "name", FieldName(field));
3865 }
3866 }
3867 }
3868
3869 // Go through the oneof fields, emitting a switch if any might have required
3870 // fields.
3871 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
3872 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
3873
3874 bool has_required_fields = false;
3875 for (int j = 0; j < oneof->field_count(); j++) {
3876 const FieldDescriptor* field = oneof->field(j);
3877
3878 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
3879 !ShouldIgnoreRequiredFieldCheck(field, options_) &&
3880 HasRequiredFields(field->message_type(), options_)) {
3881 has_required_fields = true;
3882 break;
3883 }
3884 }
3885
3886 if (!has_required_fields) {
3887 continue;
3888 }
3889
3890 printer->Print(
3891 "switch ($oneofname$_case()) {\n",
3892 "oneofname", oneof->name());
3893 printer->Indent();
3894 for (int j = 0; j < oneof->field_count(); j++) {
3895 const FieldDescriptor* field = oneof->field(j);
3896 printer->Print(
3897 "case k$field_name$: {\n",
3898 "field_name", UnderscoresToCamelCase(field->name(), true));
3899 printer->Indent();
3900
3901 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
3902 !ShouldIgnoreRequiredFieldCheck(field, options_) &&
3903 HasRequiredFields(field->message_type(), options_)) {
3904 GOOGLE_CHECK(!(field->options().weak() || !field->containing_oneof()));
3905 if (field->options().weak()) {
3763 // For weak fields, use the data member (::google::protobuf::Message*) instead 3906 // For weak fields, use the data member (::google::protobuf::Message*) instead
3764 // of the getter to avoid a link dependency on the weak message type 3907 // of the getter to avoid a link dependency on the weak message type
3765 // which is only forward declared. 3908 // which is only forward declared.
3766 printer->Print( 3909 printer->Print(
3767 "if (has_$name$()) {\n" 3910 "if (has_$name$()) {\n"
3768 " if (!this->$name$_->IsInitialized()) return false;\n" 3911 " if (!this->$name$_->IsInitialized()) return false;\n"
3769 "}\n", 3912 "}\n",
3770 "name", FieldName(field)); 3913 "name", FieldName(field));
3771 } else { 3914 } else {
3772 printer->Print( 3915 printer->Print(
3773 "if (has_$name$()) {\n" 3916 "if (has_$name$()) {\n"
3774 " if (!this->$name$().IsInitialized()) return false;\n" 3917 " if (!this->$name$().IsInitialized()) return false;\n"
3775 "}\n", 3918 "}\n",
3776 "name", FieldName(field)); 3919 "name", FieldName(field));
3777 } 3920 }
3778 } 3921 }
3922
3923 printer->Print(
3924 "break;\n");
3925 printer->Outdent();
3926 printer->Print(
3927 "}\n");
3779 } 3928 }
3780 }
3781
3782 if (descriptor_->extension_range_count() > 0) {
3783 printer->Print( 3929 printer->Print(
3784 "\n" 3930 "case $cap_oneof_name$_NOT_SET: {\n"
3785 "if (!_extensions_.IsInitialized()) return false;"); 3931 " break;\n"
3932 "}\n",
3933 "cap_oneof_name",
3934 ToUpper(oneof->name()));
3935 printer->Outdent();
3936 printer->Print(
3937 "}\n");
3786 } 3938 }
3787 3939
3788 printer->Outdent(); 3940 printer->Outdent();
3789 printer->Print( 3941 printer->Print(
3790 " return true;\n" 3942 " return true;\n"
3791 "}\n"); 3943 "}\n");
3792 } 3944 }
3793 3945
3794 3946
3795 } // namespace cpp 3947 } // namespace cpp
3796 } // namespace compiler 3948 } // namespace compiler
3797 } // namespace protobuf 3949 } // namespace protobuf
3798 } // namespace google 3950 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698