~ubuntu-branches/debian/stretch/protobuf/stretch

« back to all changes in this revision

Viewing changes to src/google/protobuf/compiler/cpp/cpp_message.cc

  • Committer: Package Import Robot
  • Author(s): Robert S. Edmonds
  • Date: 2014-09-11 22:50:10 UTC
  • mfrom: (10.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20140911225010-wt4yo9dpc1fzuq5g
Tags: 2.6.0-3
Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <algorithm>
36
36
#include <google/protobuf/stubs/hash.h>
37
37
#include <map>
 
38
#include <memory>
 
39
#include <set>
38
40
#include <utility>
39
41
#include <vector>
40
42
#include <google/protobuf/compiler/cpp/cpp_message.h>
74
76
  }
75
77
};
76
78
 
77
 
const char* kWireTypeNames[] = {
78
 
  "VARINT",
79
 
  "FIXED64",
80
 
  "LENGTH_DELIMITED",
81
 
  "START_GROUP",
82
 
  "END_GROUP",
83
 
  "FIXED32",
84
 
};
85
 
 
86
79
// Sort the fields of the given Descriptor by number into a new[]'d array
87
80
// and return it.
88
81
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
255
248
    aligned_to_4.push_back(field_group);
256
249
  }
257
250
  // Sort by preferred location to keep fields as close to their original
258
 
  // location as possible.
259
 
  sort(aligned_to_4.begin(), aligned_to_4.end());
 
251
  // location as possible.  Using stable_sort ensures that the output is
 
252
  // consistent across runs.
 
253
  stable_sort(aligned_to_4.begin(), aligned_to_4.end());
260
254
 
261
255
  // Now group fields aligned to 4 bytes (or the 4-field groups created above)
262
256
  // into pairs, and treat those like a single field aligned to 8 bytes.
271
265
    }
272
266
    aligned_to_8.push_back(field_group);
273
267
  }
274
 
  // Sort by preferred location to keep fields as close to their original
275
 
  // location as possible.
276
 
  sort(aligned_to_8.begin(), aligned_to_8.end());
 
268
  // Sort by preferred location.
 
269
  stable_sort(aligned_to_8.begin(), aligned_to_8.end());
277
270
 
278
271
  // Now pull out all the FieldDescriptors in order.
279
272
  fields->clear();
284
277
  }
285
278
}
286
279
 
 
280
string MessageTypeProtoName(const FieldDescriptor* field) {
 
281
  return field->message_type()->full_name();
 
282
}
 
283
 
287
284
}
288
285
 
289
286
// ===================================================================
290
287
 
291
288
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
292
289
                                   const Options& options)
293
 
  : descriptor_(descriptor),
294
 
    classname_(ClassName(descriptor, false)),
295
 
    options_(options),
296
 
    field_generators_(descriptor, options),
297
 
    nested_generators_(new scoped_ptr<MessageGenerator>[
298
 
      descriptor->nested_type_count()]),
299
 
    enum_generators_(new scoped_ptr<EnumGenerator>[
300
 
      descriptor->enum_type_count()]),
301
 
    extension_generators_(new scoped_ptr<ExtensionGenerator>[
302
 
      descriptor->extension_count()]) {
 
290
    : descriptor_(descriptor),
 
291
      classname_(ClassName(descriptor, false)),
 
292
      options_(options),
 
293
      field_generators_(descriptor, options),
 
294
      nested_generators_(new scoped_ptr<
 
295
          MessageGenerator>[descriptor->nested_type_count()]),
 
296
      enum_generators_(
 
297
          new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
 
298
      extension_generators_(new scoped_ptr<
 
299
          ExtensionGenerator>[descriptor->extension_count()]) {
303
300
 
304
301
  for (int i = 0; i < descriptor->nested_type_count(); i++) {
305
302
    nested_generators_[i].reset(
383
380
      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
384
381
      "classname", classname_);
385
382
  }
 
383
 
 
384
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
385
    printer->Print(
 
386
        "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
 
387
        "camel_oneof_name",
 
388
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
 
389
        "oneof_name", descriptor_->oneof_decl(i)->name());
 
390
  }
386
391
}
387
392
 
388
393
void MessageGenerator::
403
408
        "inline int $classname$::$name$_size() const {\n"
404
409
        "  return $name$_.size();\n"
405
410
        "}\n");
 
411
    } else if (field->containing_oneof()) {
 
412
      // Singular field in a oneof
 
413
      vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
 
414
      vars["oneof_name"] = field->containing_oneof()->name();
 
415
      vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
 
416
      printer->Print(vars,
 
417
        "inline bool $classname$::has_$name$() const {\n"
 
418
        "  return $oneof_name$_case() == k$field_name$;\n"
 
419
        "}\n"
 
420
        "inline void $classname$::set_has_$name$() {\n"
 
421
        "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
 
422
        "}\n");
406
423
    } else {
407
424
      // Singular field.
408
425
      char buffer[kFastToBufferSize];
426
443
      "inline void $classname$::clear_$name$() {\n");
427
444
 
428
445
    printer->Indent();
429
 
    field_generators_.get(field).GenerateClearingCode(printer);
 
446
 
 
447
    if (field->containing_oneof()) {
 
448
      // Clear this field only if it is the active field in this oneof,
 
449
      // otherwise ignore
 
450
      printer->Print(vars,
 
451
        "if (has_$name$()) {\n");
 
452
      printer->Indent();
 
453
      field_generators_.get(field).GenerateClearingCode(printer);
 
454
      printer->Print(vars,
 
455
        "clear_has_$oneof_name$();\n");
 
456
      printer->Outdent();
 
457
      printer->Print("}\n");
 
458
    } else {
 
459
      field_generators_.get(field).GenerateClearingCode(printer);
 
460
      if (!field->is_repeated()) {
 
461
        printer->Print(vars,
 
462
                       "clear_has_$name$();\n");
 
463
      }
 
464
    }
 
465
 
430
466
    printer->Outdent();
431
 
 
432
 
    if (!field->is_repeated()) {
433
 
      printer->Print(vars,
434
 
                     "  clear_has_$name$();\n");
435
 
    }
436
 
 
437
467
    printer->Print("}\n");
438
468
 
439
469
    // Generate type-specific accessors.
441
471
 
442
472
    printer->Print("\n");
443
473
  }
 
474
 
 
475
  // Generate has_$name$() and clear_has_$name$() functions for oneofs
 
476
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
477
    map<string, string> vars;
 
478
    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
 
479
    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
 
480
    vars["cap_oneof_name"] =
 
481
        ToUpper(descriptor_->oneof_decl(i)->name());
 
482
    vars["classname"] = classname_;
 
483
    printer->Print(
 
484
      vars,
 
485
      "inline bool $classname$::has_$oneof_name$() {\n"
 
486
      "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
 
487
      "}\n"
 
488
      "inline void $classname$::clear_has_$oneof_name$() {\n"
 
489
      "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
 
490
      "}\n");
 
491
  }
 
492
}
 
493
 
 
494
// Helper for the code that emits the Clear() method.
 
495
static bool CanClearByZeroing(const FieldDescriptor* field) {
 
496
  if (field->is_repeated() || field->is_extension()) return false;
 
497
  switch (field->cpp_type()) {
 
498
    case internal::WireFormatLite::CPPTYPE_ENUM:
 
499
      return field->default_value_enum()->number() == 0;
 
500
    case internal::WireFormatLite::CPPTYPE_INT32:
 
501
      return field->default_value_int32() == 0;
 
502
    case internal::WireFormatLite::CPPTYPE_INT64:
 
503
      return field->default_value_int64() == 0;
 
504
    case internal::WireFormatLite::CPPTYPE_UINT32:
 
505
      return field->default_value_uint32() == 0;
 
506
    case internal::WireFormatLite::CPPTYPE_UINT64:
 
507
      return field->default_value_uint64() == 0;
 
508
    case internal::WireFormatLite::CPPTYPE_FLOAT:
 
509
      return field->default_value_float() == 0;
 
510
    case internal::WireFormatLite::CPPTYPE_DOUBLE:
 
511
      return field->default_value_double() == 0;
 
512
    case internal::WireFormatLite::CPPTYPE_BOOL:
 
513
      return field->default_value_bool() == false;
 
514
    default:
 
515
      return false;
 
516
  }
444
517
}
445
518
 
