~ubuntu-branches/debian/squeeze/protobuf/squeeze

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-06-02 16:19:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090602161900-vm176i3ryt35yk91
Tags: 2.0.3-2.2
* Non-maintainer upload.
* Fix FTBFS from -2.1: don't fail when we can't clean up the java build,
  such as when openjdk isn't installed.
* Disable parallel builds, because libtool is made of fail (if binary-arch
  and build-indep run concurrently, we relink a library while it's being
  used; that doesn't work so well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.
 
2
// Copyright 2008 Google Inc.  All rights reserved.
3
3
// http://code.google.com/p/protobuf/
4
4
//
5
 
// Licensed under the Apache License, Version 2.0 (the "License");
6
 
// you may not use this file except in compliance with the License.
7
 
// You may obtain a copy of the License at
8
 
//
9
 
//      http://www.apache.org/licenses/LICENSE-2.0
10
 
//
11
 
// Unless required by applicable law or agreed to in writing, software
12
 
// distributed under the License is distributed on an "AS IS" BASIS,
13
 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
// See the License for the specific language governing permissions and
15
 
// limitations under the License.
 
5
// Redistribution and use in source and binary forms, with or without
 
6
// modification, are permitted provided that the following conditions are
 
7
// met:
 
8
//
 
9
//     * Redistributions of source code must retain the above copyright
 
10
// notice, this list of conditions and the following disclaimer.
 
11
//     * Redistributions in binary form must reproduce the above
 
12
// copyright notice, this list of conditions and the following disclaimer
 
13
// in the documentation and/or other materials provided with the
 
14
// distribution.
 
15
//     * Neither the name of Google Inc. nor the names of its
 
16
// contributors may be used to endorse or promote products derived from
 
17
// this software without specific prior written permission.
 
18
//
 
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
30
 
17
31
// Author: kenton@google.com (Kenton Varda)
18
32
//  Based on original Protocol Buffers design by
374
388
  } else {
375
389
    vars["dllexport"] = dllexport_decl_ + " ";
376
390
  }
 
391
  vars["builddescriptorsname"] =
 
392
    GlobalBuildDescriptorsName(descriptor_->file()->name());
377
393
 
378
394
  printer->Print(vars,
379
395
    "class $dllexport$$classname$ : public ::google::protobuf::Message {\n"
391
407
    "  return *this;\n"
392
408
    "}\n"
393
409
    "\n"
394
 
    "inline static const $classname$& default_instance() {\n"
395
 
    "  return default_instance_;\n"
396
 
    "}\n"
397
 
    "\n"
398
410
    "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
399
 
    "  return _reflection_.unknown_fields();\n"
 
411
    "  return _unknown_fields_;\n"
400
412
    "}\n"
401
413
    "\n"
402
414
    "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
403
 
    "  return _reflection_.mutable_unknown_fields();\n"
 
415
    "  return &_unknown_fields_;\n"
404
416
    "}\n"
405
417
    "\n"
406
418
    "static const ::google::protobuf::Descriptor* descriptor();\n"
 
419
    "static const $classname$& default_instance();\n"
 
420
    "void Swap($classname$* other);\n"
407
421
    "\n"
408
422
    "// implements Message ----------------------------------------------\n"
409
423
    "\n"
432
446
    "public:\n"
433
447
    "\n"
434
448
    "const ::google::protobuf::Descriptor* GetDescriptor() const;\n"
435
 
    "const ::google::protobuf::Message::Reflection* GetReflection() const;\n"
436
 
    "::google::protobuf::Message::Reflection* GetReflection();\n"
 
449
    "const ::google::protobuf::Reflection* GetReflection() const;\n"
437
450
    "\n"
438
451
    "// nested types ----------------------------------------------------\n"
439
452
    "\n");
481
494
 
482
495
  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
