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

« back to all changes in this revision

Viewing changes to src/google/protobuf/reflection_ops.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
27
41
namespace protobuf {
28
42
namespace internal {
29
43
 
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);
 
46
  Clear(to);
 
47
  Merge(from, to);
36
48
}
37
49
 
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);
 
52
 
 
53
  const Descriptor* descriptor = from.GetDescriptor();
 
54
  GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
 
55
    << "Tried to merge messages of different types.";
 
56
 
 
57
  const Reflection* from_reflection = from.GetReflection();
 
58
  const Reflection* to_reflection = to->GetReflection();
 
59
 
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];
46
64
 
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));     \
55
73
            break;
56
74
 
57
75
          HANDLE_TYPE(INT32 , Int32 );
66
84
#undef HANDLE_TYPE
67
85
 
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));
71
89
            break;
72
90
        }
73
91
      }
74
 
    } else if (from.HasField(field)) {
 
92
    } else {
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));                     \
79
98
          break;
80
99
 
81
100
        HANDLE_TYPE(INT32 , Int32 );
90
109
#undef HANDLE_TYPE
91
110
 
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));
95
114
          break;
96
115
      }
97
116
    }
98
117
  }
99
118
 
100
 
  to->MutableUnknownFields()->MergeFrom(from.GetUnknownFields());
 
119
  to_reflection->MutableUnknownFields(to)->MergeFrom(
 
120
    from_reflection->GetUnknownFields(from));
101
121
}
102
122
 
103
 
void ReflectionOps::Clear(const Descriptor* descriptor,
104
 
                          Message::Reflection* reflection) {
 
123
void ReflectionOps::Clear(Message* message) {
 
124
  const Reflection* reflection = message->GetReflection();
 
125
 
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]);
109
130
  }
110
131
 
111
 
  reflection->MutableUnknownFields()->Clear();
 
132
  reflection->MutableUnknownFields(message)->Clear();
112
133
}
113
134
 
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();
 
138
 
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))) {
120
143
        return false;
121
144
      }
122
145
    }
124
147
 
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);
133
156
 
134
157
        for (int i = 0; i < size; i++) {
135
 
          if (!reflection.GetRepeatedMessage(field, i).IsInitialized()) {
 
158
          if (!reflection->GetRepeatedMessage(message, field, i)
 
159
                          .IsInitialized()) {
136
160
            return false;
137
161
          }
138
162
        }
139
163
      } else {
140
 
        if (reflection.HasField(field) &&
141
 
            !reflection.GetMessage(field).IsInitialized()) {
 
164
        if (!reflection->GetMessage(message, field).IsInitialized()) {
142
165
          return false;
143
166
        }
144
167
      }
148
171
  return true;
149
172
}
150
173
 
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();
 
176
 
 
177
  reflection->MutableUnknownFields(message)->Clear();
155
178
 
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();
165
189
        }
166
190
      } else {
167
 
        if (reflection->HasField(field)) {
168
 
          reflection->MutableMessage(field)->DiscardUnknownFields();
169
 
        }
 
191
        reflection->MutableMessage(message, field)->DiscardUnknownFields();
170
192
      }
171
193
    }
172
194
  }
193
215
}
194
216
 
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();
 
223
 
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());
205
229
      }
206
230
    }
208
232
 
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) {
215
239
 
216
240
      if (field->is_repeated()) {
217
 
        int size = reflection.FieldSize(field);
 
241
        int size = reflection->FieldSize(message, field);
218
242
 
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),
224
248
                                   errors);
225
249
        }
226
250
      } else {
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),
232
 
                                   errors);
233
 
        }
 
251
        const Message& sub_message = reflection->GetMessage(message, field);
 
252
        FindInitializationErrors(sub_message,
 
253
                                 SubMessagePrefix(prefix, field, -1),
 
254
                                 errors);
234
255
      }
235
256
    }
236
257
  }