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/
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
9
// http://www.apache.org/licenses/LICENSE-2.0
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
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
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.
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.
17
31
// Author: kenton@google.com (Kenton Varda)
18
32
// Based on original Protocol Buffers design by
391
407
" return *this;\n"
394
"inline static const $classname$& default_instance() {\n"
395
" return default_instance_;\n"
398
410
"inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
399
" return _reflection_.unknown_fields();\n"
411
" return _unknown_fields_;\n"
402
414
"inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
403
" return _reflection_.mutable_unknown_fields();\n"
415
" return &_unknown_fields_;\n"
406
418
"static const ::google::protobuf::Descriptor* descriptor();\n"
419
"static const $classname$& default_instance();\n"
420
"void Swap($classname$* other);\n"
408
422
"// implements Message ----------------------------------------------\n"
492
505
// Generate offsets and _has_bits_ boilerplate.
493
506
printer->Print(vars,
495
"static const $classname$ default_instance_;\n");
507
"friend void $builddescriptorsname$_AssignGlobalDescriptors(\n"
508
" const ::google::protobuf::FileDescriptor* file);\n");
497
510
if (descriptor_->field_count() > 0) {
498
511
printer->Print(vars,
499
"static const int _offsets_[$field_count$];\n"
501
512
"::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
503
514
// Zero-size arrays aren't technically allowed, and MSVC in particular
522
531
"inline void _clear_bit(int index) {\n"
523
532
" _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
535
"void InitAsDefaultInstance();\n"
536
"static $classname$* default_instance_;\n",
537
"classname", classname_);
526
539
printer->Outdent();
527
540
printer->Print(vars, "};");
541
554
void MessageGenerator::
542
555
GenerateDescriptorDeclarations(io::Printer* printer) {
543
printer->Print("const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n",
557
"const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
558
"const ::google::protobuf::internal::GeneratedMessageReflection*\n"
559
" $name$_reflection_ = NULL;\n",
546
562
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
547
563
nested_generators_[i]->GenerateDescriptorDeclarations(printer);
572
589
"$parent$_descriptor_->nested_type($index$);\n");
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.
596
"$classname$::default_instance_ = new $classname$();\n");
598
// Generate the offsets.
599
GenerateOffsets(printer);
601
// Construct the reflection object.
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) {
613
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
614
"$classname$, _extensions_),\n");
621
" ::google::protobuf::DescriptorPool::generated_pool(),\n"
622
" sizeof($classname$));\n");
624
// Handle nested types.
575
625
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
576
626
nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
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");
639
void MessageGenerator::
640
GenerateDefaultInstanceInitializer(io::Printer* printer) {
642
"$classname$::default_instance_->InitAsDefaultInstance();\n",
643
"classname", classname_);
645
// Handle nested types.
646
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
647
nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
589
651
void MessageGenerator::
650
707
" return descriptor();\n"
653
"const ::google::protobuf::Message::Reflection*\n"
654
"$classname$::GetReflection() const {\n"
655
" return &_reflection_;\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"
661
"classname", classname_);
714
"classname", classname_,
715
"builddescriptorsname",
716
GlobalBuildDescriptorsName(descriptor_->file()->name()));
664
719
void MessageGenerator::
665
720
GenerateOffsets(io::Printer* printer) {
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();
689
bool has_extensions = descriptor_->extension_range_count() > 0;
690
if (has_extensions) {
745
"::google::protobuf::Message(),\n");
747
if (descriptor_->extension_range_count() > 0) {
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_);
698
"_reflection_(descriptor(),\n"
699
" this, &default_instance_,\n"
700
" _offsets_, _has_bits_, $extensions$),\n"
702
"extensions", has_extensions ? "&_extensions_" : "NULL");
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");
782
"void $classname$::InitAsDefaultInstance() {",
783
"classname", classname_);
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) {
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));
796
856
" return $classname$_descriptor_;\n"
859
"const $classname$& $classname$::default_instance() {\n"
860
" if (default_instance_ == NULL) $builddescriptorsname$();\n"
861
" return *default_instance_;\n"
864
"$classname$* $classname$::default_instance_ = NULL;\n"
799
866
"$classname$* $classname$::New() const {\n"
800
867
" return new $classname$;\n"
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_);
960
printer->Print("if (other != this) {\n");
963
for (int i = 0; i < descriptor_->field_count(); i++) {
964
const FieldDescriptor* field = descriptor_->field(i);
965
field_generators_.get(field).GenerateSwappingCode(printer);
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",
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");
980
printer->Print("}\n");
982
printer->Print("}\n");
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();
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
903
"const $classname$* source =\n"
904
" ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
906
"if (source == NULL) {\n"
907
" ::google::protobuf::internal::ReflectionOps::Merge(\n"
908
" descriptor(), *from.GetReflection(), &_reflection_);\n"
910
" MergeFrom(*source);\n"
912
"classname", classname_);
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
1000
"const $classname$* source =\n"
1001
" ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1003
"if (source == NULL) {\n"
1004
" ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1006
" MergeFrom(*source);\n"
1008
"classname", classname_);
915
1010
printer->Outdent();
916
1011
printer->Print("}\n\n");
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 ");
1143
1238
uint32 start_tag = WireFormat::MakeTag(
1144
1239
range->start, static_cast<WireFormat::WireType>(0));
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");
1220
1315
void MessageGenerator::