483
496
  printer->Print(
484
 
    "::google::protobuf::internal::GeneratedMessageReflection _reflection_;\n"
 
497
    "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
485
498
    "mutable int _cached_size_;\n"
486
499
    "\n");
487
500
  for (int i = 0; i < descriptor_->field_count(); i++) {
491
504
 
492
505
  // Generate offsets and _has_bits_ boilerplate.
493
506
  printer->Print(vars,
494
 
    "\n"
495
 
    "static const $classname$ default_instance_;\n");
 
507
    "friend void $builddescriptorsname$_AssignGlobalDescriptors(\n"
 
508
    "    const ::google::protobuf::FileDescriptor* file);\n");
496
509
 
497
510
  if (descriptor_->field_count() > 0) {
498
511
    printer->Print(vars,
499
 
      "static const int _offsets_[$field_count$];\n"
500
 
      "\n"
501
512
      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
502
513
  } else {
503
514
    // Zero-size arrays aren't technically allowed, and MSVC in particular
505
516
    // other code compile.  Since this is an uncommon case, we'll just declare
506
517
    // them with size 1 and waste some space.  Oh well.
507
518
    printer->Print(
508
 
      "static const int _offsets_[1];\n"
509
 
      "\n"
510
519
      "::google::protobuf::uint32 _has_bits_[1];\n");
511
520
  }
512
521
 
521
530
    "}\n"
522
531
    "inline void _clear_bit(int index) {\n"
523
532
    "  _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
524
 
    "}\n");
 
533
    "}\n"
 
534
    "\n"
 
535
    "void InitAsDefaultInstance();\n"
 
536
    "static $classname$* default_instance_;\n",
 
537
    "classname", classname_);
525
538
 
526
539
  printer->Outdent();
527
540
  printer->Print(vars, "};");
540
553
 
541
554
void MessageGenerator::
542
555
GenerateDescriptorDeclarations(io::Printer* printer) {
543
 
  printer->Print("const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
544
 
                 "name", classname_);
 
556
  printer->Print(
 
557
    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
 
558
    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
 
559
    "  $name$_reflection_ = NULL;\n",
 
560
    "name", classname_);
545
561
 
546
562
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
547
563
    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
562
578
  vars["classname"] = classname_;
563
579
  vars["index"] = SimpleItoa(index);
564
580
 
 
581
  // Obtain the descriptor from the parent's descriptor.
565
582
  if (descriptor_->containing_type() == NULL) {
566
583
    printer->Print(vars,
567
584
      "$classname$_descriptor_ = file->message_type($index$);\n");
572
589
        "$parent$_descriptor_->nested_type($index$);\n");
573
590
  }
574
591
 
 
592
  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
 
593
  // because we need to make sure all default instances that this one might
 
594
  // depend on are constructed first.
 
595
  printer->Print(vars,
 
596
    "$classname$::default_instance_ = new $classname$();\n");
 
597
 
 
598
  // Generate the offsets.
 
599
  GenerateOffsets(printer);
 
600
 
 
601
  // Construct the reflection object.
 
602
  printer->Print(vars,
 
603
    "$classname$_reflection_ =\n"
 
604
    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
 
605
    "    $classname$_descriptor_,\n"
 
606
    "    $classname$::default_instance_,\n"
 
607
    "    $classname$_offsets_,\n"
 
608
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
 
609
    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
 
610
      "$classname$, _unknown_fields_),\n");
 
611
  if (descriptor_->extension_range_count() > 0) {
 
612
    printer->Print(vars,
 
613
      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
 
614
        "$classname$, _extensions_),\n");
 
615
  } else {
 
616
    // No extensions.
 
617
    printer->Print(vars,
 
618
      "    -1,\n");
 
619
  }
 
620
  printer->Print(vars,
 
621
    "    ::google::protobuf::DescriptorPool::generated_pool(),\n"
 
622
    "    sizeof($classname$));\n");
 
623
 
 
624
  // Handle nested types.
575
625
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
576
626
    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
