OpenDDS  Snapshot(2023/04/28-20:55)
annotations.h
Go to the documentation of this file.
1 /**
2  * /file annotations.h
3  *
4  * Wrappers for accessing data from IDL annotations and registers the
5  * annotation by evaluating its definition. Each annotation (@key, @topic,
6  * etc.) should have class.
7  *
8  * To add a new annotation, implement a subclass of Annotation, implementing at
9  * least definition() and name(), then add a register_one call for the class to
10  * Annotations::register_all() in annotations.cpp.
11  *
12  * OpenDDS-specific annotations should go in the OpenDDS C++ namespace and the
13  * OpenDDS IDL module. Only standardized annotations should be outside those
14  * scopes.
15  */
16 
17 #ifndef OPENDDS_IDL_ANNOTATIONS_HEADER
18 #define OPENDDS_IDL_ANNOTATIONS_HEADER
19 
20 #include "../Versioned_Namespace.h"
21 
22 #include <ast_expression.h>
23 
24 #include <ace/Basic_Types.h>
25 
26 #include <vector>
27 #include <string>
28 #include <map>
29 #include <set>
30 
31 class AST_Array;
32 class AST_Sequence;
33 class AST_Decl;
34 class AST_Union;
35 class AST_Annotation_Decl;
36 class AST_Annotation_Appl;
37 class Annotation;
38 
39 class Annotations {
40 public:
41  Annotations();
42  ~Annotations();
43 
44  void register_all();
45  Annotation* operator[](const std::string& annotation) const;
46 
47  template<typename T>
48  void register_one()
49  {
50  T* annotation = new T;
51  map_[annotation->fullname()] = annotation;
52  annotation->cache();
53  }
54 
55 private:
56  typedef std::map<std::string, Annotation*> MapType;
57  MapType map_;
58 };
59 
60 /**
61  * Wrapper Base Class for Annotations
62  */
63 class Annotation {
64 public:
65  Annotation();
66  virtual ~Annotation();
67 
68  virtual std::string definition() const = 0;
69  virtual std::string name() const = 0;
70  virtual std::string module() const;
71  virtual std::string fullname() const;
72 
73  AST_Annotation_Decl* declaration() const;
74  AST_Annotation_Appl* find_on(AST_Decl* node) const;
75  void cache();
76 
77 private:
78  AST_Annotation_Decl* declaration_;
79 };
80 
81 AST_Expression::AST_ExprValue* get_annotation_member_ev(AST_Annotation_Appl* appl,
82  const char* member_name,
83  AST_Expression::ExprType type);
84 
85 bool get_bool_annotation_member_value(AST_Annotation_Appl* appl,
86  const char* member_name);
87 
88 ACE_UINT32 get_u32_annotation_member_value(AST_Annotation_Appl* appl,
89  const char* member_name);
90 
91 std::string get_str_annotation_member_value(AST_Annotation_Appl* appl,
92  const char* member_name);
93 
94 /**
95  * Annotation that logically provide a value when absent.
96  */
97 template <typename T>
98 class AbsentValue {
99 public:
100  explicit AbsentValue(const T& value)
101  : absent_value(value)
102  {}
103 
104  const T absent_value;
105 };
106 
107 /**
108  * Annotation with a Single Member Named "value"
109  */
110 template <typename T>
112 public:
113  /**
114  * If node has the annotation, this sets value to the annotation value and
115  * returns true. Returns false otherwise.
116  */
117  virtual bool node_value_exists(AST_Decl* node, T& value) const
118  {
119  AST_Annotation_Appl* appl = find_on(node);
120  if (!appl) { return false; }
121 
122  value = value_from_appl(appl);
123  return true;
124  }
125 
126 protected:
127  /* NOTE: Derived classes should either override value_from_appl. A
128  default implementation is provided so template functions can be
129  defined. */
130  virtual T value_from_appl(AST_Annotation_Appl*) const
131  {
132  return T();
133  }
134 };
135 
136 template<>
137 bool AnnotationWithValue<bool>::value_from_appl(AST_Annotation_Appl* appl) const;
138 
139 template<>
140 unsigned AnnotationWithValue<ACE_UINT32>::value_from_appl(AST_Annotation_Appl* appl) const;
141 
142 template<>
143 std::string AnnotationWithValue<std::string>::value_from_appl(AST_Annotation_Appl* appl) const;
144 
145 template <typename T>
147 protected:
148  T value_from_appl(AST_Annotation_Appl* appl) const
149  {
150  return static_cast<T>(get_u32_annotation_member_value(appl, "value"));
151  }
152 };
153 
154 // @key ======================================================================
155 
156 class KeyAnnotation : public AnnotationWithValue<bool>, public AbsentValue<bool> {
157 public:
159  : AbsentValue<bool>(false)
160  {}
161 
162  std::string definition() const;
163  std::string name() const;
164 
165  bool union_value(AST_Union* node) const;
166 };
167 
168 // @topic ====================================================================
169 
170 struct TopicValue {
171  std::string name;
172  std::string platform;
173 
175  : name("")
176  , platform("*")
177  {}
178 };
179 
180 class TopicAnnotation : public AnnotationWithValue<TopicValue> {
181 public:
182  TopicAnnotation();
183 
184  std::string definition() const;
185  std::string name() const;
186 
187 private:
188  TopicValue value_from_appl(AST_Annotation_Appl* appl) const;
189 };
190 
191 // @nested ===================================================================
192 
193 class NestedAnnotation : public AnnotationWithValue<bool> {
194 public:
195  std::string definition() const;
196  std::string name() const;
197 };
198 
199 // @default_nested ===========================================================
200 
202 public:
203  std::string definition() const;
204  std::string name() const;
205 };
206 
207 // @id =======================================================================
208 
209 class IdAnnotation : public AnnotationWithValue<ACE_UINT32> {
210 public:
211  std::string definition() const;
212  std::string name() const;
213 };
214 
215 // @autoid ===================================================================
216 
220 };
221 
222 class AutoidAnnotation : public AnnotationWithEnumValue<AutoidKind>, public AbsentValue<AutoidKind> {
223 public:
226  {}
227 
228  std::string definition() const;
229  std::string name() const;
230 };
231 
232 // @hashid ===================================================================
233 
234 class HashidAnnotation : public AnnotationWithValue<std::string> {
235 public:
236  std::string definition() const;
237  std::string name() const;
238 };
239 
240 // @optional ===================================================================
241 
242 class OptionalAnnotation : public AnnotationWithValue<bool>, public AbsentValue<bool> {
243 public:
245  : AbsentValue<bool>(false)
246  {}
247 
248  std::string definition() const;
249  std::string name() const;
250 };
251 
252 // @must_understand ============================================================
253 
254 class MustUnderstandAnnotation : public AnnotationWithValue<bool>, public AbsentValue<bool> {
255 public:
257  : AbsentValue<bool>(false)
258  {}
259 
260  std::string definition() const;
261  std::string name() const;
262 };
263 
264 // @external ===================================================================
265 
266 class ExternalAnnotation : public AnnotationWithValue<bool>, public AbsentValue<bool> {
267 public:
269  : AbsentValue<bool>(false)
270  {}
271 
272  std::string definition() const;
273  std::string name() const;
274 };
275 
276 // @extensibility ============================================================
277 
282 };
283 
284 class ExtensibilityAnnotation : public AnnotationWithEnumValue<ExtensibilityKind> {
285 public:
286  std::string definition() const;
287  std::string name() const;
288 };
289 
290 // @final ====================================================================
291 
292 class FinalAnnotation : public Annotation {
293 public:
294  std::string definition() const;
295  std::string name() const;
296 };
297 
298 // @appendable ===============================================================
299 
301 public:
302  std::string definition() const;
303  std::string name() const;
304 };
305 
306 // @mutable ==================================================================
307 
309 public:
310  std::string definition() const;
311  std::string name() const;
312 };
313 
314 // @try_construct ============================================================
315 
320 };
321 
323  : public AnnotationWithEnumValue<TryConstructFailAction>
324  , public AbsentValue<TryConstructFailAction> {
325 public:
328  {}
329 
330  std::string definition() const;
331  std::string name() const;
332 
333  TryConstructFailAction sequence_element_value(AST_Sequence* node) const;
334  TryConstructFailAction array_element_value(AST_Array* node) const;
335  TryConstructFailAction union_value(AST_Union* node) const;
336 };
337 
338 // OpenDDS Specific Annotations
340 namespace OpenDDS {
341 
342  // @OpenDDS::data_representation ===========================================
343 
345  bool xcdr1;
346  bool xcdr2;
347  bool xml;
348  bool unaligned;
349 
351  {
352  set_all(false);
353  }
354 
355  void add(const DataRepresentation& other)
356  {
357  xcdr1 |= other.xcdr1;
358  xcdr2 |= other.xcdr2;
359  xml |= other.xml;
360  unaligned |= other.unaligned;
361  }
362 
363  void set_all(bool value)
364  {
365  xcdr1 = value;
366  xcdr2 = value;
367  xml = value;
368  unaligned = value;
369  }
370 
371  bool only_xcdr1() const
372  {
373  return xcdr1 && !xcdr2 && !xml;
374  }
375 
376  bool not_only_xcdr1() const
377  {
378  return xcdr1 && (xcdr2 || xml);
379  }
380 
381  bool only_xcdr2() const
382  {
383  return !xcdr1 && xcdr2 && !xml;
384  }
385 
386  bool not_only_xcdr2() const
387  {
388  return xcdr2 && (xcdr1 || xml);
389  }
390 
391  bool only_xml() const
392  {
393  return !xcdr1 && !xcdr2 && xml;
394  }
395 
396  bool not_only_xml() const
397  {
398  return xml && (xcdr1 || xcdr2);
399  }
400  };
401 
402  /**
403  * Used to specify the allowed RTPS data representations in XTypes.
404  * Replacement for @::data_representation which requires bitmask.
405  */
407  public AnnotationWithValue<DataRepresentation> {
408  public:
409  std::string definition() const;
410  std::string name() const;
411  std::string module() const;
412 
413  bool node_value_exists(AST_Decl* node, DataRepresentation& value) const;
414 
415  protected:
416  DataRepresentation value_from_appl(AST_Annotation_Appl* appl) const;
417  };
418 
419  namespace internal {
420  /**
421  * Types with this annotation will not get a DynamicDataAdapterImpl generated
422  * for them. Attempting to access struct or union members with this
423  * annotation on their type will result in an UNSUPPORTED retcode.
424  * get_dynamic_data_adapter for these types will be generated, but will
425  * return nullptr.
426  */
428  std::string definition() const
429  {
430  return
431  "module OpenDDS {\n"
432  " module internal {\n"
433  " @annotation no_dynamic_data_adapter {\n"
434  " };\n"
435  " };\n"
436  "};\n";
437  }
438 
439  std::string name() const
440  {
441  return "no_dynamic_data_adapter";
442  }
443 
444  std::string module() const
445  {
446  return "::OpenDDS::internal::";
447  }
448  };
449 
450  /**
451  * Types with this annotation have a special serialization case in
452  * marshal_generator.
453  */
455  public:
456  std::string definition() const
457  {
458  return
459  "module OpenDDS {\n"
460  " module internal {\n"
461  " @annotation special_serialization {\n"
462  " string template_name default \"\";\n"
463  " };\n"
464  " };\n"
465  "};\n";
466  }
467 
468  std::string name() const
469  {
470  return "special_serialization";
471  }
472 
473  std::string module() const
474  {
475  return "::OpenDDS::internal::";
476  }
477 
478  protected:
479  std::string value_from_appl(AST_Annotation_Appl* appl) const
480  {
481  return get_str_annotation_member_value(appl, "template_name");
482  }
483  };
484  }
485 }
487 
488 #endif
AST_Annotation_Decl * declaration_
Definition: annotations.h:78
const LogLevel::Value value
Definition: debug.cpp:61
std::string value_from_appl(AST_Annotation_Appl *appl) const
Definition: annotations.h:479
bool get_bool_annotation_member_value(AST_Annotation_Appl *appl, const char *member_name)
void add(const DataRepresentation &other)
Definition: annotations.h:355
AbsentValue(const T &value)
Definition: annotations.h:100
ACE_UINT32 get_u32_annotation_member_value(AST_Annotation_Appl *appl, const char *member_name)
TryConstructFailAction
Definition: annotations.h:316
ExtensibilityKind
Definition: annotations.h:278
Annotation * operator[](const std::string &annotation) const
Definition: annotations.cpp:47
AST_Expression::AST_ExprValue * get_annotation_member_ev(AST_Annotation_Appl *appl, const char *member_name, AST_Expression::ExprType type)
Definition: annotations.cpp:93
std::string platform
Definition: annotations.h:172
void register_all()
Definition: annotations.cpp:14
std::map< std::string, Annotation * > MapType
Definition: annotations.h:56
MapType map_
Definition: annotations.h:57
std::string get_str_annotation_member_value(AST_Annotation_Appl *appl, const char *member_name)
virtual T value_from_appl(AST_Annotation_Appl *) const
Definition: annotations.h:130
void register_one()
Definition: annotations.h:48
const T absent_value
Definition: annotations.h:104
virtual bool node_value_exists(AST_Decl *node, T &value) const
Definition: annotations.h:117
T value_from_appl(AST_Annotation_Appl *appl) const
Definition: annotations.h:148
const char *const name
Definition: debug.cpp:60
void set_all(bool value)
Definition: annotations.h:363
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
AutoidKind
Definition: annotations.h:217
std::string name
Definition: annotations.h:171