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