577
627
  }
583
633
  // Register this message type with the message factory.
584
634
  printer->Print(vars,
585
635
    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
586
 
    "  $classname$_descriptor_, &$classname$::default_instance());\n");
 
636
    "  $classname$_descriptor_, $classname$::default_instance_);\n");
 
637
}
 
638
 
 
639
void MessageGenerator::
 
640
GenerateDefaultInstanceInitializer(io::Printer* printer) {
 
641
  printer->Print(
 
642
    "$classname$::default_instance_->InitAsDefaultInstance();\n",
 
643
    "classname", classname_);
 
644
 
 
645
  // Handle nested types.
 
646
  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
 
647
    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
 
648
  }
587
649
}
588
650
 
589
651
void MessageGenerator::
599
661
    printer->Print("\n");
600
662
  }
601
663
 
602
 
  printer->Print(
603
 
    "const $classname$ $classname$::default_instance_;\n"
604
 
    "\n",
605
 
    "classname", classname_);
606
 
 
607
664
  // Generate non-inline field definitions.
608
665
  for (int i = 0; i < descriptor_->field_count(); i++) {
609
666
    field_generators_.get(descriptor_->field(i))
616
673
    extension_generators_[i]->GenerateDefinition(printer);
617
674
  }
618
675
 
619
 
  GenerateOffsets(printer);
620
 
  printer->Print("\n");
621
 
 
622
676
  GenerateStructors(printer);
623
677
  printer->Print("\n");
624
678
 
641
695
    GenerateCopyFrom(printer);
642
696
    printer->Print("\n");
643
697
 
 
698
    GenerateSwap(printer);
 
699
    printer->Print("\n");
 
700
 
644
701
    GenerateIsInitialized(printer);
645
702
    printer->Print("\n");
646
703
  }
650
707
    "  return descriptor();\n"
651
708
    "}\n"
652
709
    "\n"
653
 
    "const ::google::protobuf::Message::Reflection*\n"
654
 
    "$classname$::GetReflection() const {\n"
655
 
    "  return &_reflection_;\n"
656
 
    "}\n"
657
 
    "\n"
658
 
    "::google::protobuf::Message::Reflection* $classname$::GetReflection() {\n"
659
 
    "  return &_reflection_;\n"
 
710
    "const ::google::protobuf::Reflection* $classname$::GetReflection() const {\n"
 
711
    "  if ($classname$_reflection_ == NULL) $builddescriptorsname$();\n"
 
712
    "  return $classname$_reflection_;\n"
660
713
    "}\n",
661
 
    "classname", classname_);
 
714
    "classname", classname_,
 
715
    "builddescriptorsname",
 
716
      GlobalBuildDescriptorsName(descriptor_->file()->name()));
662
717
}
663
718
 