446
519
void MessageGenerator::
455
528
  map<string, string> vars;
456
529
  vars["classname"] = classname_;
457
530
  vars["field_count"] = SimpleItoa(descriptor_->field_count());
 
531
  vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
458
532
  if (options_.dllexport_decl.empty()) {
459
533
    vars["dllexport"] = "";
460
534
  } else {
479
553
    "}\n"
480
554
    "\n");
481
555
 
482
 
  if (HasUnknownFields(descriptor_->file())) {
 
556
  if (UseUnknownFieldSet(descriptor_->file())) {
483
557
    printer->Print(
484
558
      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
485
559
      "  return _unknown_fields_;\n"
489
563
      "  return &_unknown_fields_;\n"
490
564
      "}\n"
491
565
      "\n");
 
566
  } else {
 
567
    printer->Print(
 
568
      "inline const ::std::string& unknown_fields() const {\n"
 
569
      "  return _unknown_fields_;\n"
 
570
      "}\n"
 
571
      "\n"
 
572
      "inline ::std::string* mutable_unknown_fields() {\n"
 
573
      "  return &_unknown_fields_;\n"
 
574
      "}\n"
 
575
      "\n");
492
576
  }
493
577
 
494
578
  // Only generate this member if it's not disabled.
502
586
    "static const $classname$& default_instance();\n"
503
587
    "\n");
504
588
 
 
589
  // Generate enum values for every field in oneofs. One list is generated for
 
590
  // each oneof with an additional *_NOT_SET value.
 
591
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
592
    printer->Print(
 
593
        "enum $camel_oneof_name$Case {\n",
 
594
        "camel_oneof_name",
 
595
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
 
596
    printer->Indent();
 
597
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
598
      printer->Print(
 
599
          "k$field_name$ = $field_number$,\n",
 
600
          "field_name",
 
601
          UnderscoresToCamelCase(
 
602
              descriptor_->oneof_decl(i)->field(j)->name(), true),
 
603
          "field_number",
 
604
          SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
 
605
    }
 
606
    printer->Print(
 
607
        "$cap_oneof_name$_NOT_SET = 0,\n",
 
608
        "cap_oneof_name",
 
609
        ToUpper(descriptor_->oneof_decl(i)->name()));
 
610
    printer->Outdent();
 
611
    printer->Print(
 
612
        "};\n"
 
613
        "\n");
 
614
  }
 
615
 
505
616
  if (!StaticInitializersForced(descriptor_->file())) {
506
617
    printer->Print(vars,
507
618
      "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
545
656
      "    ::google::protobuf::io::CodedInputStream* input);\n"
546
657
      "void SerializeWithCachedSizes(\n"
547
658
      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
 
659
    // DiscardUnknownFields() is implemented in message.cc using reflections. We
 
660
    // need to implement this function in generated code for messages.
 
661
    if (!UseUnknownFieldSet(descriptor_->file())) {
 
662
      printer->Print(
 
663
        "void DiscardUnknownFields();\n");
 
664
    }
548
665
    if (HasFastArraySerialization(descriptor_->file())) {
549
666
      printer->Print(
550
667
        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
551
668
    }
552
669
  }
553
670
 
554
 
  printer->Print(vars,
 
671
  // Check all FieldDescriptors including those in oneofs to estimate
 
672
  // whether ::std::string is likely to be used, and depending on that
 
673
  // estimate, set uses_string_ to true or false.  That contols
 
674
  // whether to force initialization of empty_string_ in SharedCtor().
 
675
  // It's often advantageous to do so to keep "is empty_string_
 
676
  // inited?" code from appearing all over the place.
 
677
  vector<const FieldDescriptor*> descriptors;
 
678
  for (int i = 0; i < descriptor_->field_count(); i++) {
 
679
    descriptors.push_back(descriptor_->field(i));
 
680
  }
 
681
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
682
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
683
      descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
 
684
    }
 
685
  }
 
686
  uses_string_ = false;
 
687
  for (int i = 0; i < descriptors.size(); i++) {
 
688
    const FieldDescriptor* field = descriptors[i];
 
689
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
 
690
      switch (field->options().ctype()) {
 
691
        default: uses_string_ = true; break;
 
692
      }
 
693
    }
 
694
  }
 
695
 
 
696
  printer->Print(
555
697
    "int GetCachedSize() const { return _cached_size_; }\n"
556
698
    "private:\n"
557
699
    "void SharedCtor();\n"
558
700
    "void SharedDtor();\n"
559
701
    "void SetCachedSize(int size) const;\n"
560
 
    "public:\n"
561
 
    "\n");
 
702
    "public:\n");
562
703
 
563
704
  if (HasDescriptorMethods(descriptor_->file())) {
564
705
    printer->Print(
621
762
      printer->Print(
622
763
        "inline void set_has_$name$();\n",
623
764
        "name", FieldName(descriptor_->field(i)));
624
 
      printer->Print(
625
 
        "inline void clear_has_$name$();\n",
626
 
        "name", FieldName(descriptor_->field(i)));
 
765
      if (!descriptor_->field(i)->containing_oneof()) {
 
766
        printer->Print(
 
767
          "inline void clear_has_$name$();\n",
 
768
          "name", FieldName(descriptor_->field(i)));
 
769
      }
627
770
    }
628
771
  }
629
772
  printer->Print("\n");
630
773
 
 
774
  // Generate oneof function declarations
 
775
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
776
    printer->Print(
 
777
        "inline bool has_$oneof_name$();\n"
 
778
        "void clear_$oneof_name$();\n"
 
779
        "inline void clear_has_$oneof_name$();\n\n",
 
780
        "oneof_name", descriptor_->oneof_decl(i)->name());
 
781
  }
 
782
 
 
783
  // Prepare decls for _cached_size_ and _has_bits_.  Their position in the
 
784
  // output will be determined later.
 
785
 
 
786
  bool need_to_emit_cached_size = true;
 
787
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
 
788
  const string cached_size_decl = "mutable int _cached_size_;\n";
 
789
 
 
790
  // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
 
791
  size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
 
792
  if (descriptor_->field_count() == 0) {
 
793
    // Zero-size arrays aren't technically allowed, and MSVC in particular
 
794
    // doesn't like them.  We still need to declare these arrays to make
 
795
    // other code compile.  Since this is an uncommon case, we'll just declare
 
796
    // them with size 1 and waste some space.  Oh well.
 
797
    sizeof_has_bits = 4;
 
798
  }
 
799
  const string has_bits_decl = sizeof_has_bits == 0 ? "" :
 
800
      "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
 
801
 
 
802
 
631
803
  // To minimize padding, data members are divided into three sections:
632
804
  // (1) members assumed to align to 8 bytes
633
805
  // (2) members corresponding to message fields, re-ordered to optimize
642
814
      "\n");
643
815
  }
644
816
 
