~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2010-02-11 11:13:19 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100211111319-zdn8hmw0gh8s4cf8
Tags: 2.2.0a-0.1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Don't use python2.4.
* Ubuntu changes dropped:
  - Disable death tests on Itanium, fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
#include <algorithm>
36
36
#include <google/protobuf/stubs/hash.h>
 
37
#include <map>
 
38
#include <vector>
37
39
#include <google/protobuf/compiler/cpp/cpp_message.h>
 
40
#include <google/protobuf/compiler/cpp/cpp_field.h>
38
41
#include <google/protobuf/compiler/cpp/cpp_enum.h>
39
42
#include <google/protobuf/compiler/cpp/cpp_extension.h>
40
43
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
41
44
#include <google/protobuf/stubs/strutil.h>
42
45
#include <google/protobuf/io/printer.h>
43
46
#include <google/protobuf/io/coded_stream.h>
44
 
#include <google/protobuf/wire_format_inl.h>
 
47
#include <google/protobuf/wire_format.h>
45
48
#include <google/protobuf/descriptor.pb.h>
46
49
 
47
50
namespace google {
50
53
namespace cpp {
51
54
 
52
55
using internal::WireFormat;
 
56
using internal::WireFormatLite;
53
57
 
54
58
namespace {
55
59
 
196
200
}
197
201
 
198
202
void MessageGenerator::
 
203
GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
 
204
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 
205
    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
 
206
  }
 
207
  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
 
208
    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
 
209
  }
 
210
}
 