664
719
void MessageGenerator::
665
720
GenerateOffsets(io::Printer* printer) {
666
721
  printer->Print(
667
 
    "const int $classname$::_offsets_[$field_count$] = {\n",
 
722
    "static const int $classname$_offsets_[$field_count$] = {\n",
668
723
    "classname", classname_,
669
724
    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
670
725
  printer->Indent();
686
741
  printer->Indent();
687
742
  printer->Indent();
688
743
 
689
 
  bool has_extensions = descriptor_->extension_range_count() > 0;
690
 
  if (has_extensions) {
 
744
  printer->Print(
 
745
    "::google::protobuf::Message(),\n");
 
746
 
 
747
  if (descriptor_->extension_range_count() > 0) {
691
748
    printer->Print(
692
 
      "_extensions_(descriptor(),\n"
 
749
      "_extensions_(&$classname$_descriptor_,\n"
693
750
      "             ::google::protobuf::DescriptorPool::generated_pool(),\n"
694
 
      "             ::google::protobuf::MessageFactory::generated_factory()),\n");
 
751
      "             ::google::protobuf::MessageFactory::generated_factory()),\n",
 
752
      "classname", classname_);
695
753
  }
696
754
 
697
755
  printer->Print(
698
 
    "_reflection_(descriptor(),\n"
699
 
    "             this, &default_instance_,\n"
700
 
    "             _offsets_, _has_bits_, $extensions$),\n"
701
 
    "_cached_size_(0)",
702
 
    "extensions", has_extensions ? "&_extensions_" : "NULL");
 
756
    "_cached_size_(0)");
703
757
 
704
758
  // Write the initializers for each field.
705
759
  for (int i = 0; i < descriptor_->field_count(); i++) {
721
775
  GenerateInitializerList(printer);
722
776
  printer->Print(" {\n"
723
777
    "  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n"
724
 
    "  if (this == &default_instance_) {\n");
 
778
    "}\n");
 
779
 
 
780
  printer->Print(
 
781
    "\n"
 
782
    "void $classname$::InitAsDefaultInstance() {",
 
783
    "classname", classname_);
725
784
 
726
785
  // The default instance needs all of its embedded message pointers
727
 
  // cross-linked to other default instances.
 
786
  // cross-linked to other default instances.  We can't do this initialization
 
787
  // in the constructor because some other default instances may not have been
 
788
  // constructed yet at that time.
728
789
  // TODO(kenton):  Maybe all message fields (even for non-default messages)
729
790
  //   should be initialized to point at default instances rather than NULL?
730
791
  for (int i = 0; i < descriptor_->field_count(); i++) {
733
794
    if (!field->is_repeated() &&
734
795
        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
735
796
      printer->Print(
736
 
          "    $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
 
797
          "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
737
798
          "name", FieldName(field),
738
799
          "type", ClassName(field->message_type(), true));
739
800
    }
740
801
  }
741
802
  printer->Print(
742
 
    "  }\n"
743
803
    "}\n"
744
804
    "\n");
745
805
 
769
829
  }
770
830
 
771
831
  printer->Print(
772
 
    "if (this != &default_instance_) {\n");
 
832
    "if (this != default_instance_) {\n");
773
833
 
774
834
  // We need to delete all embedded messages.
775
835
  // TODO(kenton):  If we make unset messages point at default instances
796
856
    "  return $classname$_descriptor_;\n"
797
857
    "}\n"
798
858
    "\n"
 
859
    "const $classname$& $classname$::default_instance() {\n"
 
860
    "  if (default_instance_ == NULL) $builddescriptorsname$();\n"
 
861
    "  return *default_instance_;\n"
 
862
    "}\n"
 
863
    "\n"
 
864
    "$classname$* $classname$::default_instance_ = NULL;\n"
 
865
    "\n"
799
866
    "$classname$* $classname$::New() const {\n"
800
867
    "  return new $classname$;\n"
801
868
    "}\n",
885
952
}
886
953
 
887
954
void MessageGenerator::
 
955
GenerateSwap(io::Printer* printer) {
 
956
  // Generate the Swap member function.
 
957
  printer->Print("void $classname$::Swap($classname$* other) {\n",
 
958
                 "classname", classname_);
 
959
  printer->Indent();
 
960
  printer->Print("if (other != this) {\n");
 
961
  printer->Indent();
 
962
 
 
963
  for (int i = 0; i < descriptor_->field_count(); i++) {
 
964
    const FieldDescriptor* field = descriptor_->field(i);
 
965
    field_generators_.get(field).GenerateSwappingCode(printer);
 
966
  }
 
967
 
 
968
  for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
 
969
    printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
 
970
                   "i", SimpleItoa(i));
 
971
  }
 
972
 
 
973
  printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
 
974
  printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
 
975
  if (descriptor_->extension_range_count() > 0) {
 
976
    printer->Print("_extensions_.Swap(&other->_extensions_);\n");
 
977
  }
 
978
 
 
979
  printer->Outdent();
 
980
  printer->Print("}\n");
 
