Line data Source code
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 :
35 : #include <iostream>
36 : #include <stack>
37 : #include <google/protobuf/stubs/hash.h>
38 :
39 : #include <google/protobuf/message.h>
40 :
41 : #include <google/protobuf/stubs/logging.h>
42 : #include <google/protobuf/stubs/common.h>
43 : #include <google/protobuf/stubs/mutex.h>
44 : #include <google/protobuf/stubs/once.h>
45 : #include <google/protobuf/reflection_internal.h>
46 : #include <google/protobuf/io/coded_stream.h>
47 : #include <google/protobuf/io/zero_copy_stream_impl.h>
48 : #include <google/protobuf/descriptor.pb.h>
49 : #include <google/protobuf/map_field.h>
50 : #include <google/protobuf/descriptor.h>
51 : #include <google/protobuf/generated_message_util.h>
52 : #include <google/protobuf/reflection_ops.h>
53 : #include <google/protobuf/wire_format.h>
54 : #include <google/protobuf/stubs/strutil.h>
55 : #include <google/protobuf/stubs/map_util.h>
56 : #include <google/protobuf/stubs/singleton.h>
57 : #include <google/protobuf/stubs/stl_util.h>
58 : #include <google/protobuf/stubs/port.h>
59 :
60 : namespace google {
61 : namespace protobuf {
62 :
63 : using internal::WireFormat;
64 : using internal::ReflectionOps;
65 :
66 7687541 : Message::~Message() {}
67 :
68 0 : void Message::MergeFrom(const Message& from) {
69 0 : const Descriptor* descriptor = GetDescriptor();
70 0 : GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
71 : << ": Tried to merge from a message with a different type. "
72 0 : "to: " << descriptor->full_name() << ", "
73 0 : "from:" << from.GetDescriptor()->full_name();
74 0 : ReflectionOps::Merge(from, this);
75 0 : }
76 :
77 0 : void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
78 0 : MergeFrom(*down_cast<const Message*>(&other));
79 0 : }
80 :
81 0 : void Message::CopyFrom(const Message& from) {
82 0 : const Descriptor* descriptor = GetDescriptor();
83 0 : GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
84 : << ": Tried to copy from a message with a different type. "
85 0 : "to: " << descriptor->full_name() << ", "
86 0 : "from:" << from.GetDescriptor()->full_name();
87 0 : ReflectionOps::Copy(from, this);
88 0 : }
89 :
90 0 : string Message::GetTypeName() const {
91 0 : return GetDescriptor()->full_name();
92 : }
93 :
94 9 : void Message::Clear() {
95 9 : ReflectionOps::Clear(this);
96 9 : }
97 :
98 14 : bool Message::IsInitialized() const {
99 14 : return ReflectionOps::IsInitialized(*this);
100 : }
101 :
102 0 : void Message::FindInitializationErrors(vector<string>* errors) const {
103 0 : return ReflectionOps::FindInitializationErrors(*this, "", errors);
104 : }
105 :
106 0 : string Message::InitializationErrorString() const {
107 : vector<string> errors;
108 0 : FindInitializationErrors(&errors);
109 0 : return Join(errors, ", ");
110 : }
111 :
112 0 : void Message::CheckInitialized() const {
113 0 : GOOGLE_CHECK(IsInitialized())
114 0 : << "Message of type \"" << GetDescriptor()->full_name()
115 0 : << "\" is missing required fields: " << InitializationErrorString();
116 0 : }
117 :
118 0 : void Message::DiscardUnknownFields() {
119 0 : return ReflectionOps::DiscardUnknownFields(this);
120 : }
121 :
122 0 : bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
123 0 : return WireFormat::ParseAndMergePartial(input, this);
124 : }
125 :
126 8 : bool Message::ParseFromFileDescriptor(int file_descriptor) {
127 8 : io::FileInputStream input(file_descriptor);
128 16 : return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
129 : }
130 :
131 0 : bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
132 0 : io::FileInputStream input(file_descriptor);
133 0 : return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
134 : }
135 :
136 0 : bool Message::ParseFromIstream(istream* input) {
137 0 : io::IstreamInputStream zero_copy_input(input);
138 0 : return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
139 : }
140 :
141 0 : bool Message::ParsePartialFromIstream(istream* input) {
142 0 : io::IstreamInputStream zero_copy_input(input);
143 0 : return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
144 : }
145 :
146 :
147 14 : void Message::SerializeWithCachedSizes(
148 : io::CodedOutputStream* output) const {
149 14 : WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
150 14 : }
151 :
152 14 : int Message::ByteSize() const {
153 14 : int size = WireFormat::ByteSize(*this);
154 14 : SetCachedSize(size);
155 14 : return size;
156 : }
157 :
158 0 : void Message::SetCachedSize(int /* size */) const {
159 0 : GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
160 : << "\" implements neither SetCachedSize() nor ByteSize(). "
161 0 : "Must implement one or the other.";
162 0 : }
163 :
164 0 : int Message::SpaceUsed() const {
165 0 : return GetReflection()->SpaceUsed(*this);
166 : }
167 :
168 8 : bool Message::SerializeToFileDescriptor(int file_descriptor) const {
169 8 : io::FileOutputStream output(file_descriptor);
170 8 : return SerializeToZeroCopyStream(&output);
171 : }
172 :
173 0 : bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
174 0 : io::FileOutputStream output(file_descriptor);
175 0 : return SerializePartialToZeroCopyStream(&output);
176 : }
177 :
178 0 : bool Message::SerializeToOstream(ostream* output) const {
179 : {
180 0 : io::OstreamOutputStream zero_copy_output(output);
181 0 : if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
182 : }
183 0 : return output->good();
184 : }
185 :
186 0 : bool Message::SerializePartialToOstream(ostream* output) const {
187 0 : io::OstreamOutputStream zero_copy_output(output);
188 0 : return SerializePartialToZeroCopyStream(&zero_copy_output);
189 : }
190 :
191 :
192 : // =============================================================================
193 : // Reflection and associated Template Specializations
194 :
195 5 : Reflection::~Reflection() {}
196 :
197 : #define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE) \
198 : template<> \
199 : const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
200 : const Message& message, const FieldDescriptor* field) const { \
201 : return *static_cast<RepeatedField<TYPE>* >( \
202 : MutableRawRepeatedField(const_cast<Message*>(&message), \
203 : field, CPPTYPE, CTYPE, NULL)); \
204 : } \
205 : \
206 : template<> \
207 : RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
208 : Message* message, const FieldDescriptor* field) const { \
209 : return static_cast<RepeatedField<TYPE>* >( \
210 : MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
211 : }
212 :
213 0 : HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
214 0 : HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
215 0 : HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
216 0 : HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
217 0 : HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
218 0 : HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
219 0 : HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
220 :
221 :
222 : #undef HANDLE_TYPE
223 :
224 0 : void* Reflection::MutableRawRepeatedString(
225 : Message* message, const FieldDescriptor* field, bool is_string) const {
226 : return MutableRawRepeatedField(message, field,
227 0 : FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL);
228 : }
229 :
230 :
231 : // Default EnumValue API implementations. Real reflection implementations should
232 : // override these. However, there are several legacy implementations that do
233 : // not, and cannot easily be changed at the same time as the Reflection API, so
234 : // we provide these for now.
235 : // TODO: Remove these once all Reflection implementations are updated.
236 0 : int Reflection::GetEnumValue(const Message& message,
237 : const FieldDescriptor* field) const {
238 0 : GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
239 0 : return 0;
240 : }
241 0 : void Reflection::SetEnumValue(Message* message,
242 : const FieldDescriptor* field,
243 : int value) const {
244 0 : GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
245 0 : }
246 0 : int Reflection::GetRepeatedEnumValue(
247 : const Message& message,
248 : const FieldDescriptor* field, int index) const {
249 0 : GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
250 0 : return 0;
251 : }
252 0 : void Reflection::SetRepeatedEnumValue(Message* message,
253 : const FieldDescriptor* field, int index,
254 : int value) const {
255 0 : GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
256 0 : }
257 0 : void Reflection::AddEnumValue(Message* message,
258 : const FieldDescriptor* field,
259 : int value) const {
260 0 : GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
261 0 : }
262 :
263 0 : MapIterator Reflection::MapBegin(
264 : Message* message,
265 : const FieldDescriptor* field) const {
266 0 : GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
267 0 : MapIterator iter(message, field);
268 0 : return iter;
269 : }
270 :
271 0 : MapIterator Reflection::MapEnd(
272 : Message* message,
273 : const FieldDescriptor* field) const {
274 0 : GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
275 0 : MapIterator iter(message, field);
276 0 : return iter;
277 : }
278 :
279 : // =============================================================================
280 : // MessageFactory
281 :
282 96 : MessageFactory::~MessageFactory() {}
283 :
284 : namespace {
285 :
286 : class GeneratedMessageFactory : public MessageFactory {
287 : public:
288 : GeneratedMessageFactory();
289 : ~GeneratedMessageFactory();
290 :
291 : static GeneratedMessageFactory* singleton();
292 :
293 : typedef void RegistrationFunc(const string&);
294 : void RegisterFile(const char* file, RegistrationFunc* registration_func);
295 : void RegisterType(const Descriptor* descriptor, const Message* prototype);
296 :
297 : // implements MessageFactory ---------------------------------------
298 : const Message* GetPrototype(const Descriptor* type);
299 :
300 : private:
301 : // Only written at static init time, so does not require locking.
302 : hash_map<const char*, RegistrationFunc*,
303 : hash<const char*>, streq> file_map_;
304 :
305 : // Initialized lazily, so requires locking.
306 : Mutex mutex_;
307 : hash_map<const Descriptor*, const Message*> type_map_;
308 : };
309 :
310 : GeneratedMessageFactory* generated_message_factory_ = NULL;
311 : GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);
312 :
313 0 : void ShutdownGeneratedMessageFactory() {
314 0 : delete generated_message_factory_;
315 0 : }
316 :
317 46 : void InitGeneratedMessageFactory() {
318 46 : generated_message_factory_ = new GeneratedMessageFactory;
319 46 : internal::OnShutdown(&ShutdownGeneratedMessageFactory);
320 46 : }
321 :
322 184 : GeneratedMessageFactory::GeneratedMessageFactory() {}
323 0 : GeneratedMessageFactory::~GeneratedMessageFactory() {}
324 :
325 : GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
326 : ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
327 235 : &InitGeneratedMessageFactory);
328 235 : return generated_message_factory_;
329 : }
330 :
331 103 : void GeneratedMessageFactory::RegisterFile(
332 : const char* file, RegistrationFunc* registration_func) {
333 103 : if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
334 0 : GOOGLE_LOG(FATAL) << "File is already registered: " << file;
335 : }
336 103 : }
337 :
338 22 : void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
339 : const Message* prototype) {
340 0 : GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
341 : << "Tried to register a non-generated type with the generated "
342 : "type registry.";
343 :
344 : // This should only be called as a result of calling a file registration
345 : // function during GetPrototype(), in which case we already have locked
346 : // the mutex.
347 22 : mutex_.AssertHeld();
348 44 : if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
349 0 : GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
350 : }
351 22 : }
352 :
353 :
354 274 : const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
355 : {
356 274 : ReaderMutexLock lock(&mutex_);
357 274 : const Message* result = FindPtrOrNull(type_map_, type);
358 274 : if (result != NULL) return result;
359 : }
360 :
361 : // If the type is not in the generated pool, then we can't possibly handle
362 : // it.
363 2 : if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
364 :
365 : // Apparently the file hasn't been registered yet. Let's do that now.
366 : RegistrationFunc* registration_func =
367 2 : FindPtrOrNull(file_map_, type->file()->name().c_str());
368 1 : if (registration_func == NULL) {
369 0 : GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
370 0 : "registered: " << type->file()->name();
371 0 : return NULL;
372 : }
373 :
374 1 : WriterMutexLock lock(&mutex_);
375 :
376 : // Check if another thread preempted us.
377 1 : const Message* result = FindPtrOrNull(type_map_, type);
378 1 : if (result == NULL) {
379 : // Nope. OK, register everything.
380 1 : registration_func(type->file()->name());
381 : // Should be here now.
382 1 : result = FindPtrOrNull(type_map_, type);
383 : }
384 :
385 1 : if (result == NULL) {
386 0 : GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
387 0 : << "registered: " << type->full_name();
388 : }
389 :
390 1 : return result;
391 : }
392 :
393 : } // namespace
394 :
395 110 : MessageFactory* MessageFactory::generated_factory() {
396 110 : return GeneratedMessageFactory::singleton();
397 : }
398 :
399 103 : void MessageFactory::InternalRegisterGeneratedFile(
400 : const char* filename, void (*register_messages)(const string&)) {
401 : GeneratedMessageFactory::singleton()->RegisterFile(filename,
402 103 : register_messages);
403 103 : }
404 :
405 22 : void MessageFactory::InternalRegisterGeneratedMessage(
406 : const Descriptor* descriptor, const Message* prototype) {
407 22 : GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
408 22 : }
409 :
410 :
411 0 : MessageFactory* Reflection::GetMessageFactory() const {
412 0 : GOOGLE_LOG(FATAL) << "Not implemented.";
413 0 : return NULL;
414 : }
415 :
416 0 : void* Reflection::RepeatedFieldData(
417 : Message* message, const FieldDescriptor* field,
418 : FieldDescriptor::CppType cpp_type,
419 : const Descriptor* message_type) const {
420 0 : GOOGLE_LOG(FATAL) << "Not implemented.";
421 0 : return NULL;
422 : }
423 :
424 : namespace internal {
425 0 : RepeatedFieldAccessor::~RepeatedFieldAccessor() {
426 0 : }
427 : } // namespace internal
428 :
429 0 : const internal::RepeatedFieldAccessor* Reflection::RepeatedFieldAccessor(
430 0 : const FieldDescriptor* field) const {
431 0 : GOOGLE_CHECK(field->is_repeated());
432 0 : switch (field->cpp_type()) {
433 : #define HANDLE_PRIMITIVE_TYPE(TYPE, type) \
434 : case FieldDescriptor::CPPTYPE_ ## TYPE: \
435 : return internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<type> >::get();
436 0 : HANDLE_PRIMITIVE_TYPE(INT32, int32)
437 0 : HANDLE_PRIMITIVE_TYPE(UINT32, uint32)
438 0 : HANDLE_PRIMITIVE_TYPE(INT64, int64)
439 0 : HANDLE_PRIMITIVE_TYPE(UINT64, uint64)
440 0 : HANDLE_PRIMITIVE_TYPE(FLOAT, float)
441 0 : HANDLE_PRIMITIVE_TYPE(DOUBLE, double)
442 0 : HANDLE_PRIMITIVE_TYPE(BOOL, bool)
443 0 : HANDLE_PRIMITIVE_TYPE(ENUM, int32)
444 : #undef HANDLE_PRIMITIVE_TYPE
445 : case FieldDescriptor::CPPTYPE_STRING:
446 0 : switch (field->options().ctype()) {
447 : default:
448 : case FieldOptions::STRING:
449 0 : return internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::get();
450 : }
451 : break;
452 : case FieldDescriptor::CPPTYPE_MESSAGE:
453 0 : if (field->is_map()) {
454 0 : return internal::Singleton<internal::MapFieldAccessor>::get();
455 : } else {
456 0 : return internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::get();
457 : }
458 : }
459 0 : GOOGLE_LOG(FATAL) << "Should not reach here.";
460 0 : return NULL;
461 : }
462 :
463 : namespace internal {
464 : namespace {
465 0 : void ShutdownRepeatedFieldAccessor() {
466 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int32> >::ShutDown();
467 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint32> >::ShutDown();
468 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<int64> >::ShutDown();
469 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<uint64> >::ShutDown();
470 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<float> >::ShutDown();
471 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<double> >::ShutDown();
472 : internal::Singleton<internal::RepeatedFieldPrimitiveAccessor<bool> >::ShutDown();
473 : internal::Singleton<internal::RepeatedPtrFieldStringAccessor>::ShutDown();
474 : internal::Singleton<internal::RepeatedPtrFieldMessageAccessor>::ShutDown();
475 : internal::Singleton<internal::MapFieldAccessor>::ShutDown();
476 0 : }
477 :
478 : struct ShutdownRepeatedFieldRegister {
479 : ShutdownRepeatedFieldRegister() {
480 46 : OnShutdown(&ShutdownRepeatedFieldAccessor);
481 : }
482 : } shutdown_;
483 :
484 : } // namespace
485 : } // namespace internal
486 :
487 : namespace internal {
488 : template<>
489 : #if defined(_MSC_VER) && (_MSC_VER >= 1900)
490 : // Note: force noinline to workaround MSVC 2015 compiler bug, issue #240
491 : GOOGLE_ATTRIBUTE_NOINLINE
492 : #endif
493 0 : Message* GenericTypeHandler<Message>::NewFromPrototype(
494 : const Message* prototype, google::protobuf::Arena* arena) {
495 0 : return prototype->New(arena);
496 : }
497 : template<>
498 0 : google::protobuf::Arena* GenericTypeHandler<Message>::GetArena(
499 : Message* value) {
500 0 : return value->GetArena();
501 : }
502 : template<>
503 0 : void* GenericTypeHandler<Message>::GetMaybeArenaPointer(
504 : Message* value) {
505 0 : return value->GetMaybeArenaPointer();
506 : }
507 : } // namespace internal
508 :
509 : } // namespace protobuf
510 138 : } // namespace google
|