Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Delic, Adam | |
11 | * Forstner, Matyas | |
12 | * Raduly, Csaba | |
13 | * Szabo, Janos Zoltan – initial implementation | |
14 | * | |
15 | ******************************************************************************/ | |
970ed795 EL |
16 | #ifndef _Common_Constraint_HH |
17 | #define _Common_Constraint_HH | |
18 | ||
19 | #include "Setting.hh" | |
20 | ||
21 | namespace Asn { | |
22 | class Block; | |
23 | } | |
24 | ||
25 | namespace Common { | |
26 | ||
27 | /** | |
28 | * \ingroup Type | |
29 | * | |
30 | * \defgroup Constraint Constraint specifications | |
31 | * | |
32 | * These classes provide a unified interface for constraints. | |
33 | * | |
34 | * @{ | |
35 | */ | |
36 | ||
37 | class Constraint; | |
38 | class Constraints; | |
39 | ||
40 | // not defined here | |
41 | class Type; | |
42 | class Value; | |
43 | class SubtypeConstraint; | |
44 | class Identifier; | |
45 | ||
46 | using Asn::Block; | |
47 | ||
48 | /** | |
49 | * Class to represent Constraint. | |
50 | */ | |
51 | class Constraint : public Node, public Location { | |
52 | public: | |
53 | enum constrtype_t { | |
54 | CT_ELEMENTSETSPEC, /** ElementSetSpecsConstraint */ | |
55 | CT_IGNORE, /**< Constraint : used if erroneous or not yet supported */ | |
56 | CT_TABLE, /**< TableConstraint */ | |
57 | CT_SINGLEVALUE, /**< SingleValueConstraint */ | |
58 | CT_CONTAINEDSUBTYPE, /**< ContainedSubtypeConstraint */ | |
59 | CT_VALUERANGE, /**< ValueRangeConstraint */ | |
60 | CT_SIZE, /**< SizeConstraint */ | |
61 | CT_PERMITTEDALPHABET, /**< PermittedAlphabetConstraint */ | |
62 | CT_PATTERN, /**< PatternConstraint */ | |
63 | CT_SETOPERATION, /**< SetOperationConstraint */ | |
64 | CT_FULLSET, /**< FullSetConstraint */ | |
65 | CT_SINGLEINNERTYPE, /**< SingleInnerTypeConstraint */ | |
66 | CT_NAMED, /**< NamedConstraint */ | |
67 | CT_UNPARSEDMULTIPLEINNERTYPE, /**< UnparsedMultipleInnerTypeConstraint */ | |
68 | CT_MULTIPLEINNERTYPE /**< MultipleInnerTypeConstraint */ | |
69 | }; | |
70 | protected: | |
71 | constrtype_t constrtype; | |
72 | Type* my_type; /**< the type to which this constraint belongs to */ | |
73 | Scope* my_scope; /**< scope or NULL, if NULL then get scope from my_type */ | |
74 | Constraint* my_parent; /**< the parent constraint node in AST or NULL */ | |
75 | Constraints* my_cons; /**< the Constraints object or NULL, it is set if this | |
76 | is the root node of a constraint tree */ | |
77 | bool checked; /**< set to true by chk() */ | |
78 | SubtypeConstraint* subtype; /**< NULL or set by chk() if constraint is valid, this is the root part */ | |
79 | bool extendable; /**< set by chk() */ | |
80 | SubtypeConstraint* extension; /**< NULL if there is no extension or not valid, set by chk() */ | |
81 | ||
82 | Constraint(const Constraint& p); | |
83 | /// Assignment disabled | |
84 | Constraint& operator=(const Constraint& p); | |
85 | public: | |
86 | Constraint(constrtype_t p_constrtype); | |
87 | virtual ~Constraint(); | |
88 | virtual Constraint* clone() const = 0; | |
89 | constrtype_t get_constrtype() const { return constrtype; } | |
90 | void set_my_type(Type *p_my_type) { my_type = p_my_type; } | |
91 | void set_my_parent(Constraint* p_my_parent) { my_parent = p_my_parent; } | |
92 | Constraint* get_my_parent() const { return my_parent; } | |
93 | void set_my_scope(Scope* p_my_scope) { my_scope = p_my_scope; } | |
94 | Scope* get_my_scope(); | |
95 | void set_my_cons(Constraints* p_my_cons); | |
96 | Constraints* get_my_cons(); | |
97 | virtual void chk() = 0; | |
98 | /** return the subtype constraint */ | |
99 | SubtypeConstraint* get_subtype() const { return subtype; } | |
100 | bool is_extendable() const { return extendable; } | |
101 | SubtypeConstraint* get_extension() const { return extension; } | |
102 | /** returns the name of this constraint which can be used in error messages */ | |
103 | virtual const char* get_name() const = 0; | |
104 | /** if this constraint is inside a FROM() constraint then we are in | |
105 | a char context */ | |
106 | bool in_char_context() const; | |
107 | /** returns true if this constraint is inside a single or multiple inner type constraint */ | |
108 | bool in_inner_constraint() const; | |
109 | /** returns if this kind of constraint is ignored, when ignored the | |
110 | full set is used as it's subtype value | |
111 | TODO: set operations which have operands that are ignored constraints should | |
112 | somehow drop or simplify their constraint, example: (inner subtype) EXCEPT (inner subtype) | |
113 | */ | |
114 | virtual bool is_ignored() const { return false; } | |
115 | }; | |
116 | ||
117 | /** | |
118 | * Class to represent constraints. | |
119 | */ | |
120 | class Constraints : public Node { | |
121 | private: | |
122 | vector<Constraint> cons; | |
123 | Type *my_type; | |
124 | SubtypeConstraint* subtype; /**< NULL or set by chk() if constraint is valid, this is the root part */ | |
125 | bool extendable; /**< set by chk() */ | |
126 | SubtypeConstraint* extension; /**< NULL if there is no extension or not valid, set by chk() */ | |
127 | ||
128 | Constraints(const Constraints& p); | |
129 | /// Assignment disabled | |
130 | Constraints& operator=(const Constraints& p); | |
131 | public: | |
132 | Constraints() : Node(), cons(), my_type(0), subtype(0), extendable(false), extension(0) {} | |
133 | virtual ~Constraints(); | |
134 | virtual Constraints *clone() const; | |
135 | void add_con(Constraint *p_con); | |
136 | size_t get_nof_cons() const {return cons.size();} | |
137 | Constraint* get_con_byIndex(size_t p_i) const { return cons[p_i]; } | |
138 | Constraint* get_tableconstraint() const; | |
139 | void set_my_type(Type *p_my_type); | |
140 | Type* get_my_type() const { return my_type; } | |
141 | void chk(SubtypeConstraint* parent_subtype); | |
142 | void chk_table(); | |
143 | /* return the subtype constraint */ | |
144 | SubtypeConstraint* get_subtype() const { return subtype; } | |
145 | bool is_extendable() const { return extendable; } | |
146 | SubtypeConstraint* get_extension() const { return extension; } | |
147 | }; | |
148 | ||
149 | /** @} end of Constraint group */ | |
150 | ||
151 | ||
152 | // ================================= | |
153 | // ===== ElementSetSpecsConstraint | |
154 | // ================================= | |
155 | ||
156 | /* This AST element is used only if "..." is present, otherwise it's not | |
157 | created, therefore the extendable bool is always true in this constraint */ | |
158 | class ElementSetSpecsConstraint : public Constraint | |
159 | { | |
160 | Constraint* root_constr; | |
161 | Constraint* ext_constr; /* NULL if no extension addition was present */ | |
162 | ElementSetSpecsConstraint(const ElementSetSpecsConstraint& p); | |
163 | /// Assignment disabled | |
164 | ElementSetSpecsConstraint& operator=(const ElementSetSpecsConstraint& p); | |
165 | public: | |
166 | ElementSetSpecsConstraint(Constraint* p_root_constr, Constraint* p_ext_constr); | |
167 | virtual ~ElementSetSpecsConstraint(); | |
168 | ElementSetSpecsConstraint* clone() const { return new ElementSetSpecsConstraint(*this); } | |
169 | void chk(); | |
170 | const char* get_name() const { return "ElementSetSpecs constraint"; } | |
171 | void set_fullname(const string& p_fullname); | |
172 | }; | |
173 | ||
174 | // ================================= | |
175 | // ===== IgnoredConstraint | |
176 | // ================================= | |
177 | ||
178 | class IgnoredConstraint : public Constraint | |
179 | { | |
180 | const char* my_name; | |
181 | IgnoredConstraint(const IgnoredConstraint& p); | |
182 | /// Assignment disabled | |
183 | IgnoredConstraint& operator=(const IgnoredConstraint& p); | |
184 | public: | |
185 | IgnoredConstraint(const char* p_name); | |
186 | IgnoredConstraint* clone() const { return new IgnoredConstraint(*this); } | |
187 | void chk(); | |
188 | const char* get_name() const { return my_name; } | |
189 | bool is_ignored() const { return true; } | |
190 | }; | |
191 | ||
192 | ||
193 | // ================================= | |
194 | // ===== SingleValueConstraint | |
195 | // ================================= | |
196 | ||
197 | class SingleValueConstraint : public Constraint | |
198 | { | |
199 | Value* value; | |
200 | SingleValueConstraint(const SingleValueConstraint& p); | |
201 | /// Assignment disabled | |
202 | SingleValueConstraint& operator=(const SingleValueConstraint& p); | |
203 | public: | |
204 | SingleValueConstraint(Value* p_value); | |
205 | virtual ~SingleValueConstraint(); | |
206 | SingleValueConstraint* clone() const { return new SingleValueConstraint(*this); } | |
207 | void chk(); | |
208 | const char* get_name() const { return "single value constraint"; } | |
209 | void set_fullname(const string& p_fullname); | |
210 | }; | |
211 | ||
212 | // ================================= | |
213 | // ===== ContainedSubtypeConstraint | |
214 | // ================================= | |
215 | ||
216 | class ContainedSubtypeConstraint : public Constraint | |
217 | { | |
218 | Type* type; | |
219 | bool has_includes; /**< INCLUDES keyword was used, then this cannot be a TypeConstraint, | |
220 | otherwise it can be both TypeConstraint and ContainedSubtypeConstraint */ | |
221 | ContainedSubtypeConstraint(const ContainedSubtypeConstraint& p); | |
222 | /// Assignment disabled | |
223 | ContainedSubtypeConstraint& operator=(const ContainedSubtypeConstraint& p); | |
224 | public: | |
225 | ContainedSubtypeConstraint(Type* p_type, bool p_has_includes); | |
226 | virtual ~ContainedSubtypeConstraint(); | |
227 | ContainedSubtypeConstraint* clone() const { return new ContainedSubtypeConstraint(*this); } | |
228 | void chk(); | |
229 | const char* get_name() const { return "contained subtype constraint"; } | |
230 | void set_fullname(const string& p_fullname); | |
231 | }; | |
232 | ||
233 | // ================================= | |
234 | // ===== RangeEndpoint | |
235 | // ================================= | |
236 | ||
237 | class ValueRangeConstraint; | |
238 | ||
239 | class RangeEndpoint : public Node, public Location | |
240 | { | |
241 | public: | |
242 | enum endpoint_t { | |
243 | MIN, /**< minimum value */ | |
244 | VALUE, /**< value */ | |
245 | MAX /**< maximum value */ | |
246 | }; | |
247 | private: | |
248 | endpoint_t type; /**< type of endpoint */ | |
249 | Value* value; /**< a value or NULL if type!=VALUE */ | |
250 | bool inclusive; /**< true if the endpoint is part of the range */ | |
251 | RangeEndpoint(const RangeEndpoint& p); | |
252 | RangeEndpoint& operator=(const RangeEndpoint& p); // = disabled | |
253 | public: | |
254 | RangeEndpoint(endpoint_t p_type); | |
255 | RangeEndpoint(Value* p_value); | |
256 | void set_exclusive() { inclusive = false; } | |
257 | bool get_exclusive() const { return !inclusive; } | |
258 | endpoint_t get_type() const { return type; } | |
259 | Value* get_value() const { return value; } | |
260 | ~RangeEndpoint(); | |
261 | RangeEndpoint* clone() const { return new RangeEndpoint(*this); } | |
262 | void chk(Type* my_type, ValueRangeConstraint* constraint); | |
263 | void set_fullname(const string& p_fullname); | |
264 | }; | |
265 | ||
266 | // ================================= | |
267 | // ===== ValueRangeConstraint | |
268 | // ================================= | |
269 | ||
270 | class ValueRangeConstraint : public Constraint | |
271 | { | |
272 | RangeEndpoint* lower_endpoint; | |
273 | RangeEndpoint* upper_endpoint; | |
274 | ValueRangeConstraint(const ValueRangeConstraint& p); | |
275 | /// Assignment disabled | |
276 | ValueRangeConstraint& operator=(const ValueRangeConstraint& p); | |
277 | public: | |
278 | ValueRangeConstraint(RangeEndpoint* p_lower, RangeEndpoint* p_upper); | |
279 | virtual ~ValueRangeConstraint() { delete lower_endpoint; delete upper_endpoint; } | |
280 | ValueRangeConstraint* clone() const { return new ValueRangeConstraint(*this); } | |
281 | void chk(); | |
282 | const char* get_name() const { return "value range constraint"; } | |
283 | void set_fullname(const string& p_fullname); | |
284 | }; | |
285 | ||
286 | // ================================= | |
287 | // ===== SizeConstraint | |
288 | // ================================= | |
289 | ||
290 | class SizeConstraint : public Constraint | |
291 | { | |
292 | Constraint* constraint; | |
293 | SizeConstraint(const SizeConstraint& p); | |
294 | /// Assignment disabled | |
295 | SizeConstraint& operator=(const SizeConstraint& p); | |
296 | public: | |
297 | SizeConstraint(Constraint* p); | |
298 | virtual ~SizeConstraint() { delete constraint; } | |
299 | SizeConstraint* clone() const { return new SizeConstraint(*this); } | |
300 | void chk(); | |
301 | const char* get_name() const { return "size constraint"; } | |
302 | void set_fullname(const string& p_fullname); | |
303 | }; | |
304 | ||
305 | // ================================= | |
306 | // ===== PermittedAlphabetConstraint | |
307 | // ================================= | |
308 | ||
309 | class PermittedAlphabetConstraint : public Constraint | |
310 | { | |
311 | Constraint* constraint; | |
312 | PermittedAlphabetConstraint(const PermittedAlphabetConstraint& p); | |
313 | /// Assignment disabled | |
314 | PermittedAlphabetConstraint& operator=(const PermittedAlphabetConstraint& p); | |
315 | public: | |
316 | PermittedAlphabetConstraint(Constraint* p); | |
317 | virtual ~PermittedAlphabetConstraint() { delete constraint; } | |
318 | PermittedAlphabetConstraint* clone() const { return new PermittedAlphabetConstraint(*this); } | |
319 | void chk(); | |
320 | const char* get_name() const { return "permitted alphabet constraint"; } | |
321 | void set_fullname(const string& p_fullname); | |
322 | }; | |
323 | ||
324 | // ================================= | |
325 | // ===== SetOperationConstraint | |
326 | // ================================= | |
327 | ||
328 | class SetOperationConstraint : public Constraint | |
329 | { | |
330 | public: | |
331 | enum operationtype_t { | |
332 | UNION, | |
333 | INTERSECTION, | |
334 | EXCEPT | |
335 | }; | |
336 | private: | |
337 | operationtype_t operationtype; | |
338 | Constraint* operand_a; | |
339 | Constraint* operand_b; | |
340 | SetOperationConstraint(const SetOperationConstraint& p); | |
341 | /// Assignment disabled | |
342 | SetOperationConstraint& operator=(const SetOperationConstraint& p); | |
343 | public: | |
344 | SetOperationConstraint(Constraint* p_a, operationtype_t p_optype, Constraint* p_b); | |
345 | virtual ~SetOperationConstraint() { delete operand_a; delete operand_b; } | |
346 | void set_first_operand(Constraint* p_a); | |
347 | SetOperationConstraint* clone() const { return new SetOperationConstraint(*this); } | |
348 | const char* get_operationtype_str() const; | |
349 | void chk(); | |
350 | const char* get_name() const { return get_operationtype_str(); } | |
351 | void set_fullname(const string& p_fullname); | |
352 | }; | |
353 | ||
354 | // ================================= | |
355 | // ===== FullSetConstraint | |
356 | // ================================= | |
357 | ||
358 | class FullSetConstraint : public Constraint | |
359 | { | |
360 | FullSetConstraint(const FullSetConstraint& p): Constraint(p) {} | |
361 | /// Assignment disabled | |
362 | FullSetConstraint& operator=(const FullSetConstraint& p); | |
363 | public: | |
364 | FullSetConstraint(): Constraint(CT_FULLSET) {} | |
365 | FullSetConstraint* clone() const { return new FullSetConstraint(*this); } | |
366 | void chk(); | |
367 | const char* get_name() const { return "ALL"; } | |
368 | }; | |
369 | ||
370 | // ================================= | |
371 | // ===== PatternConstraint | |
372 | // ================================= | |
373 | ||
374 | class PatternConstraint : public Constraint | |
375 | { | |
376 | Value* value; | |
377 | PatternConstraint(const PatternConstraint& p); | |
378 | /// Assignment disabled | |
379 | PatternConstraint& operator=(const PatternConstraint& p); | |
380 | public: | |
381 | PatternConstraint(Value* p_value); | |
382 | virtual ~PatternConstraint(); | |
383 | PatternConstraint* clone() const { return new PatternConstraint(*this); } | |
384 | void chk(); | |
385 | const char* get_name() const { return "pattern constraint"; } | |
386 | void set_fullname(const string& p_fullname); | |
387 | bool is_ignored() const { return true; } | |
388 | }; | |
389 | ||
390 | // ================================= | |
391 | // ===== SingleInnerTypeConstraint | |
392 | // ================================= | |
393 | ||
394 | class SingleInnerTypeConstraint : public Constraint | |
395 | { | |
396 | Constraint* constraint; | |
397 | SingleInnerTypeConstraint(const SingleInnerTypeConstraint& p); | |
398 | /// Assignment disabled | |
399 | SingleInnerTypeConstraint& operator=(const SingleInnerTypeConstraint& p); | |
400 | public: | |
401 | SingleInnerTypeConstraint(Constraint* p); | |
402 | virtual ~SingleInnerTypeConstraint() { delete constraint; } | |
403 | SingleInnerTypeConstraint* clone() const { return new SingleInnerTypeConstraint(*this); } | |
404 | void chk(); | |
405 | void set_fullname(const string& p_fullname); | |
406 | const char* get_name() const { return "inner type constraint"; } | |
407 | bool is_ignored() const { return true; } | |
408 | }; | |
409 | ||
410 | // ================================= | |
411 | // ===== NamedConstraint | |
412 | // ================================= | |
413 | ||
414 | class NamedConstraint : public Constraint | |
415 | { | |
416 | public: | |
417 | enum presence_constraint_t { | |
418 | PC_NONE, // presence constraint was not specified | |
419 | PC_PRESENT, | |
420 | PC_ABSENT, | |
421 | PC_OPTIONAL | |
422 | }; | |
423 | private: | |
424 | Identifier* id; | |
425 | Constraint* value_constraint; // NULL if it was not specified | |
426 | presence_constraint_t presence_constraint; | |
427 | NamedConstraint(const NamedConstraint& p); | |
428 | /// Assignment disabled | |
429 | NamedConstraint& operator=(const NamedConstraint& p); | |
430 | public: | |
431 | NamedConstraint(Identifier* p_id, Constraint* p_value_constraint, presence_constraint_t p_presence_constraint); | |
432 | ~NamedConstraint(); | |
433 | const Identifier& get_id() const { return *id; } | |
434 | Constraint* get_value_constraint() const { return value_constraint; } | |
435 | presence_constraint_t get_presence_constraint() const { return presence_constraint; } | |
436 | const char* get_presence_constraint_name() const; | |
437 | NamedConstraint* clone() const { return new NamedConstraint(*this); } | |
438 | void chk(); | |
439 | void set_fullname(const string& p_fullname); | |
440 | const char* get_name() const { return "named constraint"; } | |
441 | bool is_ignored() const { return true; } | |
442 | }; | |
443 | ||
444 | // ================================= | |
445 | // ===== MultipleInnerTypeConstraint | |
446 | // ================================= | |
447 | ||
448 | class MultipleInnerTypeConstraint : public Constraint | |
449 | { | |
450 | bool partial; // Full/Partial Specification | |
451 | vector<NamedConstraint> named_con_vec; | |
452 | map<Identifier,NamedConstraint> named_con_map; // values owned by named_con_vec, filled by chk() | |
453 | MultipleInnerTypeConstraint(const MultipleInnerTypeConstraint& p); | |
454 | /// Assignment disabled | |
455 | MultipleInnerTypeConstraint& operator=(const MultipleInnerTypeConstraint& p); | |
456 | public: | |
457 | MultipleInnerTypeConstraint(): Constraint(CT_MULTIPLEINNERTYPE) {} | |
458 | virtual ~MultipleInnerTypeConstraint(); | |
459 | MultipleInnerTypeConstraint* clone() const { return new MultipleInnerTypeConstraint(*this); } | |
460 | ||
461 | void set_partial(bool b) { partial = b; } | |
462 | bool get_partial() const { return partial; } | |
463 | void addNamedConstraint(NamedConstraint* named_con); | |
464 | ||
465 | void chk(); | |
466 | void set_fullname(const string& p_fullname); | |
467 | const char* get_name() const { return "inner type constraint"; } | |
468 | bool is_ignored() const { return true; } | |
469 | }; | |
470 | ||
471 | // ================================= | |
472 | // ===== UnparsedMultipleInnerTypeConstraint | |
473 | // ================================= | |
474 | ||
475 | class UnparsedMultipleInnerTypeConstraint : public Constraint | |
476 | { | |
477 | Block* block; | |
478 | MultipleInnerTypeConstraint* constraint; | |
479 | UnparsedMultipleInnerTypeConstraint(const UnparsedMultipleInnerTypeConstraint& p); | |
480 | /// Assignment disabled | |
481 | UnparsedMultipleInnerTypeConstraint& operator=(const UnparsedMultipleInnerTypeConstraint& p); | |
482 | public: | |
483 | UnparsedMultipleInnerTypeConstraint(Block* p_block); | |
484 | virtual ~UnparsedMultipleInnerTypeConstraint(); | |
485 | UnparsedMultipleInnerTypeConstraint* clone() const { return new UnparsedMultipleInnerTypeConstraint(*this); } | |
486 | void chk(); | |
487 | void set_fullname(const string& p_fullname); | |
488 | const char* get_name() const { return "inner type constraint"; } | |
489 | bool is_ignored() const { return true; } | |
490 | }; | |
491 | ||
492 | } // namespace Common | |
493 | ||
494 | #endif // _Common_Constraint_HH |