645
 
  if (HasUnknownFields(descriptor_->file())) {
 
817
  if (UseUnknownFieldSet(descriptor_->file())) {
646
818
    printer->Print(
647
819
      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
648
820
      "\n");
 
821
  } else {
 
822
    printer->Print(
 
823
      "::std::string _unknown_fields_;\n"
 
824
      "\n");
 
825
  }
 
826
 
 
827
  // _has_bits_ is frequently accessed, so to reduce code size and improve
 
828
  // speed, it should be close to the start of the object.  But, try not to
 
829
  // waste space:_has_bits_ by itself always makes sense if its size is a
 
830
  // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
 
831
  // will work well.
 
832
  printer->Print(has_bits_decl.c_str());
 
833
  if ((sizeof_has_bits % 8) != 0) {
 
834
    printer->Print(cached_size_decl.c_str());
 
835
    need_to_emit_cached_size = false;
649
836
  }
650
837
 
651
838
  // Field members:
652
839
 
 
840
  // List fields which doesn't belong to any oneof
653
841
  vector<const FieldDescriptor*> fields;
 
842
  hash_map<string, int> fieldname_to_chunk;
654
843
  for (int i = 0; i < descriptor_->field_count(); i++) {
655
 
    fields.push_back(descriptor_->field(i));
 
844
    if (!descriptor_->field(i)->containing_oneof()) {
 
845
      const FieldDescriptor* field = descriptor_->field(i);
 
846
      fields.push_back(field);
 
847
      fieldname_to_chunk[FieldName(field)] = i / 8;
 
848
    }
656
849
  }
657
850
  OptimizePadding(&fields);
 
851
  // Emit some private and static members
 
852
  runs_of_fields_ = vector< vector<string> >(1);
658
853
  for (int i = 0; i < fields.size(); ++i) {
659
 
    field_generators_.get(fields[i]).GeneratePrivateMembers(printer);
 
854
    const FieldDescriptor* field = fields[i];
 
855
    const FieldGenerator& generator = field_generators_.get(field);
 
856
    generator.GenerateStaticMembers(printer);
 
857
    generator.GeneratePrivateMembers(printer);
 
858
    if (CanClearByZeroing(field)) {
 
859
      const string& fieldname = FieldName(field);
 
860
      if (!runs_of_fields_.back().empty() &&
 
861
          (fieldname_to_chunk[runs_of_fields_.back().back()] !=
 
862
           fieldname_to_chunk[fieldname])) {
 
863
        runs_of_fields_.push_back(vector<string>());
 
864
      }
 
865
      runs_of_fields_.back().push_back(fieldname);
 
866
    } else if (!runs_of_fields_.back().empty()) {
 
867
      runs_of_fields_.push_back(vector<string>());
 
868
    }
 
869
  }
 
870
 
 
871
  // For each oneof generate a union
 
872
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
873
    printer->Print(
 
874
        "union $camel_oneof_name$Union {\n",
 
875
        "camel_oneof_name",
 
876
        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
 
877
    printer->Indent();
 
878
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
879
      field_generators_.get(descriptor_->oneof_decl(i)->
 
880
                            field(j)).GeneratePrivateMembers(printer);
 
881
    }
 
882
    printer->Outdent();
 
883
    printer->Print(
 
884
        "} $oneof_name$_;\n",
 
885
        "oneof_name", descriptor_->oneof_decl(i)->name());
 
886
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
887
      field_generators_.get(descriptor_->oneof_decl(i)->
 
888
                            field(j)).GenerateStaticMembers(printer);
 
889
    }
660
890
  }
661
891
 
662
892
  // Members assumed to align to 4 bytes:
663
893
 
664
 
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
665
 
  printer->Print(
666
 
      "\n"
667
 
      "mutable int _cached_size_;\n");
 
894
  if (need_to_emit_cached_size) {
 
895
    printer->Print(cached_size_decl.c_str());
 
896
    need_to_emit_cached_size = false;
 
897
  }
668
898
 
669
 
  // Generate _has_bits_.
670
 
  if (descriptor_->field_count() > 0) {
 
899
  // Generate _oneof_case_.
 
900
  if (descriptor_->oneof_decl_count() > 0) {
671
901
    printer->Print(vars,
672
 
      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"
673
 
      "\n");
674
 
  } else {
675
 
    // Zero-size arrays aren't technically allowed, and MSVC in particular
676
 
    // doesn't like them.  We still need to declare these arrays to make
677
 
    // other code compile.  Since this is an uncommon case, we'll just declare
678
 
    // them with size 1 and waste some space.  Oh well.
679
 
    printer->Print(
680
 
      "::google::protobuf::uint32 _has_bits_[1];\n"
 
902
      "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
681
903
      "\n");
682
904
  }
683
905
 
710
932
 
711
933
  printer->Outdent();
712
934
  printer->Print(vars, "};");
 
935
  GOOGLE_DCHECK(!need_to_emit_cached_size);
713
936
}
714
937
 
715
938
void MessageGenerator::
721
944
  }
722
945
 
723
946
  GenerateFieldAccessorDefinitions(printer);
 
947
 
 
948
  // Generate oneof_case() functions.
 
949
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
950
    map<string, string> vars;
 
951
    vars["class_name"] = classname_;
 
952
    vars["camel_oneof_name"] = UnderscoresToCamelCase(
 
953
        descriptor_->oneof_decl(i)->name(), true);
 
954
    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
 
955
    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
 
956
    printer->Print(
 
957
        vars,
 
958
        "inline $class_name$::$camel_oneof_name$Case $class_name$::"
 
959
        "$oneof_name$_case() const {\n"
 
960
        "  return $class_name$::$camel_oneof_name$Case("
 
961
        "_oneof_case_[$oneof_index$]);\n"
 
962
        "}\n");
 
963
  }
724
964
}
725
965
 
726
966
void MessageGenerator::
731
971
    "  $name$_reflection_ = NULL;\n",
732
972
    "name", classname_);
733
973
 
 
974
  // Generate oneof default instance for reflection usage.
 
975
  if (descriptor_->oneof_decl_count() > 0) {
 
976
    printer->Print("struct $name$OneofInstance {\n",
 
977
                   "name", classname_);
 
978
    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
979
      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
980
        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
 
981
        printer->Print("  ");
 
982
        if (IsStringOrMessage(field)) {
 
983
          printer->Print("const ");
 
984
        }
 
985
        field_generators_.get(field).GeneratePrivateMembers(printer);
 
986
      }
 
987
    }
 
988
 
 
989
    printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
 
990
                   "name", classname_);
 
991
  }
 
992
 
734
993
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
735
994
    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
736
995
  }
783
1042
    printer->Print(vars,
784
1043
      "    -1,\n");
785
1044
  }
 
1045
 
 
1046
  if (descriptor_->oneof_decl_count() > 0) {
 
1047
    printer->Print(vars,
 
1048
    "    $classname$_default_oneof_instance_,\n"
 
1049
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
 
1050
      "$classname$, _oneof_case_[0]),\n");
 
1051
  }
 
1052
 
786
1053
  printer->Print(
787
1054
    "    ::google::protobuf::DescriptorPool::generated_pool(),\n");
788
1055
  printer->Print(vars,
830
1097
    "$classname$::default_instance_ = new $classname$();\n",
831
1098
    "classname", classname_);
832
1099
 
 
1100
  if ((descriptor_->oneof_decl_count() > 0) &&
 
1101
      HasDescriptorMethods(descriptor_->file())) {
 
1102
    printer->Print(
 
1103
    "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
 
1104
    "classname", classname_);
 
1105
  }
 
1106
 
833
1107
  // Handle nested types.
834
1108
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
835
1109
    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
861
1135
    "classname", classname_);
862
1136
 
