1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
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.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 #include <google/protobuf/reflection_ops.h>
35
36 #include <string>
37 #include <vector>
38
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/descriptor.pb.h>
42 #include <google/protobuf/descriptor.h>
43 #include <google/protobuf/map_field.h>
44 #include <google/protobuf/map_field_inl.h>
45 #include <google/protobuf/unknown_field_set.h>
46 #include <google/protobuf/stubs/strutil.h>
47
48
49 #include <google/protobuf/port_def.inc>
50
51 namespace google {
52 namespace protobuf {
53 namespace internal {
54
GetReflectionOrDie(const Message & m)55 static const Reflection* GetReflectionOrDie(const Message& m) {
56 const Reflection* r = m.GetReflection();
57 if (r == nullptr) {
58 const Descriptor* d = m.GetDescriptor();
59 const std::string& mtype = d ? d->name() : "unknown";
60 // RawMessage is one known type for which GetReflection() returns nullptr.
61 GOOGLE_LOG(FATAL) << "Message does not support reflection (type " << mtype << ").";
62 }
63 return r;
64 }
65
Copy(const Message & from,Message * to)66 void ReflectionOps::Copy(const Message& from, Message* to) {
67 if (&from == to) return;
68 Clear(to);
69 Merge(from, to);
70 }
71
Merge(const Message & from,Message * to)72 void ReflectionOps::Merge(const Message& from, Message* to) {
73 GOOGLE_CHECK_NE(&from, to);
74
75 const Descriptor* descriptor = from.GetDescriptor();
76 GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
77 << "Tried to merge messages of different types "
78 << "(merge " << descriptor->full_name() << " to "
79 << to->GetDescriptor()->full_name() << ")";
80
81 const Reflection* from_reflection = GetReflectionOrDie(from);
82 const Reflection* to_reflection = GetReflectionOrDie(*to);
83 bool is_from_generated = (from_reflection->GetMessageFactory() ==
84 google::protobuf::MessageFactory::generated_factory());
85 bool is_to_generated = (to_reflection->GetMessageFactory() ==
86 google::protobuf::MessageFactory::generated_factory());
87
88 std::vector<const FieldDescriptor*> fields;
89 from_reflection->ListFields(from, &fields);
90 for (int i = 0; i < fields.size(); i++) {
91 const FieldDescriptor* field = fields[i];
92
93 if (field->is_repeated()) {
94 // Use map reflection if both are in map status and have the
95 // same map type to avoid sync with repeated field.
96 // Note: As from and to messages have the same descriptor, the
97 // map field types are the same if they are both generated
98 // messages or both dynamic messages.
99 if (is_from_generated == is_to_generated && field->is_map()) {
100 const MapFieldBase* from_field =
101 from_reflection->GetMapData(from, field);
102 MapFieldBase* to_field = to_reflection->MutableMapData(to, field);
103 if (to_field->IsMapValid() && from_field->IsMapValid()) {
104 to_field->MergeFrom(*from_field);
105 continue;
106 }
107 }
108 int count = from_reflection->FieldSize(from, field);
109 for (int j = 0; j < count; j++) {
110 switch (field->cpp_type()) {
111 #define HANDLE_TYPE(CPPTYPE, METHOD) \
112 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
113 to_reflection->Add##METHOD( \
114 to, field, from_reflection->GetRepeated##METHOD(from, field, j)); \
115 break;
116
117 HANDLE_TYPE(INT32, Int32);
118 HANDLE_TYPE(INT64, Int64);
119 HANDLE_TYPE(UINT32, UInt32);
120 HANDLE_TYPE(UINT64, UInt64);
121 HANDLE_TYPE(FLOAT, Float);
122 HANDLE_TYPE(DOUBLE, Double);
123 HANDLE_TYPE(BOOL, Bool);
124 HANDLE_TYPE(STRING, String);
125 HANDLE_TYPE(ENUM, Enum);
126 #undef HANDLE_TYPE
127
128 case FieldDescriptor::CPPTYPE_MESSAGE:
129 to_reflection->AddMessage(to, field)->MergeFrom(
130 from_reflection->GetRepeatedMessage(from, field, j));
131 break;
132 }
133 }
134 } else {
135 switch (field->cpp_type()) {
136 #define HANDLE_TYPE(CPPTYPE, METHOD) \
137 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
138 to_reflection->Set##METHOD(to, field, \
139 from_reflection->Get##METHOD(from, field)); \
140 break;
141
142 HANDLE_TYPE(INT32, Int32);
143 HANDLE_TYPE(INT64, Int64);
144 HANDLE_TYPE(UINT32, UInt32);
145 HANDLE_TYPE(UINT64, UInt64);
146 HANDLE_TYPE(FLOAT, Float);
147 HANDLE_TYPE(DOUBLE, Double);
148 HANDLE_TYPE(BOOL, Bool);
149 HANDLE_TYPE(STRING, String);
150 HANDLE_TYPE(ENUM, Enum);
151 #undef HANDLE_TYPE
152
153 case FieldDescriptor::CPPTYPE_MESSAGE:
154 to_reflection->MutableMessage(to, field)->MergeFrom(
155 from_reflection->GetMessage(from, field));
156 break;
157 }
158 }
159 }
160
161 to_reflection->MutableUnknownFields(to)->MergeFrom(
162 from_reflection->GetUnknownFields(from));
163 }
164
Clear(Message * message)165 void ReflectionOps::Clear(Message* message) {
166 const Reflection* reflection = GetReflectionOrDie(*message);
167
168 std::vector<const FieldDescriptor*> fields;
169 reflection->ListFields(*message, &fields);
170 for (int i = 0; i < fields.size(); i++) {
171 reflection->ClearField(message, fields[i]);
172 }
173
174 reflection->MutableUnknownFields(message)->Clear();
175 }
176
IsInitialized(const Message & message)177 bool ReflectionOps::IsInitialized(const Message& message) {
178 const Descriptor* descriptor = message.GetDescriptor();
179 const Reflection* reflection = GetReflectionOrDie(message);
180
181 // Check required fields of this message.
182 for (int i = 0; i < descriptor->field_count(); i++) {
183 if (descriptor->field(i)->is_required()) {
184 if (!reflection->HasField(message, descriptor->field(i))) {
185 return false;
186 }
187 }
188 }
189
190 // Check that sub-messages are initialized.
191 std::vector<const FieldDescriptor*> fields;
192 reflection->ListFields(message, &fields);
193 for (int i = 0; i < fields.size(); i++) {
194 const FieldDescriptor* field = fields[i];
195 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
196
197 if (field->is_map()) {
198 const FieldDescriptor* value_field = field->message_type()->field(1);
199 if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
200 const MapFieldBase* map_field =
201 reflection->GetMapData(message, field);
202 if (map_field->IsMapValid()) {
203 MapIterator iter(const_cast<Message*>(&message), field);
204 MapIterator end(const_cast<Message*>(&message), field);
205 for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
206 iter != end; ++iter) {
207 if (!iter.GetValueRef().GetMessageValue().IsInitialized()) {
208 return false;
209 }
210 }
211 continue;
212 }
213 } else {
214 continue;
215 }
216 }
217
218 if (field->is_repeated()) {
219 int size = reflection->FieldSize(message, field);
220
221 for (int j = 0; j < size; j++) {
222 if (!reflection->GetRepeatedMessage(message, field, j)
223 .IsInitialized()) {
224 return false;
225 }
226 }
227 } else {
228 if (!reflection->GetMessage(message, field).IsInitialized()) {
229 return false;
230 }
231 }
232 }
233 }
234
235 return true;
236 }
237
DiscardUnknownFields(Message * message)238 void ReflectionOps::DiscardUnknownFields(Message* message) {
239 const Reflection* reflection = GetReflectionOrDie(*message);
240
241 reflection->MutableUnknownFields(message)->Clear();
242
243 std::vector<const FieldDescriptor*> fields;
244 reflection->ListFields(*message, &fields);
245 for (int i = 0; i < fields.size(); i++) {
246 const FieldDescriptor* field = fields[i];
247 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
248 if (field->is_repeated()) {
249 if (field->is_map()) {
250 const FieldDescriptor* value_field = field->message_type()->field(1);
251 if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
252 const MapFieldBase* map_field =
253 reflection->MutableMapData(message, field);
254 if (map_field->IsMapValid()) {
255 MapIterator iter(message, field);
256 MapIterator end(message, field);
257 for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
258 iter != end; ++iter) {
259 iter.MutableValueRef()
260 ->MutableMessageValue()
261 ->DiscardUnknownFields();
262 }
263 continue;
264 }
265 } else {
266 continue;
267 }
268 }
269 int size = reflection->FieldSize(*message, field);
270 for (int j = 0; j < size; j++) {
271 reflection->MutableRepeatedMessage(message, field, j)
272 ->DiscardUnknownFields();
273 }
274 } else {
275 reflection->MutableMessage(message, field)->DiscardUnknownFields();
276 }
277 }
278 }
279 }
280
SubMessagePrefix(const std::string & prefix,const FieldDescriptor * field,int index)281 static std::string SubMessagePrefix(const std::string& prefix,
282 const FieldDescriptor* field, int index) {
283 std::string result(prefix);
284 if (field->is_extension()) {
285 result.append("(");
286 result.append(field->full_name());
287 result.append(")");
288 } else {
289 result.append(field->name());
290 }
291 if (index != -1) {
292 result.append("[");
293 result.append(StrCat(index));
294 result.append("]");
295 }
296 result.append(".");
297 return result;
298 }
299
FindInitializationErrors(const Message & message,const std::string & prefix,std::vector<std::string> * errors)300 void ReflectionOps::FindInitializationErrors(const Message& message,
301 const std::string& prefix,
302 std::vector<std::string>* errors) {
303 const Descriptor* descriptor = message.GetDescriptor();
304 const Reflection* reflection = GetReflectionOrDie(message);
305
306 // Check required fields of this message.
307 for (int i = 0; i < descriptor->field_count(); i++) {
308 if (descriptor->field(i)->is_required()) {
309 if (!reflection->HasField(message, descriptor->field(i))) {
310 errors->push_back(prefix + descriptor->field(i)->name());
311 }
312 }
313 }
314
315 // Check sub-messages.
316 std::vector<const FieldDescriptor*> fields;
317 reflection->ListFields(message, &fields);
318 for (int i = 0; i < fields.size(); i++) {
319 const FieldDescriptor* field = fields[i];
320 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
321
322 if (field->is_repeated()) {
323 int size = reflection->FieldSize(message, field);
324
325 for (int j = 0; j < size; j++) {
326 const Message& sub_message =
327 reflection->GetRepeatedMessage(message, field, j);
328 FindInitializationErrors(sub_message,
329 SubMessagePrefix(prefix, field, j), errors);
330 }
331 } else {
332 const Message& sub_message = reflection->GetMessage(message, field);
333 FindInitializationErrors(sub_message,
334 SubMessagePrefix(prefix, field, -1), errors);
335 }
336 }
337 }
338 }
339
340 } // namespace internal
341 } // namespace protobuf
342 } // namespace google
343