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
27
41
namespace protobuf {
28
42
namespace internal {
30
void ReflectionOps::Copy(const Descriptor* descriptor,
31
const Message::Reflection& from,
32
Message::Reflection* to) {
44
void ReflectionOps::Copy(const Message& from, Message* to) {
33
45
if (&from == to) return;
34
Clear(descriptor, to);
35
Merge(descriptor, from, to);
38
void ReflectionOps::Merge(const Descriptor* descriptor,
39
const Message::Reflection& from,
40
Message::Reflection* to) {
50
void ReflectionOps::Merge(const Message& from, Message* to) {
41
51
GOOGLE_CHECK_NE(&from, to);
53
const Descriptor* descriptor = from.GetDescriptor();
54
GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
55
<< "Tried to merge messages of different types.";
57
const Reflection* from_reflection = from.GetReflection();
58
const Reflection* to_reflection = to->GetReflection();
42
60
vector<const FieldDescriptor*> fields;
43
from.ListFields(&fields);
61
from_reflection->ListFields(from, &fields);
44
62
for (int i = 0; i < fields.size(); i++) {
45
63
const FieldDescriptor* field = fields[i];
47
65
if (field->is_repeated()) {
48
int count = from.FieldSize(field);
66
int count = from_reflection->FieldSize(from, field);
49
67
for (int j = 0; j < count; j++) {
50
68
switch (field->cpp_type()) {
51
69
#define HANDLE_TYPE(CPPTYPE, METHOD) \
52
70
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
53
to->Add##METHOD(field, \
54
from.GetRepeated##METHOD(field, j)); \
71
to_reflection->Add##METHOD(to, field, \
72
from_reflection->GetRepeated##METHOD(from, field, j)); \
57
75
HANDLE_TYPE(INT32 , Int32 );
68
86
case FieldDescriptor::CPPTYPE_MESSAGE:
69
to->AddMessage(field)->MergeFrom(
70
from.GetRepeatedMessage(field, j));
87
to_reflection->AddMessage(to, field)->MergeFrom(
88
from_reflection->GetRepeatedMessage(from, field, j));
74
} else if (from.HasField(field)) {
75
93
switch (field->cpp_type()) {
76
94
#define HANDLE_TYPE(CPPTYPE, METHOD) \
77
95
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
78
to->Set##METHOD(field, from.Get##METHOD(field)); \
96
to_reflection->Set##METHOD(to, field, \
97
from_reflection->Get##METHOD(from, field)); \
81
100
HANDLE_TYPE(INT32 , Int32 );
90
109
#undef HANDLE_TYPE
92
111
case FieldDescriptor::CPPTYPE_MESSAGE:
93
to->MutableMessage(field)->MergeFrom(
94
from.GetMessage(field));
112
to_reflection->MutableMessage(to, field)->MergeFrom(
113
from_reflection->GetMessage(from, field));
100
to->MutableUnknownFields()->MergeFrom(from.GetUnknownFields());
119
to_reflection->MutableUnknownFields(to)->MergeFrom(
120
from_reflection->GetUnknownFields(from));
103
void ReflectionOps::Clear(const Descriptor* descriptor,
104
Message::Reflection* reflection) {
123
void ReflectionOps::Clear(Message* message) {
124
const Reflection* reflection = message->GetReflection();
105
126
vector<const FieldDescriptor*> fields;
106
reflection->ListFields(&fields);
127
reflection->ListFields(*message, &fields);
107
128
for (int i = 0; i < fields.size(); i++) {
108
reflection->ClearField(fields[i]);
129
reflection->ClearField(message, fields[i]);
111
reflection->MutableUnknownFields()->Clear();
132
reflection->MutableUnknownFields(message)->Clear();
114
bool ReflectionOps::IsInitialized(const Descriptor* descriptor,
115
const Message::Reflection& reflection) {
135
bool ReflectionOps::IsInitialized(const Message& message) {
136
const Descriptor* descriptor = message.GetDescriptor();
137
const Reflection* reflection = message.GetReflection();
116
139
// Check required fields of this message.
117
140
for (int i = 0; i < descriptor->field_count(); i++) {
118
141
if (descriptor->field(i)->is_required()) {
119
if (!reflection.HasField(descriptor->field(i))) {
142
if (!reflection->HasField(message, descriptor->field(i))) {
125
148
// Check that sub-messages are initialized.
126
149
vector<const FieldDescriptor*> fields;
127
reflection.ListFields(&fields);
150
reflection->ListFields(message, &fields);
128
151
for (int i = 0; i < fields.size(); i++) {
129
152
const FieldDescriptor* field = fields[i];
130
153
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
131
154
if (field->is_repeated()) {
132
int size = reflection.FieldSize(field);
155
int size = reflection->FieldSize(message, field);
134
157
for (int i = 0; i < size; i++) {
135
if (!reflection.GetRepeatedMessage(field, i).IsInitialized()) {
158
if (!reflection->GetRepeatedMessage(message, field, i)
140
if (reflection.HasField(field) &&
141
!reflection.GetMessage(field).IsInitialized()) {
164
if (!reflection->GetMessage(message, field).IsInitialized()) {
151
void ReflectionOps::DiscardUnknownFields(
152
const Descriptor* descriptor,
153
Message::Reflection* reflection) {
154
reflection->MutableUnknownFields()->Clear();
174
void ReflectionOps::DiscardUnknownFields(Message* message) {
175
const Reflection* reflection = message->GetReflection();
177
reflection->MutableUnknownFields(message)->Clear();
156
179
vector<const FieldDescriptor*> fields;
157
reflection->ListFields(&fields);
180
reflection->ListFields(*message, &fields);
158
181
for (int i = 0; i < fields.size(); i++) {
159
182
const FieldDescriptor* field = fields[i];
160
183
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
161
184
if (field->is_repeated()) {
162
int size = reflection->FieldSize(field);
185
int size = reflection->FieldSize(*message, field);
163
186
for (int i = 0; i < size; i++) {
164
reflection->MutableRepeatedMessage(field, i)->DiscardUnknownFields();
187
reflection->MutableRepeatedMessage(message, field, i)
188
->DiscardUnknownFields();
167
if (reflection->HasField(field)) {
168
reflection->MutableMessage(field)->DiscardUnknownFields();
191
reflection->MutableMessage(message, field)->DiscardUnknownFields();
195
217
void ReflectionOps::FindInitializationErrors(
196
const Descriptor* descriptor,
197
const Message::Reflection& reflection,
218
const Message& message,
198
219
const string& prefix,
199
220
vector<string>* errors) {
221
const Descriptor* descriptor = message.GetDescriptor();
222
const Reflection* reflection = message.GetReflection();
200
224
// Check required fields of this message.
201
225
for (int i = 0; i < descriptor->field_count(); i++) {
202
226
if (descriptor->field(i)->is_required()) {
203
if (!reflection.HasField(descriptor->field(i))) {
227
if (!reflection->HasField(message, descriptor->field(i))) {
204
228
errors->push_back(prefix + descriptor->field(i)->name());
209
233
// Check sub-messages.
210
234
vector<const FieldDescriptor*> fields;
211
reflection.ListFields(&fields);
235
reflection->ListFields(message, &fields);
212
236
for (int i = 0; i < fields.size(); i++) {
213
237
const FieldDescriptor* field = fields[i];
214
238
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
216
240
if (field->is_repeated()) {
217
int size = reflection.FieldSize(field);
241
int size = reflection->FieldSize(message, field);
219
243
for (int i = 0; i < size; i++) {
220
const Message& sub_message = reflection.GetRepeatedMessage(field, i);
221
FindInitializationErrors(field->message_type(),
222
*sub_message.GetReflection(),
244
const Message& sub_message =
245
reflection->GetRepeatedMessage(message, field, i);
246
FindInitializationErrors(sub_message,
223
247
SubMessagePrefix(prefix, field, i),
227
if (reflection.HasField(field)) {
228
const Message& sub_message = reflection.GetMessage(field);
229
FindInitializationErrors(field->message_type(),
230
*sub_message.GetReflection(),
231
SubMessagePrefix(prefix, field, -1),
251
const Message& sub_message = reflection->GetMessage(message, field);
252
FindInitializationErrors(sub_message,
253
SubMessagePrefix(prefix, field, -1),