863
1137
  if (HasDescriptorMethods(descriptor_->file())) {
 
1138
    if (descriptor_->oneof_decl_count() > 0) {
 
1139
      printer->Print(
 
1140
        "delete $classname$_default_oneof_instance_;\n",
 
1141
        "classname", classname_);
 
1142
    }
864
1143
    printer->Print(
865
1144
      "delete $classname$_reflection_;\n",
866
1145
      "classname", classname_);
918
1197
  GenerateStructors(printer);
919
1198
  printer->Print("\n");
920
1199
 
 
1200
  if (descriptor_->oneof_decl_count() > 0) {
 
1201
    GenerateOneofClear(printer);
 
1202
    printer->Print("\n");
 
1203
  }
 
1204
 
921
1205
  if (HasGeneratedMethods(descriptor_->file())) {
922
1206
    GenerateClear(printer);
923
1207
    printer->Print("\n");
977
1261
  printer->Print(
978
1262
    "static const int $classname$_offsets_[$field_count$] = {\n",
979
1263
    "classname", classname_,
980
 
    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
 
1264
    "field_count", SimpleItoa(max(
 
1265
        1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
981
1266
  printer->Indent();
982
1267
 
983
1268
  for (int i = 0; i < descriptor_->field_count(); i++) {
984
1269
    const FieldDescriptor* field = descriptor_->field(i);
 
1270
    if (field->containing_oneof()) {
 
1271
      printer->Print(
 
1272
          "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
 
1273
          "$classname$_default_oneof_instance_, $name$_),\n",
 
1274
          "classname", classname_,
 
1275
          "name", FieldName(field));
 
1276
    } else {
 
1277
      printer->Print(
 
1278
          "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
 
1279
                                                 "$name$_),\n",
 
1280
          "classname", classname_,
 
1281
          "name", FieldName(field));
 
1282
    }
 
1283
  }
 
1284
 
 
1285
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1286
    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
985
1287
    printer->Print(
986
1288
      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
987
1289
      "classname", classname_,
988
 
      "name", FieldName(field));
 
1290
      "name", oneof->name());
989
1291
  }
990
1292
 
991
1293
  printer->Outdent();
999
1301
    "classname", classname_);
1000
1302
  printer->Indent();
1001
1303
 
1002
 
  printer->Print(
1003
 
    "_cached_size_ = 0;\n");
 
1304
  printer->Print(StrCat(
 
1305
      uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
 
1306
      "_cached_size_ = 0;\n").c_str());
1004
1307
 
1005
1308
  for (int i = 0; i < descriptor_->field_count(); i++) {
1006
 
    field_generators_.get(descriptor_->field(i))
1007
 
                     .GenerateConstructorCode(printer);
 
1309
    if (!descriptor_->field(i)->containing_oneof()) {
 
1310
      field_generators_.get(descriptor_->field(i))
 
1311
          .GenerateConstructorCode(printer);
 
1312
    }
1008
1313
  }
1009
1314
 
1010
1315
  printer->Print(
1011
1316
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1012
1317
 
 
1318
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1319
    printer->Print(
 
1320
        "clear_has_$oneof_name$();\n",
 
1321
        "oneof_name", descriptor_->oneof_decl(i)->name());
 
1322
  }
 
1323
 
1013
1324
  printer->Outdent();
1014
1325
  printer->Print("}\n\n");
1015
1326
}
1020
1331
    "void $classname$::SharedDtor() {\n",
1021
1332
    "classname", classname_);
1022
1333
  printer->Indent();
1023
 
  // Write the destructors for each field.
 
1334
  // Write the destructors for each field except oneof members.
1024
1335
  for (int i = 0; i < descriptor_->field_count(); i++) {
1025
 
    field_generators_.get(descriptor_->field(i))
1026
 
                     .GenerateDestructorCode(printer);
 
1336
    if (!descriptor_->field(i)->containing_oneof()) {
 
1337
      field_generators_.get(descriptor_->field(i))
 
1338
                       .GenerateDestructorCode(printer);
 
1339
    }
 
1340
  }
 
1341
 
 
1342
  // Generate code to destruct oneofs. Clearing should do the work.
 
1343
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1344
    printer->Print(
 
1345
        "if (has_$oneof_name$()) {\n"
 
1346
        "  clear_$oneof_name$();\n"
 
1347
        "}\n",
 
1348
        "oneof_name", descriptor_->oneof_decl(i)->name());
1027
1349
  }
1028
1350
 
1029
1351
  PrintHandlingOptionalStaticInitializers(
1042
1364
 
1043
1365
    if (!field->is_repeated() &&
1044
1366
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1045
 
      printer->Print("  delete $name$_;\n",
1046
 
                     "name", FieldName(field));
 
1367
      // Skip oneof members
 
1368
      if (!field->containing_oneof()) {
 
1369
        printer->Print(
 
1370
            "  delete $name$_;\n",
 
1371
            "name", FieldName(field));
 
1372
      }
1047
1373
    }
1048
1374
  }
1049
1375
 
1063
1389
    "$classname$::$classname$()\n"
1064
1390
    "  : $superclass$() {\n"
1065
1391
    "  SharedCtor();\n"
 
1392
    "  // @@protoc_insertion_point(constructor:$full_name$)\n"
1066
1393
    "}\n",
1067
1394
    "classname", classname_,
1068
 
    "superclass", superclass);
 
1395
    "superclass", superclass,
 
1396
    "full_name", descriptor_->full_name());
1069
1397
 
1070
1398
  printer->Print(
1071
1399
    "\n"
1082
1410
    const FieldDescriptor* field = descriptor_->field(i);
1083
1411
 
1084
1412
    if (!field->is_repeated() &&
1085
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
 
1413
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
 
1414
        (field->containing_oneof() == NULL ||
 
1415
         HasDescriptorMethods(descriptor_->file()))) {
 
1416
      string name;
 
1417
      if (field->containing_oneof()) {
 
1418
        name = classname_ + "_default_oneof_instance_->";
 
1419
      }
 
1420
      name += FieldName(field);
1086
1421
      PrintHandlingOptionalStaticInitializers(
1087
1422
        descriptor_->file(), printer,
1088
1423
        // With static initializers.
1091
1426
        "  $name$_ = const_cast< $type$*>(\n"
1092
1427
        "      $type$::internal_default_instance());\n",
1093
1428
        // Vars.
1094
 
        "name", FieldName(field),
 
1429
        "name", name,
1095
1430
        "type", FieldMessageTypeName(field));
 
1431
    } else if (field->containing_oneof() &&
 
1432
               HasDescriptorMethods(descriptor_->file())) {
 
1433
      field_generators_.get(descriptor_->field(i))
 
1434
          .GenerateConstructorCode(printer);
1096
1435
    }
1097
1436
  }
1098
1437
  printer->Print(
1105
1444
    "  : $superclass$() {\n"
1106
1445
    "  SharedCtor();\n"
1107
1446
    "  MergeFrom(from);\n"
 
1447
    "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
1108
1448
    "}\n"
1109
1449
    "\n",
1110
1450
    "classname", classname_,
1111
 
    "superclass", superclass);
 
1451
    "superclass", superclass,
 
1452
    "full_name", descriptor_->full_name());
1112
1453
 
1113
1454
  // Generate the shared constructor code.
1114
1455
  GenerateSharedConstructorCode(printer);
1116
1457
  // Generate the destructor.
1117
1458
  printer->Print(
1118
1459
    "$classname$::~$classname$() {\n"
 
1460
    "  // @@protoc_insertion_point(destructor:$full_name$)\n"
1119
1461
    "  SharedDtor();\n"
1120
1462
    "}\n"
1121
1463
    "\n",
1122
 
    "classname", classname_);
 
1464
    "classname", classname_,
 
1465
    "full_name", descriptor_->full_name());
1123
1466
 
1124
1467
  // Generate the shared destructor code.
1125
1468
  GenerateSharedDestructorCode(printer);
1166
1509
    "}\n"
1167
1510
    "\n"
1168
1511
    "$classname$* $classname$::default_instance_ = NULL;\n"
1169
 
    "\n"
 
1512
    "\n",
 
1513
    "classname", classname_);
 
1514
 
 
1515
  printer->Print(
1170
1516
    "$classname$* $classname$::New() const {\n"
1171
1517
    "  return new $classname$;\n"
1172
1518
    "}\n",
1173
 
    "classname", classname_,
1174
 
    "adddescriptorsname",
1175
 
    GlobalAddDescriptorsName(descriptor_->file()->name()));
 
1519
    "classname", classname_);
 
1520
 
 
1521
}
 
1522
 
 
1523
// Return the number of bits set in n, a non-negative integer.
 
1524
static int popcnt(uint32 n) {
 
1525
  int result = 0;
 
1526
  while (n != 0) {
 
1527
    result += (n & 1);
 
1528
    n = n / 2;
 
1529
  }
 
1530
  return result;
1176
1531
}
1177
1532
 
1178
1533
void MessageGenerator::
1181
1536
                 "classname", classname_);
1182
1537
  printer->Indent();
1183
1538
 
1184
 
  int last_index = -1;
1185
 
 
 
