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

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

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

Powered by Google App Engine
This is Rietveld 408576698