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
35
50
// Lookup functions
37
52
const FieldDescriptor*
38
ExtensionSet::FindKnownExtensionByName(const string& name) const {
39
const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
40
if (result != NULL && result->containing_type() == extendee_) {
44
if (extendee_->options().message_set_wire_format()) {
45
// MessageSet extensions may be identified by type name.
46
const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
48
// Look for a matching extension in the foreign type's scope.
49
for (int i = 0; i < type->extension_count(); i++) {
50
const FieldDescriptor* extension = type->extension(i);
51
if (extension->containing_type() == extendee_ &&
52
extension->type() == FieldDescriptor::TYPE_MESSAGE &&
53
extension->is_optional() &&
54
extension->message_type() == type) {
65
const FieldDescriptor*
66
ExtensionSet::FindKnownExtensionByNumber(int number) const {
67
return descriptor_pool_->FindExtensionByNumber(extendee_, number);
70
const FieldDescriptor*
71
53
ExtensionSet::FindKnownExtensionOrDie(int number) const {
72
const FieldDescriptor* descriptor = FindKnownExtensionByNumber(number);
54
const FieldDescriptor* descriptor =
55
descriptor_pool_->FindExtensionByNumber(*extendee_, number);
73
56
if (descriptor == NULL) {
74
57
// This extension doesn't exist, so we have to crash. However, let's
75
58
// try to provide an informative error message.
77
60
message_factory_ == MessageFactory::generated_factory()) {
78
61
// This is probably the ExtensionSet for a generated class.
79
62
GOOGLE_LOG(FATAL) << ": No extension is registered for \""
80
<< extendee_->full_name() << "\" with number "
63
<< (*extendee_)->full_name() << "\" with number "
81
64
<< number << ". Perhaps you were trying to access it via "
82
65
"the Reflection interface, but you provided a "
83
66
"FieldDescriptor which did not come from a linked-in "
88
71
// This is probably a DynamicMessage.
89
72
GOOGLE_LOG(FATAL) << ": No extension is registered for \""
90
<< extendee_->full_name() << "\" with number "
73
<< (*extendee_)->full_name() << "\" with number "
91
74
<< number << ". If you were using a DynamicMessage, "
92
75
"remember that you are only allowed to access extensions "
93
76
"which are defined in the DescriptorPool which you passed "
519
void ExtensionSet::Swap(ExtensionSet* x) {
520
extensions_.swap(x->extensions_);
521
std::swap(extendee_, x->extendee_);
522
std::swap(descriptor_pool_, x->descriptor_pool_);
523
std::swap(message_factory_, x->message_factory_);
536
526
bool ExtensionSet::IsInitialized() const {
537
527
// Extensions are never requried. However, we need to check that all
538
528
// embedded messages are initialized.
560
550
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
561
Message::Reflection* reflection) {
562
552
const FieldDescriptor* field =
563
FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
553
message->GetReflection()
554
->FindKnownExtensionByNumber(WireFormat::GetTagFieldNumber(tag));
565
return WireFormat::ParseAndMergeField(tag, field, reflection, input);
556
return WireFormat::ParseAndMergeField(tag, field, message, input);
568
559
bool ExtensionSet::SerializeWithCachedSizes(
569
560
int start_field_number, int end_field_number,
570
const Message::Reflection* reflection,
561
const Message& message,
571
562
io::CodedOutputStream* output) const {
572
563
map<int, Extension>::const_iterator iter;
573
564
for (iter = extensions_.lower_bound(start_field_number);
574
565
iter != extensions_.end() && iter->first < end_field_number;
576
if (!iter->second.SerializeFieldWithCachedSizes(reflection, output)) {
567
if (!iter->second.SerializeFieldWithCachedSizes(message, output)) {
584
int ExtensionSet::ByteSize(const Message::Reflection* reflection) const {
575
int ExtensionSet::ByteSize(const Message& message) const {
585
576
int total_size = 0;
587
578
for (map<int, Extension>::const_iterator iter = extensions_.begin();
588
579
iter != extensions_.end(); ++iter) {
589
total_size += iter->second.ByteSize(reflection);
580
total_size += iter->second.ByteSize(message);
586
int ExtensionSet::SpaceUsedExcludingSelf() const {
588
extensions_.size() * sizeof(map<int, Extension>::value_type);
589
for (map<int, Extension>::const_iterator iter = extensions_.begin(),
590
end = extensions_.end();
593
total_size += iter->second.SpaceUsedExcludingSelf();
592
595
return total_size;
654
657
bool ExtensionSet::Extension::SerializeFieldWithCachedSizes(
655
const Message::Reflection* reflection,
658
const Message& message,
656
659
io::CodedOutputStream* output) const {
657
660
if (descriptor->is_repeated() || !is_cleared) {
658
661
return WireFormat::SerializeFieldWithCachedSizes(
659
descriptor, reflection, output);
662
descriptor, message, output);
665
int64 ExtensionSet::Extension::ByteSize(
666
const Message::Reflection* reflection) const {
668
int64 ExtensionSet::Extension::ByteSize(const Message& message) const {
667
669
if (descriptor->is_repeated() || !is_cleared) {
668
return WireFormat::FieldByteSize(descriptor, reflection);
670
return WireFormat::FieldByteSize(descriptor, message);
670
672
// Cleared, non-repeated field.
735
int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
737
if (descriptor->is_repeated()) {
738
switch (descriptor->cpp_type()) {
739
#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
740
case FieldDescriptor::CPPTYPE_##UPPERCASE: \
741
total_size += sizeof(*repeated_##LOWERCASE##_value) + \
742
repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
745
HANDLE_TYPE( INT32, int32);
746
HANDLE_TYPE( INT64, int64);
747
HANDLE_TYPE( UINT32, uint32);
748
HANDLE_TYPE( UINT64, uint64);
749
HANDLE_TYPE( FLOAT, float);
750
HANDLE_TYPE( DOUBLE, double);
751
HANDLE_TYPE( BOOL, bool);
752
HANDLE_TYPE( ENUM, enum);
753
HANDLE_TYPE( STRING, string);
754
HANDLE_TYPE(MESSAGE, message);
757
switch (descriptor->cpp_type()) {
758
case FieldDescriptor::CPPTYPE_STRING:
759
total_size += sizeof(*string_value) +
760
StringSpaceUsedExcludingSelf(*string_value);
762
case FieldDescriptor::CPPTYPE_MESSAGE:
763
total_size += message_value->SpaceUsed();
766
// No extra storage costs for primitive types.
733
773
} // namespace internal
734
774
} // namespace protobuf
735
775
} // namespace google