1539
  // Step 1: Extensions
1186
1540
  if (descriptor_->extension_range_count() > 0) {
1187
1541
    printer->Print("_extensions_.Clear();\n");
1188
1542
  }
1189
1543
 
1190
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
1191
 
    const FieldDescriptor* field = descriptor_->field(i);
1192
 
 
1193
 
    if (!field->is_repeated()) {
1194
 
      // We can use the fact that _has_bits_ is a giant bitfield to our
1195
 
      // advantage:  We can check up to 32 bits at a time for equality to
1196
 
      // zero, and skip the whole range if so.  This can improve the speed
1197
 
      // of Clear() for messages which contain a very large number of
1198
 
      // optional fields of which only a few are used at a time.  Here,
1199
 
      // we've chosen to check 8 bits at a time rather than 32.
1200
 
      if (i / 8 != last_index / 8 || last_index < 0) {
1201
 
        if (last_index >= 0) {
1202
 
          printer->Outdent();
1203
 
          printer->Print("}\n");
1204
 
        }
1205
 
        printer->Print(
1206
 
          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1207
 
          "index", SimpleItoa(field->index()));
1208
 
        printer->Indent();
1209
 
      }
1210
 
      last_index = i;
1211
 
 
1212
 
      // It's faster to just overwrite primitive types, but we should
1213
 
      // only clear strings and messages if they were set.
1214
 
      // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
1215
 
      bool should_check_bit =
1216
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1217
 
        field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
1218
 
 
1219
 
      if (should_check_bit) {
1220
 
        printer->Print(
1221
 
          "if (has_$name$()) {\n",
1222
 
          "name", FieldName(field));
1223
 
        printer->Indent();
1224
 
      }
1225
 
 
1226
 
      field_generators_.get(field).GenerateClearingCode(printer);
1227
 
 
1228
 
      if (should_check_bit) {
 
1544
  // Step 2: Everything but extensions, repeateds, unions.
 
1545
  // These are handled in chunks of 8.  The first chunk is
 
1546
  // the non-extensions-non-repeateds-non-unions in
 
1547
  //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
 
1548
  // and the second chunk is the same for
 
1549
  //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
 
1550
  // etc.
 
1551
  set<int> step2_indices;
 
1552
  hash_map<string, int> fieldname_to_chunk;
 
1553
  hash_map<int, string> memsets_for_chunk;
 
1554
  hash_map<int, int> memset_field_count_for_chunk;
 
1555
  hash_set<string> handled;  // fields that appear anywhere in memsets_for_chunk
 
1556
  hash_map<int, uint32> fields_mask_for_chunk;
 
1557
  for (int i = 0; i < descriptor_->field_count(); i++) {
 
1558
    const FieldDescriptor* field = descriptor_->field(i);
 
1559
    if (!field->is_repeated() && !field->containing_oneof()) {
 
1560
      step2_indices.insert(i);
 
1561
      int chunk = i / 8;
 
1562
      fieldname_to_chunk[FieldName(field)] = chunk;
 
1563
      fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
 
1564
    }
 
1565
  }
 
1566
 
 
1567
  // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
 
1568
  // The generated code uses two macros to help it clear runs of fields:
 
1569
  // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
 
1570
  // ZR_ zeroes a non-empty range of fields via memset.
 
1571
  const char* macros =
 
1572
      "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \\\n"
 
1573
      "  &reinterpret_cast<$classname$*>(16)->f) - \\\n"
 
1574
      "   reinterpret_cast<char*>(16))\n\n"
 
1575
      "#define ZR_(first, last) do {                              \\\n"
 
1576
      "    size_t f = OFFSET_OF_FIELD_(first);                    \\\n"
 
1577
      "    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \\\n"
 
1578
      "    ::memset(&first, 0, n);                                \\\n"
 
1579
      "  } while (0)\n\n";
 
1580
  for (int i = 0; i < runs_of_fields_.size(); i++) {
 
1581
    const vector<string>& run = runs_of_fields_[i];
 
1582
    if (run.size() < 2) continue;
 
1583
    const string& first_field_name = run[0];
 
1584
    const string& last_field_name = run.back();
 
1585
    int chunk = fieldname_to_chunk[run[0]];
 
1586
    memsets_for_chunk[chunk].append(
 
1587
      "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
 
1588
    for (int j = 0; j < run.size(); j++) {
 
1589
      GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
 
1590
      handled.insert(run[j]);
 
1591
    }
 
1592
    memset_field_count_for_chunk[chunk] += run.size();
 
1593
  }
 
1594
  const bool macros_are_needed = handled.size() > 0;
 
1595
  if (macros_are_needed) {
 
1596
    printer->Outdent();
 
1597
    printer->Print(macros,
 
1598
                   "classname", classname_);
 
1599
    printer->Indent();
 
1600
  }
 
1601
  // Step 2b: Finish step 2, ignoring fields handled in step 2a.
 
1602
  int last_index = -1;
 
1603
  bool chunk_block_in_progress = false;
 
1604
  for (int i = 0; i < descriptor_->field_count(); i++) {
 
1605
    if (step2_indices.count(i) == 0) continue;
 
1606
    const FieldDescriptor* field = descriptor_->field(i);
 
1607
    const string fieldname = FieldName(field);
 
1608
    if (i / 8 != last_index / 8 || last_index < 0) {
 
1609
      // End previous chunk, if there was one.
 
1610
      if (chunk_block_in_progress) {
1229
1611
        printer->Outdent();
1230
1612
        printer->Print("}\n");
1231
 
      }
 
1613
        chunk_block_in_progress = false;
 
1614
      }
 
1615
      // Start chunk.
 
1616
      const string& memsets = memsets_for_chunk[i / 8];
 
1617
      uint32 mask = fields_mask_for_chunk[i / 8];
 
1618
      int count = popcnt(mask);
 
1619
      if (count == 1 ||
 
1620
          (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
 
1621
        // No "if" here because the chunk is trivial.
 
1622
      } else {
 
1623
        printer->Print(
 
1624
          "if (_has_bits_[$index$ / 32] & $mask$) {\n",
 
1625
          "index", SimpleItoa(i / 8 * 8),
 
1626
          "mask", SimpleItoa(mask));
 
1627
        printer->Indent();
 
1628
        chunk_block_in_progress = true;
 
1629
      }
 
1630
      printer->Print(memsets.c_str());
 
1631
    }
 
1632
    last_index = i;
 
1633
    if (handled.count(fieldname) > 0) continue;
 
1634
 
 
1635
    // It's faster to just overwrite primitive types, but we should
 
1636
    // only clear strings and messages if they were set.
 
1637
    // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
 
1638
    bool should_check_bit =
 
1639
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
 
1640
      field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
 
1641
 
 
1642
    if (should_check_bit) {
 
1643
      printer->Print("if (has_$name$()) {\n", "name", fieldname);
 
1644
      printer->Indent();
 
1645
    }
 
1646
 
 
1647
    field_generators_.get(field).GenerateClearingCode(printer);
 
1648
 
 
1649
    if (should_check_bit) {
 
1650
      printer->Outdent();
 
1651
      printer->Print("}\n");
1232
1652
    }
1233
1653
  }
1234
1654
 
1235
 
  if (last_index >= 0) {
 
1655
  if (chunk_block_in_progress) {
1236
1656
    printer->Outdent();
1237
1657
    printer->Print("}\n");
1238
1658
  }
 
1659
  if (macros_are_needed) {
 
1660
    printer->Outdent();
 
1661
    printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
 
1662
    printer->Indent();
 
1663
  }
1239
1664
 
1240
 
  // Repeated fields don't use _has_bits_ so we clear them in a separate
1241
 
  // pass.
 
1665
  // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
1242
1666
  for (int i = 0; i < descriptor_->field_count(); i++) {
1243
1667
    const FieldDescriptor* field = descriptor_->field(i);
1244
1668
 
1247
1671
    }
1248
1672
  }
1249
1673
 
 
1674
  // Step 4: Unions.
 
1675
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1676
    printer->Print(
 
1677
        "clear_$oneof_name$();\n",
 
1678
        "oneof_name", descriptor_->oneof_decl(i)->name());
 
1679
  }
 
1680
 
 
1681
  // Step 5: Everything else.
1250
1682
  printer->Print(
1251
1683
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1252
1684
 
1253
 
  if (HasUnknownFields(descriptor_->file())) {
 
1685
  if (UseUnknownFieldSet(descriptor_->file())) {
1254
1686
    printer->Print(
1255
1687
      "mutable_unknown_fields()->Clear();\n");
 
1688
  } else {
 
1689
    printer->Print(
 
1690
      "mutable_unknown_fields()->clear();\n");
1256
1691
  }
1257
1692
 
1258
1693
  printer->Outdent();
1260
1695
}
1261
1696
 
1262
1697
void MessageGenerator::
 
1698
GenerateOneofClear(io::Printer* printer) {
 
1699
  // Generated function clears the active field and union case (e.g. foo_case_).
 
1700
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1701
    printer->Print(
 
1702
        "void $classname$::clear_$oneofname$() {\n",
 
1703
        "classname", classname_,
 
1704
        "oneofname", descriptor_->oneof_decl(i)->name());
 
1705
    printer->Indent();
 
1706
    printer->Print(
 
1707
        "switch($oneofname$_case()) {\n",
 
1708
        "oneofname", descriptor_->oneof_decl(i)->name());
 
1709
    printer->Indent();
 
1710
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
1711
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
 
1712
      printer->Print(
 
1713
          "case k$field_name$: {\n",
 
1714
          "field_name", UnderscoresToCamelCase(field->name(), true));
 
1715
      printer->Indent();
 
1716
      // We clear only allocated objects in oneofs
 
1717
      if (!IsStringOrMessage(field)) {
 
1718
        printer->Print(
 
1719
            "// No need to clear\n");
 
1720
      } else {
 
1721
        field_generators_.get(field).GenerateClearingCode(printer);
 
1722
      }
 
1723
      printer->Print(
 
1724
          "break;\n");
 
1725
      printer->Outdent();
 
1726
      printer->Print(
 
1727
          "}\n");
 
1728
    }
 
1729
    printer->Print(
 
1730
        "case $cap_oneof_name$_NOT_SET: {\n"
 
1731
        "  break;\n"
 
1732
        "}\n",
 
1733
        "cap_oneof_name",
 
1734
        ToUpper(descriptor_->oneof_decl(i)->name()));
 
1735
    printer->Outdent();
 
1736
    printer->Print(
 
1737
        "}\n"
 
1738
        "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
 
1739
        "oneof_index", SimpleItoa(i),
 
1740
        "cap_oneof_name",
 
1741
        ToUpper(descriptor_->oneof_decl(i)->name()));
 
1742
    printer->Outdent();
 
1743
    printer->Print(
 
1744
        "}\n"
 
1745
        "\n");
 
1746
  }
 
1747
}
 
1748
 
 
1749
void MessageGenerator::
1263
1750
GenerateSwap(io::Printer* printer) {
1264
1751
  // Generate the Swap member function.
1265
1752
  printer->Print("void $classname$::Swap($classname$* other) {\n",
1274
1761
      field_generators_.get(field).GenerateSwappingCode(printer);
1275
1762
    }
1276
1763
 
 
1764
    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
1765
      printer->Print(
 
1766
        "std::swap($oneof_name$_, other->$oneof_name$_);\n"
 
1767
        "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
 
1768
        "oneof_name", descriptor_->oneof_decl(i)->name(),
 
1769
        "i", SimpleItoa(i));
 
1770
    }
 
1771
 
1277
1772
    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1278
1773
      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1279
1774
                     "i", SimpleItoa(i));