211
 
 
212
void MessageGenerator::
199
213
GenerateFieldAccessorDeclarations(io::Printer* printer) {
200
214
  for (int i = 0; i < descriptor_->field_count(); i++) {
201
215
    const FieldDescriptor* field = descriptor_->field(i);
203
217
    PrintFieldComment(printer, field);
204
218
 
205
219
    map<string, string> vars;
206
 
    vars["name"] = FieldName(field);
 
220
    SetCommonFieldVariables(field, &vars);
207
221
    vars["constant_name"] = FieldConstantName(field);
208
 
    vars["number"] = SimpleItoa(field->number());
209
222
 
210
223
    if (field->is_repeated()) {
211
 
      printer->Print(vars, "inline int $name$_size() const;\n");
 
224
      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
212
225
    } else {
213
 
      printer->Print(vars, "inline bool has_$name$() const;\n");
 
226
      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
214
227
    }
215
228
 
216
 
    printer->Print(vars, "inline void clear_$name$();\n");
 
229
    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
217
230
    printer->Print(vars, "static const int $constant_name$ = $number$;\n");
218
231
 
219
232
    // Generate type-specific accessor declarations.
241
254
    PrintFieldComment(printer, field);
242
255
 
243
256
    map<string, string> vars;
244
 
    vars["name"] = FieldName(field);
245
 
    vars["index"] = SimpleItoa(field->index());
246
 
    vars["classname"] = classname_;
 
257
    SetCommonFieldVariables(field, &vars);
247
258
 
248
259
    // Generate has_$name$() or $name$_size().
249
260
    if (field->is_repeated()) {
297
308
  } else {
298
309
    vars["dllexport"] = dllexport_decl_ + " ";
299
310
  }
 
311
  vars["superclass"] = HasDescriptorMethods(descriptor_->file()) ?
 
312
                       "Message" : "MessageLite";
300
313
 
301
314
  printer->Print(vars,
302
 
    "class $dllexport$$classname$ : public ::google::protobuf::Message {\n"
 
315
    "class $dllexport$$classname$ : public ::google::protobuf::$superclass$ {\n"
303
316
    " public:\n");
304
317
  printer->Indent();
305
318
 
313
326
    "  CopyFrom(from);\n"
314
327
    "  return *this;\n"
315
328
    "}\n"
316
 
    "\n"
317
 
    "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
318
 
    "  return _unknown_fields_;\n"
319
 
    "}\n"
320
 
    "\n"
321
 
    "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
322
 
    "  return &_unknown_fields_;\n"
323
 
    "}\n"
324
 
    "\n"
325
 
    "static const ::google::protobuf::Descriptor* descriptor();\n"
 
329
    "\n");
 
330
 
 
331
  if (HasUnknownFields(descriptor_->file())) {
 
332
    printer->Print(
 
333
      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
 
334
      "  return _unknown_fields_;\n"
 
335
      "}\n"
 
336
      "\n"
 
337
      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
 
338
      "  return &_unknown_fields_;\n"
 
339
      "}\n"
 
340
      "\n");
 
341
  }
 
342
 
 
343
  // Only generate this member if it's not disabled.
 
344
  if (HasDescriptorMethods(descriptor_->file()) &&
 
345
      !descriptor_->options().no_standard_descriptor_accessor()) {
 
346
    printer->Print(vars,
 
347
      "static const ::google::protobuf::Descriptor* descriptor();\n");
 
348
  }
 
349
 
 
350
  printer->Print(vars,
326
351
    "static const $classname$& default_instance();\n"
327
352
    "void Swap($classname$* other);\n"
328
353
    "\n"
330
355
    "\n"
331
356
    "$classname$* New() const;\n");
332
357
 
333
 
  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
 
358
  if (HasGeneratedMethods(descriptor_->file())) {
 
359
    if (HasDescriptorMethods(descriptor_->file())) {
 
360
      printer->Print(vars,
 
361
        "void CopyFrom(const ::google::protobuf::Message& from);\n"
 
362
        "void MergeFrom(const ::google::protobuf::Message& from);\n");
 
363
    } else {
 
364
      printer->Print(vars,
 
365
        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
 
366
    }
 
367
 
334
368
    printer->Print(vars,
335
 
      "void CopyFrom(const ::google::protobuf::Message& from);\n"
336
 
      "void MergeFrom(const ::google::protobuf::Message& from);\n"
337
369
      "void CopyFrom(const $classname$& from);\n"
338
370
      "void MergeFrom(const $classname$& from);\n"
339
371
      "void Clear();\n"
340
 
      "bool IsInitialized() const;\n");
341
 
 
342
 
    if (!descriptor_->options().message_set_wire_format()) {
343
 
      // For message_set_wire_format, we don't generate parsing or
344
 
      // serialization code even if optimize_for = SPEED, since MessageSet
345
 
      // encoding is somewhat more complicated than normal extension encoding
346
 
      // and we'd like to avoid having to implement it in multiple places.
347
 
      // WireFormat's implementation is probably good enough.
348
 
      printer->Print(vars,
349
 
        "\n"
350
 
        "int ByteSize() const;\n"
351
 
        "bool MergePartialFromCodedStream(\n"
352
 
        "    ::google::protobuf::io::CodedInputStream* input);\n"
353
 
        "void SerializeWithCachedSizes(\n"
354
 
        "    ::google::protobuf::io::CodedOutputStream* output) const;\n"
 
372
      "bool IsInitialized() const;\n"
 
373
      "\n"
 
374
      "int ByteSize() const;\n"
 
375
      "bool MergePartialFromCodedStream(\n"
 
376
      "    ::google::protobuf::io::CodedInputStream* input);\n"
 
377
      "void SerializeWithCachedSizes(\n"
 
378
      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
 
379
    if (HasFastArraySerialization(descriptor_->file())) {
 
380
      printer->Print(
355
381
        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
356
382
    }
357
383
  }
363
389
    "void SharedDtor();\n"
364
390
    "void SetCachedSize(int size) const { _cached_size_ = size; }\n"
365
391
    "public:\n"
366
 
    "\n"
367
 
    "const ::google::protobuf::Descriptor* GetDescriptor() const;\n"
368
 
    "const ::google::protobuf::Reflection* GetReflection() const;\n"
369
 
    "\n"
 
392
    "\n");
 
393
 
 
394
  if (HasDescriptorMethods(descriptor_->file())) {
 
395
    printer->Print(
 
396
      "::google::protobuf::Metadata GetMetadata() const;\n"
 
397
      "\n");
 
398
  } else {
 
399
    printer->Print(
 
400
      "::std::string GetTypeName() const;\n"
 
401
      "\n");
 
402
  }
 
403
 
 
404
  printer->Print(
370
405
    "// nested types ----------------------------------------------------\n"
371
406
    "\n");
372
407
 
411
446
      "::google::protobuf::internal::ExtensionSet _extensions_;\n");
412
447
  }
413
448
 
 
449
  if (HasUnknownFields(descriptor_->file())) {
 
450
    printer->Print(
 
451
      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
 
452
  }
 
453
 
414
454
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
415
455
  printer->Print(
416
 
    "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
417
456
    "mutable int _cached_size_;\n"
418
457
    "\n");
419
458
  for (int i = 0; i < descriptor_->field_count(); i++) {
431
470
      GlobalAddDescriptorsName(descriptor_->file()->name()));
432
471
  printer->Print(
433
472
    "friend void $assigndescriptorsname$();\n"
434
 
    "friend void $shutdownfilename$();\n",
 
473
    "friend void $shutdownfilename$();\n"
 
474
    "\n",
435
475
    "assigndescriptorsname",
436
476
      GlobalAssignDescriptorsName(descriptor_->file()->name()),
437
477
    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
605
645
void MessageGenerator::
606
646
GenerateShutdownCode(io::Printer* printer) {
607
647
  printer->Print(
608
 
    "delete $classname$::default_instance_;\n"
609
 
    "delete $classname$_reflection_;\n",
 
648
    "delete $classname$::default_instance_;\n",
610
649
    "classname", classname_);
611
650
 
 
651
  if (HasDescriptorMethods(descriptor_->file())) {
 
652
    printer->Print(
 
653
      "delete $classname$_reflection_;\n",
 
654
      "classname", classname_);
 
655
  }
 
656
 
612
657
  // Handle nested types.
613
658
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
614
659
    nested_generators_[i]->GenerateShutdownCode(printer);
655
700
  GenerateStructors(printer);
656
701
  printer->Print("\n");
657
702
 
658
 
  if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
 
703
  if (HasGeneratedMethods(descriptor_->file())) {
659
704
    GenerateClear(printer);
660
705
    printer->Print("\n");
661
706
 
662
 
    if (!descriptor_->options().message_set_wire_format()) {
663
 
      // For message_set_wire_format, we don't generate parsing or
664
 
      // serialization code even if optimize_for = SPEED, since MessageSet
665
 
      // encoding is somewhat more complicated than normal extension encoding
666
 
      // and we'd like to avoid having to implement it in multiple places.
667
 
      // WireFormat's implementation is probably good enough.
668
 
      GenerateMergeFromCodedStream(printer);
669
 
      printer->Print("\n");
670
 
 
671
 
      GenerateSerializeWithCachedSizes(printer);
672
 
      printer->Print("\n");
673
 
 
 
707
    GenerateMergeFromCodedStream(printer);
 
708
    printer->Print("\n");
 
709
 
 
710
    GenerateSerializeWithCachedSizes(printer);
 
711
    printer->Print("\n");
 
712
 
 
713
    if (HasFastArraySerialization(descriptor_->file())) {
674
714
      GenerateSerializeWithCachedSizesToArray(printer);
675
715
      printer->Print("\n");
676
 
 
677
 
      GenerateByteSize(printer);
678
 
      printer->Print("\n");
679
716
    }
680
717
 
 
718
    GenerateByteSize(printer);
 
719
    printer->Print("\n");
 
720
 
681
721
    GenerateMergeFrom(printer);
682
722
    printer->Print("\n");
683
723
 
684
724
    GenerateCopyFrom(printer);
685
725
    printer->Print("\n");
686
726
 
687
 
    GenerateSwap(printer);
688
 
    printer->Print("\n");
689
 
 
690
727
    GenerateIsInitialized(printer);
691
728
    printer->Print("\n");
692
729
  }
693
730
 
694
 
  printer->Print(
695
 
    "const ::google::protobuf::Descriptor* $classname$::GetDescriptor() const {\n"
696
 
    "  return descriptor();\n"
697
 
    "}\n"
698
 
    "\n"
699
 
    "const ::google::protobuf::Reflection* $classname$::GetReflection() const {\n"
700
 
    "  protobuf_AssignDescriptorsOnce();\n"
701
 
    "  return $classname$_reflection_;\n"
702
 
    "}\n",
703
 
    "classname", classname_);
 
731
  GenerateSwap(printer);
 
732
  printer->Print("\n");
 
733
 
 
734
  if (HasDescriptorMethods(descriptor_->file())) {
 
735
    printer->Print(
 
736
      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
 
737
      "  protobuf_AssignDescriptorsOnce();\n"
 
738
      "  ::google::protobuf::Metadata metadata;\n"
 
739
      "  metadata.descriptor = $classname$_descriptor_;\n"
 
740
      "  metadata.reflection = $classname$_reflection_;\n"
 
741
      "  return metadata;\n"
 
742
      "}\n"
 
743
      "\n",
 
744
      "classname", classname_);
 
745
  } else {
 
746
    printer->Print(
 
747
      "::std::string $classname$::GetTypeName() const {\n"
 
748
      "  return \"$type_name$\";\n"
 
749
      "}\n"
 
750
      "\n",
 
751
      "classname", classname_,
 
752
      "type_name", descriptor_->full_name());
 
753
  }
704
754
}
705
755
 
706
756
void MessageGenerator::
724
774
}
725
775
 
726
776
void MessageGenerator::
727
 
GenerateInitializerList(io::Printer* printer) {
728
 
  printer->Indent();
729
 
  printer->Indent();
730
 
 
731
 
  printer->Print(
732
 
    "::google::protobuf::Message()");
733
 
 
734
 
  printer->Outdent();
735
 
  printer->Outdent();
736
 
}
737
 
 
738
 
void MessageGenerator::
739
777
GenerateSharedConstructorCode(io::Printer* printer) {
740
778
  printer->Print(
741
779
    "void $classname$::SharedCtor() {\n",
797
835
GenerateStructors(io::Printer* printer) {
798
836
  // Generate the default constructor.
799
837
  printer->Print(
800
 
      "$classname$::$classname$()\n"
801
 
      "  : ",
802
 
      "classname", classname_);
803
 
  GenerateInitializerList(printer);
804
 
  printer->Print(" {\n"
 
838
    "$classname$::$classname$() {\n"
805
839
    "  SharedCtor();\n"
806
 
    "}\n");
 
840
    "}\n",
 
841
    "classname", classname_);
807
842
 
808
843
  printer->Print(
809
844
    "\n"
810
 
    "void $classname$::InitAsDefaultInstance() {",
 
845
    "void $classname$::InitAsDefaultInstance() {\n",
811
846
    "classname", classname_);
812
847
 
813
848
  // The default instance needs all of its embedded message pointers
833
868
 
834
869
  // Generate the copy constructor.
835
870
  printer->Print(
836
 
      "$classname$::$classname$(const $classname$& from)\n"
837
 
      "  : ",
838
 
      "classname", classname_);
839
 
  GenerateInitializerList(printer);
840
 
  printer->Print(" {\n"
 
871
    "$classname$::$classname$(const $classname$& from) {\n"
841
872
    "  SharedCtor();\n"
842
873
    "  MergeFrom(from);\n"
843
874
    "}\n"
844
 
    "\n");
 
875
    "\n",
 
876
    "classname", classname_);
845
877
 
846
878
  // Generate the shared constructor code.
847
879
  GenerateSharedConstructorCode(printer);
857
889
  // Generate the shared destructor code.
858
890
  GenerateSharedDestructorCode(printer);
859
891
 
 
892
  // Only generate this member if it's not disabled.
 
893
  if (HasDescriptorMethods(descriptor_->file()) &&
 
894
      !descriptor_->options().no_standard_descriptor_accessor()) {
 
895
    printer->Print(
 
896
      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
 
897
      "  protobuf_AssignDescriptorsOnce();\n"
 
898
      "  return $classname$_descriptor_;\n"
 
899
      "}\n"
 
900
      "\n",
 
901
      "classname", classname_,
 
902
      "adddescriptorsname",
 
903
      GlobalAddDescriptorsName(descriptor_->file()->name()));
 
904
  }
 
905
 
860
906
  printer->Print(
861
 
    "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
862
 
    "  protobuf_AssignDescriptorsOnce();\n"
863
 
    "  return $classname$_descriptor_;\n"
864
 
    "}\n"
865
 
    "\n"
866
907
    "const $classname$& $classname$::default_instance() {\n"
867
908
    "  if (default_instance_ == NULL) $adddescriptorsname$();"
868
909
    "  return *default_instance_;\n"
951
992
  }
952
993
 
953
994
  printer->Print(
954
 
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
955
 
    "mutable_unknown_fields()->Clear();\n");
 
995
    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
 
996
 
 
997
  if (HasUnknownFields(descriptor_->file())) {
 
998
    printer->Print(
 
999
      "mutable_unknown_fields()->Clear();\n");
 
1000
  }
956
1001
 
957
1002
  printer->Outdent();
958
1003
  printer->Print("}\n");
967
1012
  printer->Print("if (other != this) {\n");
968
1013
  printer->Indent();
969
1014
 
970
 
  for (int i = 0; i < descriptor_->field_count(); i++) {
971
 
    const FieldDescriptor* field = descriptor_->field(i);
972
 
    field_generators_.get(field).GenerateSwappingCode(printer);
973
 
  }
974
 
 
975
 
  for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
976
 
    printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
977
 
                   "i", SimpleItoa(i));
978
 
  }
979
 
 
980
 
  printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
981
 
  printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
982
 
  if (descriptor_->extension_range_count() > 0) {
983
 
    printer->Print("_extensions_.Swap(&other->_extensions_);\n");
 
1015
  if (HasGeneratedMethods(descriptor_->file())) {
 
1016
    for (int i = 0; i < descriptor_->field_count(); i++) {
 
1017
      const FieldDescriptor* field = descriptor_->field(i);
 
1018
      field_generators_.get(field).GenerateSwappingCode(printer);
 
1019
    }
 
1020
 
 
1021
    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
 
1022
      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
 
1023
                     "i", SimpleItoa(i));
 
1024
    }
 
1025
 
 
1026
    if (HasUnknownFields(descriptor_->file())) {
 
1027
      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
 
1028
    }
 
1029
    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
 
1030
    if (descriptor_->extension_range_count() > 0) {
 
1031
      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
 
1032
    }
 
1033
  } else {
 
1034
    printer->Print("GetReflection()->Swap(this, other);");
984
1035
  }
985
1036
 
986
1037
  printer->Outdent();
991
1042
 
992
1043
void MessageGenerator::
993
1044
GenerateMergeFrom(io::Printer* printer) {
994
 
  // Generate the generalized MergeFrom (aka that which takes in the Message
995
 
  // base class as a parameter).
996
 
  printer->Print(
997
 
    "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
998
 
    "  GOOGLE_CHECK_NE(&from, this);\n",
999
 
    "classname", classname_);
1000
 
  printer->Indent();
1001
 
 
1002
 
  // Cast the message to the proper type. If we find that the message is
1003
 
  // *not* of the proper type, we can still call Merge via the reflection
1004
 
  // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1005
 
  // for each message.
1006
 
  printer->Print(
1007
 
    "const $classname$* source =\n"
1008
 
    "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1009
 
    "    &from);\n"
1010
 
    "if (source == NULL) {\n"
1011
 
    "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1012
 
    "} else {\n"
1013
 
    "  MergeFrom(*source);\n"
1014
 
    "}\n",
1015
 
    "classname", classname_);
1016
 
 
1017
 
  printer->Outdent();
1018
 
  printer->Print("}\n\n");
 
1045
  if (HasDescriptorMethods(descriptor_->file())) {
 
1046
    // Generate the generalized MergeFrom (aka that which takes in the Message
 
1047
    // base class as a parameter).
 
1048
    printer->Print(
 
1049
      "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
 
1050
      "  GOOGLE_CHECK_NE(&from, this);\n",
 
1051
      "classname", classname_);
 
1052
    printer->Indent();
 
1053
 
 
1054
    // Cast the message to the proper type. If we find that the message is
 
1055
    // *not* of the proper type, we can still call Merge via the reflection
 
1056
    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
 
1057
    // for each message.
 
1058
    printer->Print(
 
1059
      "const $classname$* source =\n"
 
1060
      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
 
1061
      "    &from);\n"
 
1062
      "if (source == NULL) {\n"
 
1063
      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
 
1064
      "} else {\n"
 
1065
      "  MergeFrom(*source);\n"
 
1066
      "}\n",
 
1067
      "classname", classname_);
 
1068
 
 
1069
    printer->Outdent();
 
1070
    printer->Print("}\n\n");
 
1071
  } else {
 
1072
    // Generate CheckTypeAndMergeFrom().
 
1073
    printer->Print(
 
1074
      "void $classname$::CheckTypeAndMergeFrom(\n"
 
1075
      "    const ::google::protobuf::MessageLite& from) {\n"
 
1076
      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
 
1077
      "}\n"
 
1078
      "\n",
 
1079
      "classname", classname_);
 
1080
  }
1019
1081
 
1020
1082
  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1021
1083
  printer->Print(
1077
1139
    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1078
1140
  }
1079
1141
 
1080
 
  printer->Print(
1081
 
    "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
 
1142
  if (HasUnknownFields(descriptor_->file())) {
 
1143
    printer->Print(
 
1144
      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
 
1145
  }
1082
1146
 
1083
1147
  printer->Outdent();
1084
1148
  printer->Print("}\n");
1086
1150
 
1087
1151
void MessageGenerator::
1088
1152
GenerateCopyFrom(io::Printer* printer) {
1089
 
  // Generate the generalized CopyFrom (aka that which takes in the Message
1090
 
  // base class as a parameter).
1091
 
  printer->Print(
1092
 
    "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1093
 
    "classname", classname_);
1094
 
  printer->Indent();
1095
 
 
1096
 
  printer->Print(
1097
 
    "if (&from == this) return;\n"
1098
 
    "Clear();\n"
1099
 
    "MergeFrom(from);\n");
1100
 
 
1101
 
  printer->Outdent();
1102
 
  printer->Print("}\n\n");
 
1153
  if (HasDescriptorMethods(descriptor_->file())) {
 
1154
    // Generate the generalized CopyFrom (aka that which takes in the Message
 
1155
    // base class as a parameter).
 
1156
    printer->Print(
 
1157
      "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
 
1158
      "classname", classname_);
 
1159
    printer->Indent();
 
1160
 
 
1161
    printer->Print(
 
1162
      "if (&from == this) return;\n"
 
1163
      "Clear();\n"
 
1164
      "MergeFrom(from);\n");
 
1165
 
 
1166
    printer->Outdent();
 
1167
    printer->Print("}\n\n");
 
1168
  }
1103
1169
 
1104
1170
  // Generate the class-specific CopyFrom.
1105
1171
  printer->Print(
1118
1184
 
1119
1185
void MessageGenerator::
1120
1186
GenerateMergeFromCodedStream(io::Printer* printer) {
 
1187
  if (descriptor_->options().message_set_wire_format()) {
 
1188
    // Special-case MessageSet.
 
1189
    printer->Print(
 
1190
      "bool $classname$::MergePartialFromCodedStream(\n"
 
1191
      "    ::google::protobuf::io::CodedInputStream* input) {\n"
 
1192
      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
 
1193
      "                                      mutable_unknown_fields());\n"
 
1194
      "}\n",
 
1195
      "classname", classname_);
 
1196
    return;
 
1197
  }
 
1198
 
1121
1199
  printer->Print(
1122
1200
    "bool $classname$::MergePartialFromCodedStream(\n"
1123
1201
    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1139
1217
    // creates a jump table that is 8x larger and sparser, and meanwhile the
1140
1218
    // if()s are highly predictable.
1141
1219
    printer->Print(
1142
 
      "switch (::google::protobuf::internal::WireFormat::GetTagFieldNumber(tag)) {\n");
 
1220
      "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1143
1221
 
1144
1222
    printer->Indent();
1145
1223
 
1153
1231
 
1154
1232
      printer->Print(
1155
1233
        "case $number$: {\n"
1156
 
        "  if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) !=\n"
1157
 
        "      ::google::protobuf::internal::WireFormat::WIRETYPE_$wiretype$) {\n"
 
1234
        "  if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) !=\n"
 
1235
        "      ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n"
1158
1236
        "    goto handle_uninterpreted;\n"
1159
1237
        "  }\n",
1160
1238
        "number", SimpleItoa(field->number()),
1209
1287
 
1210
1288
  // Is this an end-group tag?  If so, this must be the end of the message.
1211
1289
  printer->Print(
1212
 
    "if (::google::protobuf::internal::WireFormat::GetTagWireType(tag) ==\n"
1213
 
    "    ::google::protobuf::internal::WireFormat::WIRETYPE_END_GROUP) {\n"
 
1290
    "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
 
1291
    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1214
1292
    "  return true;\n"
1215
1293
    "}\n");
1216
1294
 
1223
1301
        descriptor_->extension_range(i);
1224
1302
      if (i > 0) printer->Print(" ||\n    ");
1225
1303
 
1226
 
      uint32 start_tag = WireFormat::MakeTag(
1227
 
        range->start, static_cast<WireFormat::WireType>(0));
1228
 
      uint32 end_tag = WireFormat::MakeTag(
1229
 
        range->end, static_cast<WireFormat::WireType>(0));
 
1304
      uint32 start_tag = WireFormatLite::MakeTag(
 
1305
        range->start, static_cast<WireFormatLite::WireType>(0));
 
1306
      uint32 end_tag = WireFormatLite::MakeTag(
 
1307
        range->end, static_cast<WireFormatLite::WireType>(0));
1230
1308
 
1231
1309
      if (range->end > FieldDescriptor::kMaxNumber) {
1232
1310
        printer->Print(
1239
1317
          "end", SimpleItoa(end_tag));
1240
1318
      }
1241
1319
    }
1242
 
    printer->Print(") {\n"
1243
 
      "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
1244
 
      "                              mutable_unknown_fields()));\n"
 
1320
    printer->Print(") {\n");
 
1321
    if (HasUnknownFields(descriptor_->file())) {
 
1322
      printer->Print(
 
1323
        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
 
1324
        "                              mutable_unknown_fields()));\n");
 
1325
    } else {
 
1326
      printer->Print(
 
1327
        "  DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
 
1328
    }
 
1329
    printer->Print(
1245
1330
      "  continue;\n"
1246
1331
      "}\n");
1247
1332
  }
1248
1333
 
1249
1334
  // We really don't recognize this tag.  Skip it.
1250
 
  printer->Print(
1251
 
    "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1252
 
    "      input, tag, mutable_unknown_fields()));\n");
 
1335
  if (HasUnknownFields(descriptor_->file())) {
 
1336
    printer->Print(
 
1337
      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
 
1338
      "      input, tag, mutable_unknown_fields()));\n");
 
1339
  } else {
 
1340
    printer->Print(
 
1341
      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
 
1342
  }
1253
1343
 
1254
1344
  if (descriptor_->field_count() > 0) {
1255
1345
    printer->Print("break;\n");
1314
1404
 
1315
1405
void MessageGenerator::
1316
1406
GenerateSerializeWithCachedSizes(io::Printer* printer) {
 
1407
  if (descriptor_->options().message_set_wire_format()) {
 
1408
    // Special-case MessageSet.
 
1409
    printer->Print(
 
1410
      "void $classname$::SerializeWithCachedSizes(\n"
 
1411
      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
 
1412
      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
 
1413
      "classname", classname_);
 
1414
    if (HasUnknownFields(descriptor_->file())) {
 
1415
      printer->Print(
 
1416
        "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
 
1417
        "      unknown_fields(), output);\n");
 
1418
    }
 
1419
    printer->Print(
 
1420
      "}\n");
 
1421
    return;
 
1422
  }
 
1423
 
1317
1424
  printer->Print(
1318
1425
    "void $classname$::SerializeWithCachedSizes(\n"
1319
1426
    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
1320
1427
    "classname", classname_);
1321
1428
  printer->Indent();
1322
1429
 
1323
 
  printer->Print(
1324
 
    "::google::protobuf::uint8* raw_buffer = "
1325
 
      "output->GetDirectBufferForNBytesAndAdvance(_cached_size_);\n"
1326
 
    "if (raw_buffer != NULL) {\n"
1327
 
    "  $classname$::SerializeWithCachedSizesToArray(raw_buffer);\n"
1328
 
    "  return;\n"
1329
 
    "}\n"
1330
 
    "\n",
1331
 
    "classname", classname_);
 
1430
  if (HasFastArraySerialization(descriptor_->file())) {
 
1431
    printer->Print(
 
1432
      "::google::protobuf::uint8* raw_buffer = "
 
1433
        "output->GetDirectBufferForNBytesAndAdvance(_cached_size_);\n"
 
1434
      "if (raw_buffer != NULL) {\n"
 
1435
      "  $classname$::SerializeWithCachedSizesToArray(raw_buffer);\n"
 
1436
      "  return;\n"
 
1437
      "}\n"
 
1438
      "\n",
 
1439
      "classname", classname_);
 
1440
  }
 
1441
 
1332
1442
  GenerateSerializeWithCachedSizesBody(printer, false);
1333
1443
 
1334
1444
  printer->Outdent();
1338
1448
 
1339
1449
void MessageGenerator::
1340
1450
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
 
1451
  if (descriptor_->options().message_set_wire_format()) {
 
1452
    // Special-case MessageSet.
 
1453
    printer->Print(
 
1454
      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
 
1455
      "    ::google::protobuf::uint8* target) const {\n"
 
1456
      "  target =\n"
 
1457
      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
 
1458
      "classname", classname_);
 
1459
    if (HasUnknownFields(descriptor_->file())) {
 
1460
      printer->Print(
 
1461
        "  target = ::google::protobuf::internal::WireFormat::\n"
 
1462
        "             SerializeUnknownMessageSetItemsToArray(\n"
 
1463
        "               unknown_fields(), target);\n");
 
1464
    }
 
1465
    printer->Print(
 
1466
      "  return target;\n"
 
1467
      "}\n");
 
1468
    return;
 
1469
  }
 
1470
 
1341
1471
  printer->Print(
1342
1472
    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1343
1473
    "    ::google::protobuf::uint8* target) const {\n",
1384
1514
    }
1385
1515
  }
1386
1516
 
1387
 
  printer->Print("if (!unknown_fields().empty()) {\n");
1388
 
  printer->Indent();
1389
 
  if (to_array) {
1390
 
    printer->Print(
1391
 
      "target = "
1392
 
          "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
1393
 
      "    unknown_fields(), target);\n");
1394
 
  } else {
1395
 
    printer->Print(
1396
 
      "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
1397
 
      "    unknown_fields(), output);\n");
 
1517
  if (HasUnknownFields(descriptor_->file())) {
 
1518
    printer->Print("if (!unknown_fields().empty()) {\n");
 
1519
    printer->Indent();
 
1520
    if (to_array) {
 
1521
      printer->Print(
 
1522
        "target = "
 
1523
            "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
 
1524
        "    unknown_fields(), target);\n");
 
1525
    } else {
 
1526
      printer->Print(
 
1527
        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
 
1528
        "    unknown_fields(), output);\n");
 
1529
    }
 
1530
    printer->Outdent();
 
1531
 
 
1532
    printer->Print(
 
1533
      "}\n");
1398
1534
  }
1399
 
  printer->Outdent();
1400
 
 
1401
 
  printer->Print(
1402
 
    "}\n");
1403
1535
}
1404
1536
 
1405
1537
void MessageGenerator::
1406
1538
GenerateByteSize(io::Printer* printer) {
 
1539
  if (descriptor_->options().message_set_wire_format()) {
 
1540
    // Special-case MessageSet.
 
1541
    printer->Print(
 
1542
      "int $classname$::ByteSize() const {\n"
 
1543
      "  int total_size = _extensions_.MessageSetByteSize();\n",
 
1544
      "classname", classname_);
 
1545
    if (HasUnknownFields(descriptor_->file())) {
 
1546
      printer->Print(
 
1547
        "  total_size += ::google::protobuf::internal::WireFormat::\n"
 
1548
        "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
 
1549
    }
 
1550
    printer->Print(
 
1551
      "  _cached_size_ = total_size;\n"
 
1552
      "  return total_size;\n"
 
1553
      "}\n");
 
1554
    return;
 
1555
  }
 
1556
 
1407
1557
  printer->Print(
1408
1558
    "int $classname$::ByteSize() const {\n",
1409
1559
    "classname", classname_);
1473
1623
      "\n");
1474
1624
  }
1475
1625
 
1476
 
  printer->Print("if (!unknown_fields().empty()) {\n");
1477
 
  printer->Indent();
1478
 
  printer->Print(
1479
 
    "total_size +=\n"
1480
 
    "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
1481
 
    "    unknown_fields());\n");
1482
 
  printer->Outdent();
1483
 
  printer->Print("}\n");
 
1626
  if (HasUnknownFields(descriptor_->file())) {
 
1627
    printer->Print("if (!unknown_fields().empty()) {\n");
 
1628
    printer->Indent();
 
1629
    printer->Print(
 
1630
      "total_size +=\n"
 
1631
      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
 
1632
      "    unknown_fields());\n");
 
1633
    printer->Outdent();
 
1634
    printer->Print("}\n");
 
1635
  }
1484
1636
 
1485
1637
  // We update _cached_size_ even though this is a const method.  In theory,
1486
1638
  // this is not thread-compatible, because concurrent writes have undefined