DCCL v3
protobuf_cpp_type_helpers.h
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef DCCLPROTOBUFCPPTYPEHELPERS20110323H
23 #define DCCLPROTOBUFCPPTYPEHELPERS20110323H
24 
25 #include <boost/any.hpp>
26 #include <google/protobuf/descriptor.h>
27 #include <google/protobuf/descriptor.pb.h>
28 #include <google/protobuf/message.h>
29 
30 
31 namespace dccl
32 {
33  namespace internal
34  {
37  {
38  public:
39  virtual ~FromProtoTypeBase() { }
41  virtual std::string as_str() { return "TYPE_UNKNOWN"; }
42  };
43 
44  template<google::protobuf::FieldDescriptor::Type t>
46  {
47  public:
48  std::string as_str()
49  { return google::protobuf::FieldDescriptorProto::Type_Name(static_cast<google::protobuf::FieldDescriptorProto::Type>(t)); }
50 
51  };
52 
55  {
56  public:
57  virtual ~FromProtoCppTypeBase() { }
58 
60  virtual std::string as_str() { return "CPPTYPE_UNKNOWN"; }
61 
67  boost::any get_value(const google::protobuf::FieldDescriptor* field,
68  const google::protobuf::Message& msg)
69  {
70  const google::protobuf::Reflection* refl = msg.GetReflection();
71  if(!refl->HasField(msg, field))
72  return boost::any();
73  else
74  return _get_value(field, msg);
75  }
76 
78  boost::any get_value(const google::protobuf::Message& msg)
79  {
80  return _get_value(0, msg);
81  }
82 
89  boost::any get_repeated_value(
90  const google::protobuf::FieldDescriptor* field,
91  const google::protobuf::Message& msg,
92  int index)
93  { return _get_repeated_value(field, msg, index); }
94 
95 
101  void set_value(const google::protobuf::FieldDescriptor* field,
103  boost::any value)
104  {
105  if(value.empty())
106  return;
107  else
108  _set_value(field, msg, value);
109  }
110 
113  boost::any value)
114  {
115  if(value.empty())
116  return;
117  else
118  _set_value(0, msg, value);
119  }
120 
121 
125  void add_value(const google::protobuf::FieldDescriptor* field,
127  boost::any value)
128  {
129  if(value.empty())
130  return;
131  else
132  _add_value(field, msg, value);
133  }
134 
135  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
137  boost::any value)
138  { return; }
139 
140  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
142  boost::any value)
143  { return; }
144 
145  virtual boost::any _get_repeated_value(
146  const google::protobuf::FieldDescriptor* field,
147  const google::protobuf::Message& msg,
148  int index)
149  { return boost::any(); }
150 
151  virtual boost::any _get_value(
152  const google::protobuf::FieldDescriptor* field,
153  const google::protobuf::Message& msg)
154  { return boost::any(); }
155  };
156 
157  template<google::protobuf::FieldDescriptor::CppType> class FromProtoCppType { };
158  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE>
159  : public FromProtoCppTypeBase
160  {
161  public:
162  typedef double type;
163  std::string as_str() { return "CPPTYPE_DOUBLE"; }
164  private:
165  boost::any _get_value(
166  const google::protobuf::FieldDescriptor* field,
167  const google::protobuf::Message& msg)
168  { return msg.GetReflection()->GetDouble(msg, field); }
169  boost::any _get_repeated_value(
170  const google::protobuf::FieldDescriptor* field,
171  const google::protobuf::Message& msg,
172  int index)
173  { return msg.GetReflection()->GetRepeatedDouble(msg, field, index); }
174  void _set_value(const google::protobuf::FieldDescriptor* field,
176  boost::any value)
177  { msg->GetReflection()->SetDouble(msg, field, boost::any_cast<type>(value)); }
178  void _add_value(const google::protobuf::FieldDescriptor* field,
180  boost::any value)
181  { msg->GetReflection()->AddDouble(msg, field, boost::any_cast<type>(value)); }
182  };
183 
184  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_FLOAT>
185  : public FromProtoCppTypeBase
186  {
187  public:
188  typedef float type;
189  std::string as_str() { return "CPPTYPE_FLOAT"; }
190  private:
191  boost::any _get_value(
192  const google::protobuf::FieldDescriptor* field,
193  const google::protobuf::Message& msg)
194  { return msg.GetReflection()->GetFloat(msg, field); }
195  boost::any _get_repeated_value(
196  const google::protobuf::FieldDescriptor* field,
197  const google::protobuf::Message& msg,
198  int index)
199  { return msg.GetReflection()->GetRepeatedFloat(msg, field, index); }
200  void _set_value(const google::protobuf::FieldDescriptor* field,
202  boost::any value)
203  { msg->GetReflection()->SetFloat(msg, field, boost::any_cast<type>(value)); }
204  void _add_value(const google::protobuf::FieldDescriptor* field,
206  boost::any value)
207  { msg->GetReflection()->AddFloat(msg, field, boost::any_cast<type>(value)); }
208  };
209  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_INT32>
210  : public FromProtoCppTypeBase
211  {
212  public:
213  typedef google::protobuf::int32 type;
214  std::string as_str() { return "CPPTYPE_INT32"; }
215  private:
216  boost::any _get_value(
217  const google::protobuf::FieldDescriptor* field,
218  const google::protobuf::Message& msg)
219  { return msg.GetReflection()->GetInt32(msg, field); }
220  boost::any _get_repeated_value(
221  const google::protobuf::FieldDescriptor* field,
222  const google::protobuf::Message& msg,
223  int index)
224  { return msg.GetReflection()->GetRepeatedInt32(msg, field, index); }
225  void _set_value(const google::protobuf::FieldDescriptor* field,
227  boost::any value)
228  { msg->GetReflection()->SetInt32(msg, field, boost::any_cast<type>(value)); }
229  void _add_value(const google::protobuf::FieldDescriptor* field,
231  boost::any value)
232  { msg->GetReflection()->AddInt32(msg, field, boost::any_cast<type>(value)); }
233  };
234  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_INT64>
235  : public FromProtoCppTypeBase
236  {
237  public:
238  typedef google::protobuf::int64 type;
239  std::string as_str() { return "CPPTYPE_INT64"; }
240  private:
241  boost::any _get_value(
242  const google::protobuf::FieldDescriptor* field,
243  const google::protobuf::Message& msg)
244  { return msg.GetReflection()->GetInt64(msg, field); }
245  boost::any _get_repeated_value(
246  const google::protobuf::FieldDescriptor* field,
247  const google::protobuf::Message& msg,
248  int index)
249  { return msg.GetReflection()->GetRepeatedInt64(msg, field, index); }
250  void _set_value(const google::protobuf::FieldDescriptor* field,
252  boost::any value)
253  { msg->GetReflection()->SetInt64(msg, field, boost::any_cast<type>(value)); }
254  void _add_value(const google::protobuf::FieldDescriptor* field,
256  boost::any value)
257  { msg->GetReflection()->AddInt64(msg, field, boost::any_cast<type>(value)); }
258  };
259  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_UINT32>
260  : public FromProtoCppTypeBase
261  {
262  public:
263  typedef google::protobuf::uint32 type;
264  std::string as_str() { return "CPPTYPE_UINT32"; }
265  private:
266  boost::any _get_value(
267  const google::protobuf::FieldDescriptor* field,
268  const google::protobuf::Message& msg)
269  { return msg.GetReflection()->GetUInt32(msg, field); }
270  boost::any _get_repeated_value(
271  const google::protobuf::FieldDescriptor* field,
272  const google::protobuf::Message& msg,
273  int index)
274  { return msg.GetReflection()->GetRepeatedUInt32(msg, field, index); }
275  void _set_value(const google::protobuf::FieldDescriptor* field,
277  boost::any value)
278  { msg->GetReflection()->SetUInt32(msg, field, boost::any_cast<type>(value)); }
279  void _add_value(const google::protobuf::FieldDescriptor* field,
281  boost::any value)
282  { msg->GetReflection()->AddUInt32(msg, field, boost::any_cast<type>(value)); }
283  };
284  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_UINT64>
285  : public FromProtoCppTypeBase
286  {
287  public:
288  typedef google::protobuf::uint64 type;
289 
290  std::string as_str() { return "CPPTYPE_UINT64"; }
291  private:
292  boost::any _get_value(
293  const google::protobuf::FieldDescriptor* field,
294  const google::protobuf::Message& msg)
295  { return msg.GetReflection()->GetUInt64(msg, field); }
296  boost::any _get_repeated_value(
297  const google::protobuf::FieldDescriptor* field,
298  const google::protobuf::Message& msg,
299  int index)
300  { return msg.GetReflection()->GetRepeatedUInt64(msg, field, index); }
301  void _set_value(const google::protobuf::FieldDescriptor* field,
303  boost::any value)
304  { msg->GetReflection()->SetUInt64(msg, field, boost::any_cast<type>(value)); }
305  void _add_value(const google::protobuf::FieldDescriptor* field,
307  boost::any value)
308  { msg->GetReflection()->AddUInt64(msg, field, boost::any_cast<type>(value)); }
309  };
310  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_BOOL>
311  : public FromProtoCppTypeBase
312  {
313  public:
314  typedef bool type;
315  std::string as_str() { return "CPPTYPE_BOOL"; }
316  private:
317  boost::any _get_value(
318  const google::protobuf::FieldDescriptor* field,
319  const google::protobuf::Message& msg)
320  { return msg.GetReflection()->GetBool(msg, field); }
321  boost::any _get_repeated_value(
322  const google::protobuf::FieldDescriptor* field,
323  const google::protobuf::Message& msg,
324  int index)
325  { return msg.GetReflection()->GetRepeatedBool(msg, field, index); }
326  void _set_value(const google::protobuf::FieldDescriptor* field,
328  boost::any value)
329  { msg->GetReflection()->SetBool(msg, field, boost::any_cast<type>(value)); }
330  void _add_value(const google::protobuf::FieldDescriptor* field,
332  boost::any value)
333  { msg->GetReflection()->AddBool(msg, field, boost::any_cast<type>(value)); }
334  };
335  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_STRING>
336  : public FromProtoCppTypeBase
337  {
338  public:
339  typedef std::string type;
340  std::string as_str() { return "CPPTYPE_STRING"; }
341  private:
342  boost::any _get_value(
343  const google::protobuf::FieldDescriptor* field,
344  const google::protobuf::Message& msg)
345  { return msg.GetReflection()->GetString(msg, field); }
346  boost::any _get_repeated_value(
347  const google::protobuf::FieldDescriptor* field,
348  const google::protobuf::Message& msg,
349  int index)
350  { return msg.GetReflection()->GetRepeatedString(msg, field, index); }
351  void _set_value(const google::protobuf::FieldDescriptor* field,
353  boost::any value)
354  { msg->GetReflection()->SetString(msg, field, boost::any_cast<type>(value)); }
355  void _add_value(const google::protobuf::FieldDescriptor* field,
357  boost::any value)
358  { msg->GetReflection()->AddString(msg, field, boost::any_cast<type>(value)); }
359  };
360 
361  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_ENUM>
362  : public FromProtoCppTypeBase
363  {
364  public:
365  typedef const google::protobuf::EnumValueDescriptor* const_type;
366  typedef google::protobuf::EnumValueDescriptor* mutable_type;
367 
368  std::string as_str() { return "CPPTYPE_ENUM"; }
369  private:
370  boost::any _get_value(
371  const google::protobuf::FieldDescriptor* field,
372  const google::protobuf::Message& msg)
373  { return msg.GetReflection()->GetEnum(msg, field); }
374  boost::any _get_repeated_value(
375  const google::protobuf::FieldDescriptor* field,
376  const google::protobuf::Message& msg,
377  int index)
378  { return msg.GetReflection()->GetRepeatedEnum(msg, field, index); }
379  void _set_value(const google::protobuf::FieldDescriptor* field,
381  boost::any value)
382  { msg->GetReflection()->SetEnum(msg, field, boost::any_cast<const_type>(value)); }
383  void _add_value(const google::protobuf::FieldDescriptor* field,
385  boost::any value)
386  { msg->GetReflection()->AddEnum(msg, field, boost::any_cast<const_type>(value)); }
387 
388  };
389 
390 
392  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE>
393  : public FromProtoCppTypeBase
394  {
395  public:
396  typedef const google::protobuf::Message* const_type;
397  typedef google::protobuf::Message* mutable_type;
398  std::string as_str() { return "CPPTYPE_MESSAGE"; }
399 
400  protected:
401  virtual boost::any _get_value(
402  const google::protobuf::FieldDescriptor* field,
403  const google::protobuf::Message& msg)
404  {
405  if(field)
406  return &(msg.GetReflection()->GetMessage(msg, field));
407  else
408  return &msg;
409  }
410 
411  virtual boost::any _get_repeated_value(
412  const google::protobuf::FieldDescriptor* field,
413  const google::protobuf::Message& msg,
414  int index)
415  { return &(msg.GetReflection()->GetRepeatedMessage(msg, field, index)); }
416 
417 
418  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
420  boost::any value)
421  {
422  try
423  {
424  const_type p = boost::any_cast<const_type>(value);
425 
426  if(field)
427  msg->GetReflection()->MutableMessage(msg, field)->MergeFrom(*p);
428  else
429  msg->MergeFrom(*p);
430 
431  }
432  catch(boost::bad_any_cast& e)
433  {
434  mutable_type p = boost::any_cast<mutable_type>(value);
435  if(field)
436  msg->GetReflection()->MutableMessage(msg, field)->MergeFrom(*p);
437  else
438  msg->MergeFrom(*p);
439  }
440 
441  }
442  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
444  boost::any value)
445  {
446  try
447  {
448  const_type p = boost::any_cast<const_type>(value);
449  msg->GetReflection()->AddMessage(msg, field)->MergeFrom(*p);
450  }
451  catch(boost::bad_any_cast& e)
452  {
453  mutable_type p = boost::any_cast<mutable_type>(value);
454  msg->GetReflection()->AddMessage(msg, field)->MergeFrom(*p);
455  }
456  }
457 
458  };
459 
461  template<typename CustomMessage>
462  class FromProtoCustomMessage : public FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE>
463  {
464  public:
465  typedef CustomMessage type;
466 
467  private:
469 
470  virtual boost::any _get_value(
471  const google::protobuf::FieldDescriptor* field,
472  const google::protobuf::Message& msg)
473  {
474  Parent::const_type p = boost::any_cast<Parent::const_type>(Parent::_get_value(field, msg));
475  type r;
476  r.CopyFrom(*p);
477  return r;
478 // return dynamic_cast<const_type>(*p);
479  }
480  virtual boost::any _get_repeated_value(
481  const google::protobuf::FieldDescriptor* field,
482  const google::protobuf::Message& msg,
483  int index)
484  {
485  Parent::const_type p = boost::any_cast<Parent::const_type>(Parent::_get_repeated_value(field, msg, index));
486  type r;
487  r.CopyFrom(*p);
488  return r;
489 // return dynamic_cast<const_type>(*p);
490  }
491  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
493  boost::any value)
494  {
495  type v = boost::any_cast<type>(value);
496  Parent::const_type p = &v;
497  Parent::_set_value(field, msg, p);
498  }
499  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
501  boost::any value)
502  {
503  type v = boost::any_cast<type>(value);
504  Parent::const_type p = &v;
505  Parent::_add_value(field, msg, p);
506  }
507  };
508 
509 
510  template<typename T>
512  { };
513  template<>
514  class ToProtoCppType<double>
515  {
516  public:
517  static google::protobuf::FieldDescriptor::CppType as_enum()
518  { return google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE; }
519  };
520  template<>
521  class ToProtoCppType<float>
522  {
523  public:
524  static google::protobuf::FieldDescriptor::CppType as_enum()
525  { return google::protobuf::FieldDescriptor::CPPTYPE_FLOAT; }
526  };
527  template<>
528  class ToProtoCppType<google::protobuf::int32>
529  {
530  public:
531  static google::protobuf::FieldDescriptor::CppType as_enum()
532  { return google::protobuf::FieldDescriptor::CPPTYPE_INT32; }
533  };
534  template<>
535  class ToProtoCppType<google::protobuf::uint32>
536  {
537  public:
538  static google::protobuf::FieldDescriptor::CppType as_enum()
539  { return google::protobuf::FieldDescriptor::CPPTYPE_UINT32; }
540  };
541  template<>
542  class ToProtoCppType<google::protobuf::int64>
543  {
544  public:
545  static google::protobuf::FieldDescriptor::CppType as_enum()
546  { return google::protobuf::FieldDescriptor::CPPTYPE_INT64; }
547  };
548  template<>
549  class ToProtoCppType<google::protobuf::uint64>
550  {
551  public:
552  static google::protobuf::FieldDescriptor::CppType as_enum()
553  { return google::protobuf::FieldDescriptor::CPPTYPE_UINT64; }
554  };
555  template<>
556  class ToProtoCppType<std::string>
557  {
558  public:
559  static google::protobuf::FieldDescriptor::CppType as_enum()
560  { return google::protobuf::FieldDescriptor::CPPTYPE_STRING; }
561  };
562  template<>
563  class ToProtoCppType<const google::protobuf::EnumValueDescriptor*>
564  {
565  public:
566  static google::protobuf::FieldDescriptor::CppType as_enum()
567  { return google::protobuf::FieldDescriptor::CPPTYPE_ENUM; }
568  };
569 
570  template<>
572  {
573  public:
574  static google::protobuf::FieldDescriptor::CppType as_enum()
575  { return google::protobuf::FieldDescriptor::CPPTYPE_BOOL; }
576  };
577 
578  template<>
579  class ToProtoCppType<google::protobuf::Message>
580  {
581  public:
582  static google::protobuf::FieldDescriptor::CppType as_enum()
583  { return google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE; }
584  };
585  }
586 }
587 
588 
589 
590 
591 
592 
593 
594 
595 
596 
597 
598 
599 #endif
boost::any get_repeated_value(const google::protobuf::FieldDescriptor *field, const google::protobuf::Message &msg, int index)
Get the value of a repeated field at a given index.
STL namespace.
void add_value(const google::protobuf::FieldDescriptor *field, google::protobuf::Message *msg, boost::any value)
Add a new entry for a repeated field to the back.
void set_value(google::protobuf::Message *msg, boost::any value)
Set the value of the entire base message (only works for CPPTYPE_MESSAGE)
Provides various representations of a google::protobuf::FieldDescriptor::CppType enumeration, and ways to access the google::protobuf::Reflection object for a given type.
Provides various representations of a google::protobuf::FieldDescriptor::Type enumeration. Implementations are provided for all enumerations.
Implements FromProtoCppTypeBase for CPPTYPE_MESSAGE using the dynamic google::protobuf::Message as th...
virtual std::string as_str()
string representation
void set_value(const google::protobuf::FieldDescriptor *field, google::protobuf::Message *msg, boost::any value)
Set a given field&#39;s value in the provided message.
boost::any get_value(const google::protobuf::Message &msg)
Get the value of the entire base message (only works for CPPTYPE_MESSAGE)
virtual std::string as_str()
string representation of the google::protobuf::FieldDescriptor::Type.
Dynamic Compact Control Language namespace.
boost::any get_value(const google::protobuf::FieldDescriptor *field, const google::protobuf::Message &msg)
Get a given field&#39;s value from the provided message.
std::string as_str()
string representation of the google::protobuf::FieldDescriptor::Type.
Implements FromProtoCppTypeBase for CPPTYPE_MESSAGE using a specific statically generated Protobuf cl...