1280
1775
    }
1281
1776
 
1282
 
    if (HasUnknownFields(descriptor_->file())) {
 
1777
    if (UseUnknownFieldSet(descriptor_->file())) {
1283
1778
      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
 
1779
    } else {
 
1780
      printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
1284
1781
    }
1285
1782
    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1286
1783
    if (descriptor_->extension_range_count() > 0) {
1352
1849
    }
1353
1850
  }
1354
1851
 
 
1852
  // Merge oneof fields. Oneof field requires oneof case check.
 
1853
  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
 
1854
    printer->Print(
 
1855
        "switch (from.$oneofname$_case()) {\n",
 
1856
        "oneofname", descriptor_->oneof_decl(i)->name());
 
1857
    printer->Indent();
 
1858
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
1859
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
 
1860
      printer->Print(
 
1861
          "case k$field_name$: {\n",
 
1862
          "field_name", UnderscoresToCamelCase(field->name(), true));
 
1863
      printer->Indent();
 
1864
      field_generators_.get(field).GenerateMergingCode(printer);
 
1865
      printer->Print(
 
1866
          "break;\n");
 
1867
      printer->Outdent();
 
1868
      printer->Print(
 
1869
          "}\n");
 
1870
    }
 
1871
    printer->Print(
 
1872
        "case $cap_oneof_name$_NOT_SET: {\n"
 
1873
        "  break;\n"
 
1874
        "}\n",
 
1875
        "cap_oneof_name",
 
1876
        ToUpper(descriptor_->oneof_decl(i)->name()));
 
1877
    printer->Outdent();
 
1878
    printer->Print(
 
1879
        "}\n");
 
1880
  }
 
1881
 
1355
1882
  // Merge Optional and Required fields (after a _has_bit check).
1356
1883
  int last_index = -1;
1357
1884
 