981
  printer->Outdent();
 
982
  printer->Print("}\n");
 
983
}
 
984
 
 
985
void MessageGenerator::
888
986
GenerateMergeFrom(io::Printer* printer) {
889
987
  // Generate the generalized MergeFrom (aka that which takes in the Message
890
988
  // base class as a parameter).
894
992
    "classname", classname_);
895
993
  printer->Indent();
896
994
 
897
 
  if (descriptor_->field_count() > 0) {
898
 
    // Cast the message to the proper type. If we find that the message is
899
 
    // *not* of the proper type, we can still call Merge via the reflection
900
 
    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
901
 
    // for each message.
902
 
    printer->Print(
903
 
      "const $classname$* source =\n"
904
 
      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
905
 
      "    &from);\n"
906
 
      "if (source == NULL) {\n"
907
 
      "  ::google::protobuf::internal::ReflectionOps::Merge(\n"
908
 
      "    descriptor(), *from.GetReflection(), &_reflection_);\n"
909
 
      "} else {\n"
910
 
      "  MergeFrom(*source);\n"
911
 
      "}\n",
912
 
      "classname", classname_);
913
 
  }
 
995
  // Cast the message to the proper type. If we find that the message is
 
996
  // *not* of the proper type, we can still call Merge via the reflection
 
997
  // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
 
998
  // for each message.
 
999
  printer->Print(
 
1000
    "const $classname$* source =\n"
 
1001
    "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
 
1002
    "    &from);\n"
 
1003
    "if (source == NULL) {\n"
 
1004
    "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
 
1005
    "} else {\n"
 
1006
    "  MergeFrom(*source);\n"
 
1007
    "}\n",
 
1008
    "classname", classname_);
914
1009
 
915
1010
  printer->Outdent();
916
1011
  printer->Print("}\n\n");
1028
1123
      "bool $classname$::MergePartialFromCodedStream(\n"
1029
1124
      "    ::google::protobuf::io::CodedInputStream* input) {\n"
1030
1125
      "  return ::google::protobuf::internal::WireFormat::ParseAndMergePartial(\n"
1031
 
      "    descriptor(), input, &_reflection_);\n"
 
1126
      "    input, this);\n"
1032
1127
      "}\n",
1033
1128
      "classname", classname_);
1034
1129
    return;
1138
1233
    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
1139
1234
      const Descriptor::ExtensionRange* range =
1140
1235
        descriptor_->extension_range(i);
1141
 
      if (i > 0) printer->Print(" &&\n    ");
 
1236
      if (i > 0) printer->Print(" ||\n    ");
1142
1237
 
1143
1238
      uint32 start_tag = WireFormat::MakeTag(
1144
1239
        range->start, static_cast<WireFormat::WireType>(0));
1157
1252
      }
1158
1253
    }
1159
1254
    printer->Print(") {\n"
1160
 
      "  DO_(_extensions_.ParseField(tag, input, &_reflection_));\n"
 
1255
      "  DO_(_extensions_.ParseField(tag, input, this));\n"
1161
1256
      "  continue;\n"
1162
1257
      "}\n");
1163
1258
  }
1214
1309
  printer->Print(vars,
1215
1310
    "// Extension range [$start$, $end$)\n"
1216
1311
    "DO_(_extensions_.SerializeWithCachedSizes(\n"
1217
 
    "    $start$, $end$, &_reflection_, output));\n\n");
 
1312
    "    $start$, $end$, *this, output));\n\n");
1218
1313
}
1219
1314
 
1220
1315
void MessageGenerator::
1341
1436
 
1342
1437
  if (descriptor_->extension_range_count() > 0) {
1343
1438
    printer->Print(
1344
 
      "total_size += _extensions_.ByteSize(&_reflection_);\n"
 
1439
      "total_size += _extensions_.ByteSize(*this);\n"
1345
1440
      "\n");
1346
1441
  }
1347
1442