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 
126  void add_value(const google::protobuf::FieldDescriptor* field,
128  boost::any value)
129  {
130  if(value.empty())
131  return;
132  else
133  _add_value(field, msg, value);
134  }
135 
136  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
138  boost::any value)
139  { return; }
140 
141  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
143  boost::any value)
144  { return; }
145 
146  virtual boost::any _get_repeated_value(
147  const google::protobuf::FieldDescriptor* field,
148  const google::protobuf::Message& msg,
149  int index)
150  { return boost::any(); }
151 
152  virtual boost::any _get_value(
153  const google::protobuf::FieldDescriptor* field,
154  const google::protobuf::Message& msg)
155  { return boost::any(); }
156  };
157 
158  template<google::protobuf::FieldDescriptor::CppType> class FromProtoCppType { };
159  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE>
160  : public FromProtoCppTypeBase
161  {
162  public:
163  typedef double type;
164  std::string as_str() { return "CPPTYPE_DOUBLE"; }
165  private:
166  boost::any _get_value(
167  const google::protobuf::FieldDescriptor* field,
168  const google::protobuf::Message& msg)
169  { return msg.GetReflection()->GetDouble(msg, field); }
170  boost::any _get_repeated_value(
171  const google::protobuf::FieldDescriptor* field,
172  const google::protobuf::Message& msg,
173  int index)
174  { return msg.GetReflection()->GetRepeatedDouble(msg, field, index); }
175  void _set_value(const google::protobuf::FieldDescriptor* field,
177  boost::any value)
178  { msg->GetReflection()->SetDouble(msg, field, boost::any_cast<type>(value)); }
179  void _add_value(const google::protobuf::FieldDescriptor* field,
181  boost::any value)
182  { msg->GetReflection()->AddDouble(msg, field, boost::any_cast<type>(value)); }
183  };
184 
185  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_FLOAT>
186  : public FromProtoCppTypeBase
187  {
188  public:
189  typedef float type;
190  std::string as_str() { return "CPPTYPE_FLOAT"; }
191  private:
192  boost::any _get_value(
193  const google::protobuf::FieldDescriptor* field,
194  const google::protobuf::Message& msg)
195  { return msg.GetReflection()->GetFloat(msg, field); }
196  boost::any _get_repeated_value(
197  const google::protobuf::FieldDescriptor* field,
198  const google::protobuf::Message& msg,
199  int index)
200  { return msg.GetReflection()->GetRepeatedFloat(msg, field, index); }
201  void _set_value(const google::protobuf::FieldDescriptor* field,
203  boost::any value)
204  { msg->GetReflection()->SetFloat(msg, field, boost::any_cast<type>(value)); }
205  void _add_value(const google::protobuf::FieldDescriptor* field,
207  boost::any value)
208  { msg->GetReflection()->AddFloat(msg, field, boost::any_cast<type>(value)); }
209  };
210  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_INT32>
211  : public FromProtoCppTypeBase
212  {
213  public:
214  typedef google::protobuf::int32 type;
215  std::string as_str() { return "CPPTYPE_INT32"; }
216  private:
217  boost::any _get_value(
218  const google::protobuf::FieldDescriptor* field,
219  const google::protobuf::Message& msg)
220  { return msg.GetReflection()->GetInt32(msg, field); }
221  boost::any _get_repeated_value(
222  const google::protobuf::FieldDescriptor* field,
223  const google::protobuf::Message& msg,
224  int index)
225  { return msg.GetReflection()->GetRepeatedInt32(msg, field, index); }
226  void _set_value(const google::protobuf::FieldDescriptor* field,
228  boost::any value)
229  { msg->GetReflection()->SetInt32(msg, field, boost::any_cast<type>(value)); }
230  void _add_value(const google::protobuf::FieldDescriptor* field,
232  boost::any value)
233  { msg->GetReflection()->AddInt32(msg, field, boost::any_cast<type>(value)); }
234  };
235  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_INT64>
236  : public FromProtoCppTypeBase
237  {
238  public:
239  typedef google::protobuf::int64 type;
240  std::string as_str() { return "CPPTYPE_INT64"; }
241  private:
242  boost::any _get_value(
243  const google::protobuf::FieldDescriptor* field,
244  const google::protobuf::Message& msg)
245  { return msg.GetReflection()->GetInt64(msg, field); }
246  boost::any _get_repeated_value(
247  const google::protobuf::FieldDescriptor* field,
248  const google::protobuf::Message& msg,
249  int index)
250  { return msg.GetReflection()->GetRepeatedInt64(msg, field, index); }
251  void _set_value(const google::protobuf::FieldDescriptor* field,
253  boost::any value)
254  { msg->GetReflection()->SetInt64(msg, field, boost::any_cast<type>(value)); }
255  void _add_value(const google::protobuf::FieldDescriptor* field,
257  boost::any value)
258  { msg->GetReflection()->AddInt64(msg, field, boost::any_cast<type>(value)); }
259  };
260  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_UINT32>
261  : public FromProtoCppTypeBase
262  {
263  public:
264  typedef google::protobuf::uint32 type;
265  std::string as_str() { return "CPPTYPE_UINT32"; }
266  private:
267  boost::any _get_value(
268  const google::protobuf::FieldDescriptor* field,
269  const google::protobuf::Message& msg)
270  { return msg.GetReflection()->GetUInt32(msg, field); }
271  boost::any _get_repeated_value(
272  const google::protobuf::FieldDescriptor* field,
273  const google::protobuf::Message& msg,
274  int index)
275  { return msg.GetReflection()->GetRepeatedUInt32(msg, field, index); }
276  void _set_value(const google::protobuf::FieldDescriptor* field,
278  boost::any value)
279  { msg->GetReflection()->SetUInt32(msg, field, boost::any_cast<type>(value)); }
280  void _add_value(const google::protobuf::FieldDescriptor* field,
282  boost::any value)
283  { msg->GetReflection()->AddUInt32(msg, field, boost::any_cast<type>(value)); }
284  };
285  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_UINT64>
286  : public FromProtoCppTypeBase
287  {
288  public:
289  typedef google::protobuf::uint64 type;
290 
291  std::string as_str() { return "CPPTYPE_UINT64"; }
292  private:
293  boost::any _get_value(
294  const google::protobuf::FieldDescriptor* field,
295  const google::protobuf::Message& msg)
296  { return msg.GetReflection()->GetUInt64(msg, field); }
297  boost::any _get_repeated_value(
298  const google::protobuf::FieldDescriptor* field,
299  const google::protobuf::Message& msg,
300  int index)
301  { return msg.GetReflection()->GetRepeatedUInt64(msg, field, index); }
302  void _set_value(const google::protobuf::FieldDescriptor* field,
304  boost::any value)
305  { msg->GetReflection()->SetUInt64(msg, field, boost::any_cast<type>(value)); }
306  void _add_value(const google::protobuf::FieldDescriptor* field,
308  boost::any value)
309  { msg->GetReflection()->AddUInt64(msg, field, boost::any_cast<type>(value)); }
310  };
311  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_BOOL>
312  : public FromProtoCppTypeBase
313  {
314  public:
315  typedef bool type;
316  std::string as_str() { return "CPPTYPE_BOOL"; }
317  private:
318  boost::any _get_value(
319  const google::protobuf::FieldDescriptor* field,
320  const google::protobuf::Message& msg)
321  { return msg.GetReflection()->GetBool(msg, field); }
322  boost::any _get_repeated_value(
323  const google::protobuf::FieldDescriptor* field,
324  const google::protobuf::Message& msg,
325  int index)
326  { return msg.GetReflection()->GetRepeatedBool(msg, field, index); }
327  void _set_value(const google::protobuf::FieldDescriptor* field,
329  boost::any value)
330  { msg->GetReflection()->SetBool(msg, field, boost::any_cast<type>(value)); }
331  void _add_value(const google::protobuf::FieldDescriptor* field,
333  boost::any value)
334  { msg->GetReflection()->AddBool(msg, field, boost::any_cast<type>(value)); }
335  };
336  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_STRING>
337  : public FromProtoCppTypeBase
338  {
339  public:
340  typedef std::string type;
341  std::string as_str() { return "CPPTYPE_STRING"; }
342  private:
343  boost::any _get_value(
344  const google::protobuf::FieldDescriptor* field,
345  const google::protobuf::Message& msg)
346  { return msg.GetReflection()->GetString(msg, field); }
347  boost::any _get_repeated_value(
348  const google::protobuf::FieldDescriptor* field,
349  const google::protobuf::Message& msg,
350  int index)
351  { return msg.GetReflection()->GetRepeatedString(msg, field, index); }
352  void _set_value(const google::protobuf::FieldDescriptor* field,
354  boost::any value)
355  { msg->GetReflection()->SetString(msg, field, boost::any_cast<type>(value)); }
356  void _add_value(const google::protobuf::FieldDescriptor* field,
358  boost::any value)
359  { msg->GetReflection()->AddString(msg, field, boost::any_cast<type>(value)); }
360  };
361 
362  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_ENUM>
363  : public FromProtoCppTypeBase
364  {
365  public:
366  typedef const google::protobuf::EnumValueDescriptor* const_type;
367  typedef google::protobuf::EnumValueDescriptor* mutable_type;
368 
369  std::string as_str() { return "CPPTYPE_ENUM"; }
370  private:
371  boost::any _get_value(
372  const google::protobuf::FieldDescriptor* field,
373  const google::protobuf::Message& msg)
374  { return msg.GetReflection()->GetEnum(msg, field); }
375  boost::any _get_repeated_value(
376  const google::protobuf::FieldDescriptor* field,
377  const google::protobuf::Message& msg,
378  int index)
379  { return msg.GetReflection()->GetRepeatedEnum(msg, field, index); }
380  void _set_value(const google::protobuf::FieldDescriptor* field,
382  boost::any value)
383  { msg->GetReflection()->SetEnum(msg, field, boost::any_cast<const_type>(value)); }
384  void _add_value(const google::protobuf::FieldDescriptor* field,
386  boost::any value)
387  { msg->GetReflection()->AddEnum(msg, field, boost::any_cast<const_type>(value)); }
388 
389  };
390 
391 
393  template<> class FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE>
394  : public FromProtoCppTypeBase
395  {
396  public:
397  typedef const google::protobuf::Message* const_type;
398  typedef google::protobuf::Message* mutable_type;
399  std::string as_str() { return "CPPTYPE_MESSAGE"; }
400 
401  protected:
402  virtual boost::any _get_value(
403  const google::protobuf::FieldDescriptor* field,
404  const google::protobuf::Message& msg)
405  {
406  if(field)
407  return &(msg.GetReflection()->GetMessage(msg, field));
408  else
409  return &msg;
410  }
411 
412  virtual boost::any _get_repeated_value(
413  const google::protobuf::FieldDescriptor* field,
414  const google::protobuf::Message& msg,
415  int index)
416  { return &(msg.GetReflection()->GetRepeatedMessage(msg, field, index)); }
417 
418 
419  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
421  boost::any value)
422  {
423  try
424  {
425  const_type p = boost::any_cast<const_type>(value);
426 
427  if(field)
428  msg->GetReflection()->MutableMessage(msg, field)->MergeFrom(*p);
429  else
430  msg->MergeFrom(*p);
431 
432  }
433  catch(boost::bad_any_cast& e)
434  {
435  mutable_type p = boost::any_cast<mutable_type>(value);
436  if(field)
437  msg->GetReflection()->MutableMessage(msg, field)->MergeFrom(*p);
438  else
439  msg->MergeFrom(*p);
440  }
441 
442  }
443  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
445  boost::any value)
446  {
447  try
448  {
449  const_type p = boost::any_cast<const_type>(value);
450  msg->GetReflection()->AddMessage(msg, field)->MergeFrom(*p);
451  }
452  catch(boost::bad_any_cast& e)
453  {
454  mutable_type p = boost::any_cast<mutable_type>(value);
455  msg->GetReflection()->AddMessage(msg, field)->MergeFrom(*p);
456  }
457  }
458 
459  };
460 
462  template<typename CustomMessage>
463  class FromProtoCustomMessage : public FromProtoCppType<google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE>
464  {
465  public:
466  typedef CustomMessage type;
467 
468  private:
470 
471  virtual boost::any _get_value(
472  const google::protobuf::FieldDescriptor* field,
473  const google::protobuf::Message& msg)
474  {
475  Parent::const_type p = boost::any_cast<Parent::const_type>(Parent::_get_value(field, msg));
476  type r;
477  r.CopyFrom(*p);
478  return r;
479 // return dynamic_cast<const_type>(*p);
480  }
481  virtual boost::any _get_repeated_value(
482  const google::protobuf::FieldDescriptor* field,
483  const google::protobuf::Message& msg,
484  int index)
485  {
486  Parent::const_type p = boost::any_cast<Parent::const_type>(Parent::_get_repeated_value(field, msg, index));
487  type r;
488  r.CopyFrom(*p);
489  return r;
490 // return dynamic_cast<const_type>(*p);
491  }
492  virtual void _set_value(const google::protobuf::FieldDescriptor* field,
494  boost::any value)
495  {
496  type v = boost::any_cast<type>(value);
497  Parent::const_type p = &v;
498  Parent::_set_value(field, msg, p);
499  }
500  virtual void _add_value(const google::protobuf::FieldDescriptor* field,
502  boost::any value)
503  {
504  type v = boost::any_cast<type>(value);
505  Parent::const_type p = &v;
506  Parent::_add_value(field, msg, p);
507  }
508  };
509 
510 
511  template<typename T>
513  { };
514  template<>
515  class ToProtoCppType<double>
516  {
517  public:
518  static google::protobuf::FieldDescriptor::CppType as_enum()
519  { return google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE; }
520  };
521  template<>
522  class ToProtoCppType<float>
523  {
524  public:
525  static google::protobuf::FieldDescriptor::CppType as_enum()
526  { return google::protobuf::FieldDescriptor::CPPTYPE_FLOAT; }
527  };
528  template<>
529  class ToProtoCppType<google::protobuf::int32>
530  {
531  public:
532  static google::protobuf::FieldDescriptor::CppType as_enum()
533  { return google::protobuf::FieldDescriptor::CPPTYPE_INT32; }
534  };
535  template<>
536  class ToProtoCppType<google::protobuf::uint32>
537  {
538  public:
539  static google::protobuf::FieldDescriptor::CppType as_enum()
540  { return google::protobuf::FieldDescriptor::CPPTYPE_UINT32; }
541  };
542  template<>
543  class ToProtoCppType<google::protobuf::int64>
544  {
545  public:
546  static google::protobuf::FieldDescriptor::CppType as_enum()
547  { return google::protobuf::FieldDescriptor::CPPTYPE_INT64; }
548  };
549  template<>
550  class ToProtoCppType<google::protobuf::uint64>
551  {
552  public:
553  static google::protobuf::FieldDescriptor::CppType as_enum()
554  { return google::protobuf::FieldDescriptor::CPPTYPE_UINT64; }
555  };
556  template<>
557  class ToProtoCppType<std::string>
558  {
559  public:
560  static google::protobuf::FieldDescriptor::CppType as_enum()
561  { return google::protobuf::FieldDescriptor::CPPTYPE_STRING; }
562  };
563  template<>
564  class ToProtoCppType<const google::protobuf::EnumValueDescriptor*>
565  {
566  public:
567  static google::protobuf::FieldDescriptor::CppType as_enum()
568  { return google::protobuf::FieldDescriptor::CPPTYPE_ENUM; }
569  };
570 
571  template<>
573  {
574  public:
575  static google::protobuf::FieldDescriptor::CppType as_enum()
576  { return google::protobuf::FieldDescriptor::CPPTYPE_BOOL; }
577  };
578 
579  template<>
580  class ToProtoCppType<google::protobuf::Message>
581  {
582  public:
583  static google::protobuf::FieldDescriptor::CppType as_enum()
584  { return google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE; }
585  };
586  }
587 }
588 
589 
590 
591 
592 
593 
594 
595 
596 
597 
598 
599 
600 #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...