1358
1885
  for (int i = 0; i < descriptor_->field_count(); ++i) {
1359
1886
    const FieldDescriptor* field = descriptor_->field(i);
1360
1887
 
1361
 
    if (!field->is_repeated()) {
 
1888
    if (!field->is_repeated() && !field->containing_oneof()) {
1362
1889
      // See above in GenerateClear for an explanation of this.
1363
1890
      if (i / 8 != last_index / 8 || last_index < 0) {
1364
1891
        if (last_index >= 0) {
1394
1921
    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1395
1922
  }
1396
1923
 
1397
 
  if (HasUnknownFields(descriptor_->file())) {
 
1924
  if (UseUnknownFieldSet(descriptor_->file())) {
1398
1925
    printer->Print(
1399
1926
      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
 
1927
  } else {
 
1928
    printer->Print(
 
1929
      "mutable_unknown_fields()->append(from.unknown_fields());\n");
1400
1930
  }
1401
1931
 
1402
1932
  printer->Outdent();
1465
1995
  printer->Print(
1466
1996
    "bool $classname$::MergePartialFromCodedStream(\n"
1467
1997
    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1468
 
    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1469
 
    "  ::google::protobuf::uint32 tag;\n"
1470
 
    "  while ((tag = input->ReadTag()) != 0) {\n",
 
1998
    "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
 
1999
    "  ::google::protobuf::uint32 tag;\n",
1471
2000
    "classname", classname_);
1472
2001
 
1473
 
  printer->Indent();
1474
 
  printer->Indent();
1475
 
 
 
2002
  if (!UseUnknownFieldSet(descriptor_->file())) {
 
2003
    printer->Print(
 
2004
      "  ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
 
2005
      "      mutable_unknown_fields());\n"
 
2006
      "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
 
2007
      "      &unknown_fields_string);\n");
 
2008
  }
 
2009
 
 
2010
  printer->Print(
 
2011
    "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
 
2012
    "full_name", descriptor_->full_name());
 
2013
 
 
2014
  printer->Indent();
 
2015
  printer->Print("for (;;) {\n");
 
2016
  printer->Indent();
 
2017
 
 
2018
  scoped_array<const FieldDescriptor*> ordered_fields(
 
2019
      SortFieldsByNumber(descriptor_));
 
2020
  uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
 
2021
      WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
 
2022
  const int kCutoff0 = 127;               // fits in 1-byte varint
 
2023
  const int kCutoff1 = (127 << 7) + 127;  // fits in 2-byte varint
 
2024
  printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
 
2025
                 "input->ReadTagWithCutoff($max$);\n"
 
2026
                 "tag = p.first;\n"
 
2027
                 "if (!p.second) goto handle_unusual;\n",
 
2028
                 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
 
2029
                                   (maxtag <= kCutoff1 ? kCutoff1 :
 
2030
                                    maxtag)));
1476
2031
  if (descriptor_->field_count() > 0) {
1477
2032
    // We don't even want to print the switch() if we have no fields because
1478
2033
    // MSVC dislikes switch() statements that contain only a default value.
1482
2037
    // of each case.  However, this is actually a bit slower in practice as it
1483
2038
    // creates a jump table that is 8x larger and sparser, and meanwhile the
1484
2039
    // if()s are highly predictable.
1485
 
    printer->Print(
1486
 
      "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
 
2040
    printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
 
2041
                   "GetTagFieldNumber(tag)) {\n");
1487
2042
 
1488
2043
    printer->Indent();
1489
2044
 
1490
 
    scoped_array<const FieldDescriptor*> ordered_fields(
1491
 
      SortFieldsByNumber(descriptor_));
1492
 
 
1493
2045
    for (int i = 0; i < descriptor_->field_count(); i++) {
1494
2046
      const FieldDescriptor* field = ordered_fields[i];
1495
2047
 
1502
2054
      const FieldGenerator& field_generator = field_generators_.get(field);
1503
2055
 
1504
2056
      // Emit code to parse the common, expected case.
1505
 
      printer->Print(
1506
 
        "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1507
 
        "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1508
 
        "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
 
2057
      printer->Print("if (tag == $commontag$) {\n",
 
2058
                     "commontag", SimpleItoa(WireFormat::MakeTag(field)));
1509
2059
 
1510
2060
      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1511
2061
        printer->Print(
1523
2073
 
1524
2074
      // Emit code to parse unexpectedly packed or unpacked values.
1525
2075
      if (field->is_packable() && field->options().packed()) {
1526
 
        printer->Print(
1527
 
          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1528
 
          "           == ::google::protobuf::internal::WireFormatLite::\n"
1529
 
          "              WIRETYPE_$wiretype$) {\n",
1530
 
          "wiretype",
1531
 
          kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
 
2076
        internal::WireFormatLite::WireType wiretype =
 
2077
            WireFormat::WireTypeForFieldType(field->type());
 
2078
        printer->Print("} else if (tag == $uncommontag$) {\n",
 
2079
                       "uncommontag", SimpleItoa(
 
2080
                           internal::WireFormatLite::MakeTag(
 
2081
                               field->number(), wiretype)));
1532
2082
        printer->Indent();
1533
2083
        field_generator.GenerateMergeFromCodedStream(printer);
1534
2084
        printer->Outdent();
1535
2085
      } else if (field->is_packable() && !field->options().packed()) {
1536
 
        printer->Print(
1537
 
          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1538
 
          "           == ::google::protobuf::internal::WireFormatLite::\n"
1539
 
          "              WIRETYPE_LENGTH_DELIMITED) {\n");
 
2086
        internal::WireFormatLite::WireType wiretype =
 
2087
            internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
 
2088
        printer->Print("} else if (tag == $uncommontag$) {\n",
 
2089
                       "uncommontag", SimpleItoa(
 
2090
                           internal::WireFormatLite::MakeTag(
 
2091
                               field->number(), wiretype)));
1540
2092
        printer->Indent();
1541
2093
        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1542
2094
        printer->Outdent();
1544
2096
 
1545
2097
      printer->Print(
1546
2098
        "} else {\n"
1547
 
        "  goto handle_uninterpreted;\n"
 
2099
        "  goto handle_unusual;\n"
1548
2100
        "}\n");
1549
2101
 
1550
2102
      // switch() is slow since it can't be predicted well.  Insert some if()s
1568
2120
        // Expect EOF.
1569
2121
        // TODO(kenton):  Expect group end-tag?
1570
2122
        printer->Print(
1571
 
          "if (input->ExpectAtEnd()) return true;\n");
 
2123
          "if (input->ExpectAtEnd()) goto success;\n");
1572
2124
      }
1573
2125
 
1574
2126
      printer->Print(
1578
2130
      printer->Print("}\n\n");
1579
2131
    }
1580
2132
 
1581
 
    printer->Print(
1582
 
      "default: {\n"
1583
 
      "handle_uninterpreted:\n");
 
2133
    printer->Print("default: {\n");
1584
2134
    printer->Indent();
1585
2135
  }
1586
2136
 
1587
 
  // Is this an end-group tag?  If so, this must be the end of the message.
 
2137
  printer->Outdent();
 
2138
  printer->Print("handle_unusual:\n");
 
2139
  printer->Indent();
 
2140
  // If tag is 0 or an end-group tag then this must be the end of the message.
1588
2141
  printer->Print(
1589
 
    "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
 
2142
    "if (tag == 0 ||\n"
 
2143
    "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1590
2144
    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1591
 
    "  return true;\n"
 
2145
    "  goto success;\n"
1592
2146
    "}\n");
1593
2147
 
1594
2148
  // Handle extension ranges.
1617
2171
      }
1618
2172
    }
1619
2173
    printer->Print(") {\n");
1620
 
    if (HasUnknownFields(descriptor_->file())) {
 
2174
    if (UseUnknownFieldSet(descriptor_->file())) {
1621
2175
      PrintHandlingOptionalStaticInitializers(
1622
2176
        descriptor_->file(), printer,
1623
2177
        // With static initializers.
1630
2184
      PrintHandlingOptionalStaticInitializers(
1631
2185
        descriptor_->file(), printer,
1632
2186
        // With static initializers.
1633
 
        "  DO_(_extensions_.ParseField(tag, input, default_instance_));\n",
 
2187
        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
 
2188
        "                              &unknown_fields_stream));\n",
1634
2189
        // Without.
1635
 
        "  DO_(_extensions_.ParseField(tag, input, &default_instance()));\n");
 
2190
        "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
 
2191
        "                              &unknown_fields_stream));\n");
1636
2192
    }
1637
2193
    printer->Print(
1638
2194
      "  continue;\n"
1640
2196
  }
1641
2197
 
1642
2198
  // We really don't recognize this tag.  Skip it.
1643
 
  if (HasUnknownFields(descriptor_->file())) {
 
2199
  if (UseUnknownFieldSet(descriptor_->file())) {
1644
2200
    printer->Print(
1645
2201
      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1646
2202
      "      input, tag, mutable_unknown_fields()));\n");
1647
2203
  } else {
1648
2204
    printer->Print(
1649
 
      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
 
2205
      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
 
2206
      "    input, tag, &unknown_fields_stream));\n");
1650
2207
  }
1651
2208
 
1652
2209
  if (descriptor_->field_count() > 0) {
1660
2217
  printer->Outdent();
1661
2218
  printer->Outdent();
1662
2219
  printer->Print(
1663
 
    "  }\n"                   // while
 
2220
    "  }\n"                   // for (;;)
 
2221
    "success:\n"
 
2222
    "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
1664
2223
    "  return true;\n"
 
2224
    "failure:\n"
 
2225
    "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
 
2226
    "  return false;\n"
1665
2227
    "#undef DO_\n"
1666
 
    "}\n");
 
2228
    "}\n", "full_name", descriptor_->full_name());
1667
2229
}
1668
2230
 
1669
2231
void MessageGenerator::GenerateSerializeOneField(
1719
2281
      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
1720
2282
      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
1721
2283
      "classname", classname_);
1722
 
    if (HasUnknownFields(descriptor_->file())) {
1723
 
      printer->Print(
1724
 
        "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
1725
 
        "      unknown_fields(), output);\n");
1726
 
    }
 
2284
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
 
2285
    printer->Print(
 
2286
      "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
 
2287
      "      unknown_fields(), output);\n");
1727
2288
    printer->Print(
1728
2289
      "}\n");
1729
2290
    return;
1735
2296
    "classname", classname_);
1736
2297
  printer->Indent();
1737
2298
 
 
2299
  printer->Print(
 
2300
    "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
 
2301
    "full_name", descriptor_->full_name());
 
2302
 
1738
2303
  GenerateSerializeWithCachedSizesBody(printer, false);
1739
2304
 
 
2305
  printer->Print(
 
2306
    "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
 
2307
    "full_name", descriptor_->full_name());
 
2308
 
1740
2309
  printer->Outdent();
1741
2310
  printer->Print(
1742
2311
    "}\n");
1752
2321
      "  target =\n"
1753
2322
      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
1754
2323
      "classname", classname_);
1755
 
    if (HasUnknownFields(descriptor_->file())) {
1756
 
      printer->Print(
1757
 
        "  target = ::google::protobuf::internal::WireFormat::\n"
1758
 
        "             SerializeUnknownMessageSetItemsToArray(\n"
1759
 
        "               unknown_fields(), target);\n");
1760
 
    }
 
2324
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
 
2325
    printer->Print(
 
2326
      "  target = ::google::protobuf::internal::WireFormat::\n"
 
2327
      "             SerializeUnknownMessageSetItemsToArray(\n"
 
2328
      "               unknown_fields(), target);\n");
1761
2329
    printer->Print(
1762
2330
      "  return target;\n"
1763
2331
      "}\n");
1770
2338
    "classname", classname_);
1771
2339
  printer->Indent();
1772
2340
 
 
2341
  printer->Print(
 
2342
    "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
 
2343
    "full_name", descriptor_->full_name());
 
2344
 
1773
2345
  GenerateSerializeWithCachedSizesBody(printer, true);
1774
2346
 
 
2347
  printer->Print(
 
2348
    "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
 
2349
    "full_name", descriptor_->full_name());
 
2350
 
1775
2351
  printer->Outdent();
1776
2352
  printer->Print(
1777
2353
    "  return target;\n"
1781
2357
void MessageGenerator::
1782
2358
GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
1783
2359
  scoped_array<const FieldDescriptor*> ordered_fields(
1784
 
    SortFieldsByNumber(descriptor_));
 
2360
      SortFieldsByNumber(descriptor_));
1785
2361
 
1786
2362
  vector<const Descriptor::ExtensionRange*> sorted_extensions;
1787
2363
  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
1810
2386
    }
1811
2387
  }
1812
2388
 
1813
 
  if (HasUnknownFields(descriptor_->file())) {
 
2389
  if (UseUnknownFieldSet(descriptor_->file())) {
1814
2390
    printer->Print("if (!unknown_fields().empty()) {\n");
1815
2391
    printer->Indent();
1816
2392
    if (to_array) {
1827
2403
 
1828
2404
    printer->Print(
1829
2405
      "}\n");
 
2406
  } else {
 
2407
    printer->Print(
 
2408
      "output->WriteRaw(unknown_fields().data(),\n"
 
2409
      "                 unknown_fields().size());\n");
1830
2410
  }
1831
2411
}
1832
2412
 
1838
2418
      "int $classname$::ByteSize() const {\n"
1839
2419
      "  int total_size = _extensions_.MessageSetByteSize();\n",
1840
2420
      "classname", classname_);
1841
 
    if (HasUnknownFields(descriptor_->file())) {
1842
 
      printer->Print(
1843
 
        "  total_size += ::google::protobuf::internal::WireFormat::\n"
1844
 
        "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1845
 
    }
 
2421
    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
 
2422
    printer->Print(
 
2423
      "  total_size += ::google::protobuf::internal::WireFormat::\n"
 
2424
      "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1846
2425
    printer->Print(
1847
2426
      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1848
2427
      "  _cached_size_ = total_size;\n"
1865
2444
  for (int i = 0; i < descriptor_->field_count(); i++) {
1866
2445
    const FieldDescriptor* field = descriptor_->field(i);
1867
2446
 
1868
 
    if (!field->is_repeated()) {
 
2447
    if (!field->is_repeated() && !field->containing_oneof()) {
1869
2448
      // See above in GenerateClear for an explanation of this.
1870
2449
      // TODO(kenton):  Share code?  Unclear how to do so without
1871
2450
      //   over-engineering.
1915
2494
    }
1916
2495
  }
1917
2496
 
 
2497
  // Fields inside a oneof don't use _has_bits_ so we count them in a separate
 
2498
  // pass.
 
2499
  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
 
2500
    printer->Print(
 
2501
        "switch ($oneofname$_case()) {\n",
 
2502
        "oneofname", descriptor_->oneof_decl(i)->name());
 
2503
    printer->Indent();
 
2504
    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
 
2505
      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
 
2506
      PrintFieldComment(printer, field);
 
2507
      printer->Print(
 
2508
          "case k$field_name$: {\n",
 
2509
          "field_name", UnderscoresToCamelCase(field->name(), true));
 
2510
      printer->Indent();
 
2511
      field_generators_.get(field).GenerateByteSize(printer);
 
2512
      printer->Print(
 
2513
          "break;\n");
 
2514
      printer->Outdent();
 
2515
      printer->Print(
 
2516
          "}\n");
 
2517
    }
 
2518
    printer->Print(
 
2519
        "case $cap_oneof_name$_NOT_SET: {\n"
 
2520
        "  break;\n"
 
2521
        "}\n",
 
2522
        "cap_oneof_name",
 
2523
        ToUpper(descriptor_->oneof_decl(i)->name()));
 
2524
    printer->Outdent();
 
2525
    printer->Print(
 
2526
        "}\n");
 
2527
  }
 
2528
 
1918
2529
  if (descriptor_->extension_range_count() > 0) {
1919
2530
    printer->Print(
1920
2531
      "total_size += _extensions_.ByteSize();\n"
1921
2532
      "\n");
1922
2533
  }
1923
2534
 
1924
 
  if (HasUnknownFields(descriptor_->file())) {
 
2535
  if (UseUnknownFieldSet(descriptor_->file())) {
1925
2536
    printer->Print("if (!unknown_fields().empty()) {\n");
1926
2537
    printer->Indent();
1927
2538
    printer->Print(
1930
2541
      "    unknown_fields());\n");
1931
2542
    printer->Outdent();
1932
2543
    printer->Print("}\n");
 
2544
  } else {
 
2545
    printer->Print(
 
2546
      "total_size += unknown_fields().size();\n"
 
2547
      "\n");
1933
2548
  }
1934
2549
 
1935
2550
  // We update _cached_size_ even though this is a const method.  In theory,
1987
2602
        HasRequiredFields(field->message_type())) {
1988
2603
      if (field->is_repeated()) {
1989
2604
        printer->Print(
1990
 
          "for (int i = 0; i < $name$_size(); i++) {\n"
1991
 
          "  if (!this->$name$(i).IsInitialized()) return false;\n"
1992
 
          "}\n",
 
2605
          "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
 
2606
          " return false;\n",
1993
2607
          "name", FieldName(field));
1994
2608
      } else {
1995
 
        printer->Print(
1996
 
          "if (has_$name$()) {\n"
1997
 
          "  if (!this->$name$().IsInitialized()) return false;\n"
1998
 
          "}\n",
1999
 
          "name", FieldName(field));
 
2609
        if (field->options().weak()) {
 
2610
          // For weak fields, use the data member (google::protobuf::Message*) instead
 
2611
          // of the getter to avoid a link dependency on the weak message type
 
2612
          // which is only forward declared.
 
2613
          printer->Print(
 
2614
            "if (has_$name$()) {\n"
 
2615
            "  if (!this->$name$_->IsInitialized()) return false;\n"
 
2616
            "}\n",
 
2617
            "name", FieldName(field));
 
2618
        } else {
 
2619
          printer->Print(
 
2620
            "if (has_$name$()) {\n"
 
2621
            "  if (!this->$name$().IsInitialized()) return false;\n"
 
2622
            "}\n",
 
2623
            "name", FieldName(field));
 
2624
        }
2000
2625
      }
2001
2626
    }
2002
2627
  }