Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / Constraint.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 #include "Constraint.hh"
9 #include "CompilerError.hh"
10 #include "Int.hh"
11 #include "Type.hh"
12 #include "Value.hh"
13 #include "subtype.hh"
14 #include "Identifier.hh"
15 #include "CompField.hh"
16 #include "asn1/Block.hh"
17 #include "asn1/TokenBuf.hh"
18
19 namespace Common {
20
21 // =================================
22 // ===== Constraints
23 // =================================
24
25 Constraints::Constraints(const Constraints& p)
26 : Node(p), cons(), my_type(0), subtype(0), extendable(false), extension(0)
27 {
28 size_t nof_cons = p.cons.size();
29 for (size_t i = 0; i < nof_cons; i++) cons.add(p.cons[i]->clone());
30 }
31
32 Constraints::~Constraints()
33 {
34 size_t nof_cons = cons.size();
35 for (size_t i = 0; i < nof_cons; i++) delete cons[i];
36 cons.clear();
37 delete subtype;
38 delete extension;
39 }
40
41 Constraints *Constraints::clone() const
42 {
43 return new Constraints(*this);
44 }
45
46 void Constraints::add_con(Constraint *p_con)
47 {
48 if (!p_con) FATAL_ERROR("Constraints::add_con()");
49 cons.add(p_con);
50 if (my_type) p_con->set_my_type(my_type);
51 }
52
53 Constraint* Constraints::get_tableconstraint() const
54 {
55 size_t nof_cons = cons.size();
56 for (size_t i = 0; i < nof_cons; i++) {
57 Constraint *con = cons[i];
58 if (con->get_constrtype() == Constraint::CT_TABLE) return con;
59 }
60 return 0;
61 }
62
63 void Constraints::set_my_type(Type *p_my_type)
64 {
65 my_type=p_my_type;
66 size_t nof_cons = cons.size();
67 for (size_t i = 0; i < nof_cons; i++) cons[i]->set_my_type(p_my_type);
68 }
69
70 void Constraints::chk_table()
71 {
72 if(!my_type) FATAL_ERROR("Constraints::chk_table()");
73 size_t nof_cons = cons.size();
74 for (size_t i = 0; i < nof_cons; i++) {
75 Error_Context cntxt(my_type, "In constraint #%lu of type `%s'",
76 (unsigned long) (i + 1), my_type->get_typename().c_str());
77 Constraint::constrtype_t cst = cons[i]->get_constrtype();
78 if (cst==Constraint::CT_TABLE) cons[i]->chk();
79 }
80 }
81
82 void Constraints::chk(SubtypeConstraint* parent_subtype)
83 {
84 if(!my_type) FATAL_ERROR("Common::Constraints::chk()");
85 if (parent_subtype) {
86 subtype = new SubtypeConstraint(my_type->get_subtype_type());
87 subtype->copy(parent_subtype);
88 }
89 size_t nof_cons = cons.size();
90 for (size_t i = 0; i < nof_cons; i++) {
91 Error_Context cntxt(my_type, "In constraint #%lu of type `%s'",
92 (unsigned long) (i + 1), my_type->get_typename().c_str());
93 cons[i]->set_fullname(my_type->get_fullname()+".<constraint_"+Int2string(i+1)+">.<"+string(cons[i]->get_name())+">");
94 cons[i]->set_my_cons(this);
95 Constraint::constrtype_t cst = cons[i]->get_constrtype();
96 if (cst!=Constraint::CT_TABLE) cons[i]->chk();
97 if ( (cst==Constraint::CT_IGNORE) || (cst==Constraint::CT_TABLE) ) continue; // ignore
98 SubtypeConstraint* sc = cons[i]->get_subtype();
99 SubtypeConstraint* sc_ext = cons[i]->get_extension();
100 if (!sc) break; // stop on error
101 extendable = cons[i]->is_extendable();
102 if (extension) { // only the root part shall be kept
103 delete extension;
104 extension = 0;
105 }
106 if (subtype) {
107 if (sc->is_subset(subtype)==TFALSE) {
108 cons[i]->error("Constraint #%lu is %s, this is not a subset of %s",
109 (unsigned long) (i + 1),
110 sc->to_string().c_str(),
111 subtype->to_string().c_str());
112 break; // stop on error
113 }
114 if (sc_ext && (sc_ext->is_subset(subtype)==TFALSE)) {
115 cons[i]->error("Extension addition of constraint #%lu is %s, this is not a subset of %s",
116 (unsigned long) (i + 1),
117 sc_ext->to_string().c_str(),
118 subtype->to_string().c_str());
119 break; // stop on error
120 }
121 if (sc_ext) {
122 extension = new SubtypeConstraint(my_type->get_subtype_type());
123 extension->copy(sc_ext);
124 extension->intersection(subtype);
125 }
126 subtype->intersection(sc);
127 } else {
128 subtype = new SubtypeConstraint(my_type->get_subtype_type());
129 subtype->copy(sc);
130 if (sc_ext) {
131 extension = new SubtypeConstraint(my_type->get_subtype_type());
132 extension->copy(sc_ext);
133 }
134 }
135 }
136 }
137
138 // =================================
139 // ===== Constraint
140 // =================================
141
142 Constraint::Constraint(const Constraint& p):
143 Node(p), Location(p), constrtype(p.constrtype),
144 my_type(0), my_scope(0), my_parent(0), my_cons(0),
145 checked(false), subtype(0), extendable(false), extension(0)
146 {
147 }
148
149 Constraint::Constraint(constrtype_t p_constrtype):
150 Node(), Location(), constrtype(p_constrtype),
151 my_type(0), my_scope(0), my_parent(0), my_cons(0),
152 checked(false), subtype(0), extendable(false), extension(0)
153 {
154 }
155
156 Constraint::~Constraint()
157 {
158 delete subtype;
159 delete extension;
160 }
161
162 Scope* Constraint::get_my_scope()
163 {
164 if (!my_type) FATAL_ERROR("Constraint::get_my_scope()");
165 return my_scope ? my_scope : my_type->get_my_scope();
166 }
167
168 void Constraint::set_my_cons(Constraints* p_my_cons)
169 {
170 my_cons = p_my_cons;
171 }
172
173 Constraints* Constraint::get_my_cons()
174 {
175 Constraint* c = this;
176 while (c) {
177 if (c->my_cons) return c->my_cons;
178 c = c->my_parent;
179 }
180 FATAL_ERROR("Constraint::get_my_cons()");
181 return NULL;
182 }
183
184 bool Constraint::in_char_context() const
185 {
186 Constraint* parent = my_parent;
187 while (parent) {
188 if (parent->get_constrtype()==CT_PERMITTEDALPHABET) return true;
189 parent = parent->get_my_parent();
190 }
191 return false;
192 }
193
194 bool Constraint::in_inner_constraint() const
195 {
196 Constraint* parent = my_parent;
197 while (parent) {
198 switch (parent->get_constrtype()) {
199 case CT_SINGLEINNERTYPE:
200 case CT_MULTIPLEINNERTYPE:
201 return true;
202 default:
203 break;
204 }
205 parent = parent->get_my_parent();
206 }
207 return false;
208 }
209
210 // =================================
211 // ===== ElementSetSpecsConstraint
212 // =================================
213
214 ElementSetSpecsConstraint::ElementSetSpecsConstraint(const ElementSetSpecsConstraint& p)
215 : Constraint(p)
216 {
217 extendable = true;
218 root_constr = p.root_constr ? p.root_constr->clone() : 0;
219 ext_constr = p.ext_constr ? p.ext_constr->clone() : 0;
220 }
221
222 ElementSetSpecsConstraint::ElementSetSpecsConstraint(Constraint* p_root_constr, Constraint* p_ext_constr)
223 : Constraint(CT_ELEMENTSETSPEC), root_constr(p_root_constr), ext_constr(p_ext_constr)
224 {
225 if (!p_root_constr) FATAL_ERROR("ElementSetSpecsConstraint::ElementSetSpecsConstraint()");
226 // p_ext_constr can be NULL
227 extendable = true;
228 }
229
230 ElementSetSpecsConstraint::~ElementSetSpecsConstraint()
231 {
232 delete root_constr;
233 delete ext_constr;
234 }
235
236 void ElementSetSpecsConstraint::chk()
237 {
238 if (checked) return;
239 checked = true;
240 if (!root_constr || !my_type) FATAL_ERROR("ElementSetSpecsConstraint::chk()");
241 Error_Context cntxt(this, "While checking ElementSetSpecs constraint");
242 root_constr->set_my_type(my_type);
243 if (ext_constr) ext_constr->set_my_type(my_type);
244 root_constr->set_my_scope(get_my_scope());
245 if (ext_constr) ext_constr->set_my_scope(get_my_scope());
246 root_constr->set_my_parent(this);
247 if (ext_constr) ext_constr->set_my_parent(this);
248 root_constr->chk();
249 if (ext_constr) ext_constr->chk();
250 SubtypeConstraint::subtype_t my_subtype_type = my_type->get_subtype_type();
251 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
252 SubtypeConstraint* r1 = root_constr->get_subtype();
253 if (!r1) return; // root_constr is invalid, error already reported there
254 SubtypeConstraint* x1 = root_constr->get_extension();
255 if (!ext_constr) {
256 // only root part exists
257 subtype = new SubtypeConstraint(my_subtype_type);
258 subtype->copy(r1);
259 if (x1) {
260 extension = new SubtypeConstraint(my_subtype_type);
261 extension->copy(x1);
262 }
263 return;
264 }
265 SubtypeConstraint* r2 = ext_constr->get_subtype();
266 if (!r2) return; // ext_constr is invalid, error already reported there
267 SubtypeConstraint* x2 = ext_constr->get_extension();
268 subtype = new SubtypeConstraint(my_subtype_type);
269 subtype->copy(r1);
270 extension = new SubtypeConstraint(my_subtype_type);
271 extension->copy(r2);
272 if (x1) extension->union_(x1);
273 if (x2) extension->union_(x2);
274 extension->except(r1);
275 }
276
277 void ElementSetSpecsConstraint::set_fullname(const string& p_fullname)
278 {
279 Node::set_fullname(p_fullname);
280 root_constr->set_fullname(p_fullname+".<root_part>.<"+string(root_constr->get_name())+">");
281 if (ext_constr)
282 ext_constr->set_fullname(p_fullname+".<extension_part>.<"+string(ext_constr->get_name())+">");
283 }
284
285 // =================================
286 // ===== IgnoredConstraint
287 // =================================
288
289 IgnoredConstraint::IgnoredConstraint(const IgnoredConstraint& p)
290 : Constraint(p), my_name(p.my_name)
291 {
292 }
293
294 IgnoredConstraint::IgnoredConstraint(const char* p_name)
295 : Constraint(CT_IGNORE), my_name(p_name)
296 {
297 if (p_name==NULL) FATAL_ERROR("IgnoredConstraint::IgnoredConstraint()");
298 }
299
300 void IgnoredConstraint::chk()
301 {
302 if (checked) return;
303 checked = true;
304 if (!my_type) FATAL_ERROR("IgnoredConstraint::chk()");
305 if (in_char_context()) {
306 error("%s not allowed inside a permitted alphabet constraint", get_name());
307 return;
308 } else {
309 if (my_parent) warning("%s inside a %s is treated as `ALL' (constraint is dropped)", get_name(), my_parent->get_name());
310 //else warning("%s is ignored", get_name());
311 }
312 // ignored constraint does not constrain the type, set to full set
313 subtype = new SubtypeConstraint(my_type->get_subtype_type());
314 }
315
316 // =================================
317 // ===== SingleValueConstraint
318 // =================================
319
320 SingleValueConstraint::SingleValueConstraint(const SingleValueConstraint& p)
321 : Constraint(p)
322 {
323 value = p.value ? p.value->clone() : 0;
324 }
325
326 SingleValueConstraint::~SingleValueConstraint()
327 {
328 delete value;
329 }
330
331 SingleValueConstraint::SingleValueConstraint(Value* p_value)
332 : Constraint(CT_SINGLEVALUE), value(p_value)
333 {
334 if (!p_value) FATAL_ERROR("SingleValueConstraint::SingleValueConstraint()");
335 }
336
337 void SingleValueConstraint::chk()
338 {
339 if (checked) return;
340 checked = true;
341 if (!value || !my_type) FATAL_ERROR("SingleValueConstraint::chk()");
342 Error_Context cntxt(this, "While checking single value constraint");
343 value->set_my_scope(get_my_scope());
344 value->set_my_governor(my_type);
345 my_type->chk_this_value_ref(value);
346 my_type->chk_this_value(value, 0, Type::EXPECTED_CONSTANT,
347 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
348 if (in_char_context()) {
349 subtype = SubtypeConstraint::create_from_asn_charvalues(my_type, value);
350 } else {
351 subtype = SubtypeConstraint::create_from_asn_value(my_type, value);
352 }
353 }
354
355 void SingleValueConstraint::set_fullname(const string& p_fullname)
356 {
357 Node::set_fullname(p_fullname);
358 value->set_fullname(p_fullname+".<value>");
359 }
360
361 // =================================
362 // ===== ContainedSubtypeConstraint
363 // =================================
364
365 ContainedSubtypeConstraint::ContainedSubtypeConstraint(const ContainedSubtypeConstraint& p)
366 : Constraint(p)
367 {
368 type = p.type ? p.type->clone() : 0;
369 }
370
371 ContainedSubtypeConstraint::~ContainedSubtypeConstraint()
372 {
373 delete type;
374 }
375
376 ContainedSubtypeConstraint::ContainedSubtypeConstraint(Type* p_type, bool p_has_includes)
377 : Constraint(CT_CONTAINEDSUBTYPE), type(p_type), has_includes(p_has_includes)
378 {
379 if (!p_type) FATAL_ERROR("ContainedSubtypeConstraint::ContainedSubtypeConstraint()");
380 }
381
382 void ContainedSubtypeConstraint::chk()
383 {
384 if (checked) return;
385 checked = true;
386 if (!type || !my_type) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
387 Error_Context cntxt(this, "While checking contained subtype constraint");
388
389 type->set_my_scope(get_my_scope());
390 type->chk();
391 if (type->get_typetype()==Type::T_ERROR) return;
392
393 if (my_type->get_type_refd_last()->get_typetype()==Type::T_OPENTYPE) {
394 // TODO: open type and anytype should have their own ST_ANY subtype, now this is only ignored
395 subtype = new SubtypeConstraint(my_type->get_subtype_type());
396 return;
397 }
398
399 if (!type->is_identical(my_type)) {
400 error("Contained subtype constraint is invalid, constrained and constraining types have different root type");
401 return;
402 }
403 // check subtype of referenced type
404 SubType* t_st = type->get_sub_type();
405 if (t_st==NULL) {
406 error("Contained subtype constraint is invalid, the constraining type has no subtype constraint");
407 return;
408 }
409
410 // check circular subtype reference
411 Type* my_owner = get_my_cons()->get_my_type();
412 if (!my_owner || !my_owner->get_sub_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
413 if (!my_owner->get_sub_type()->add_parent_subtype(t_st)) return;
414
415 if (t_st->get_subtypetype()==SubtypeConstraint::ST_ERROR) return;
416 if (t_st->get_subtypetype()!=my_type->get_subtype_type()) FATAL_ERROR("ContainedSubtypeConstraint::chk()");
417
418 subtype = SubtypeConstraint::create_from_contained_subtype(t_st->get_root(), in_char_context(), this);
419 }
420
421 void ContainedSubtypeConstraint::set_fullname(const string& p_fullname)
422 {
423 Node::set_fullname(p_fullname);
424 type->set_fullname(p_fullname+".<type>");
425 }
426
427 // =================================
428 // ===== RangeEndpoint
429 // =================================
430
431 RangeEndpoint::RangeEndpoint(const RangeEndpoint& p):
432 Node(p), Location(p), type(p.type), inclusive(p.inclusive)
433 {
434 value = p.value ? p.value->clone() : 0;
435 }
436
437 RangeEndpoint::~RangeEndpoint()
438 {
439 delete value;
440 }
441
442 RangeEndpoint::RangeEndpoint(endpoint_t p_type):
443 Node(), Location(), type(p_type), value(0), inclusive(true)
444 {
445 if (type==VALUE) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
446 }
447
448 RangeEndpoint::RangeEndpoint(Value* p_value):
449 Node(), Location(), type(RangeEndpoint::VALUE), value(p_value), inclusive(true)
450 {
451 if (!p_value) FATAL_ERROR("RangeEndpoint::RangeEndpoint()");
452 }
453
454 void RangeEndpoint::chk(Type* my_type, ValueRangeConstraint* constraint)
455 {
456 if (value) {
457 value->set_my_scope(constraint->get_my_scope());
458 my_type->chk_this_value_ref(value);
459 my_type->chk_this_value(value, 0, Type::EXPECTED_CONSTANT,
460 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
461 }
462 }
463
464 void RangeEndpoint::set_fullname(const string& p_fullname)
465 {
466 Node::set_fullname(p_fullname);
467 if (value) value->set_fullname(p_fullname+".<value>");
468 }
469
470 // =================================
471 // ===== ValueRangeConstraint
472 // =================================
473
474 ValueRangeConstraint::ValueRangeConstraint(const ValueRangeConstraint& p)
475 : Constraint(p)
476 {
477 lower_endpoint = p.lower_endpoint ? p.lower_endpoint->clone() : 0;
478 upper_endpoint = p.upper_endpoint ? p.upper_endpoint->clone() : 0;
479 }
480
481 ValueRangeConstraint::ValueRangeConstraint(RangeEndpoint* p_lower, RangeEndpoint* p_upper)
482 : Constraint(CT_VALUERANGE), lower_endpoint(p_lower), upper_endpoint(p_upper)
483 {
484 if (!p_lower || !p_upper) FATAL_ERROR("ValueRangeConstraint::ValueRangeConstraint()");
485 }
486
487 void ValueRangeConstraint::chk()
488 {
489 if (checked) return;
490 checked = true;
491 if (!lower_endpoint || !upper_endpoint || !my_type) FATAL_ERROR("ValueRangeConstraint::chk()");
492 Error_Context cntxt(this, "While checking value range constraint");
493 SubtypeConstraint::subtype_t my_subtype_type = my_type->get_subtype_type();
494 switch (my_subtype_type) {
495 case SubtypeConstraint::ST_INTEGER:
496 case SubtypeConstraint::ST_FLOAT:
497 break;
498 case SubtypeConstraint::ST_CHARSTRING:
499 switch (my_type->get_type_refd_last()->get_typetype()) {
500 case Type::T_NUMERICSTRING:
501 case Type::T_PRINTABLESTRING:
502 case Type::T_IA5STRING:
503 case Type::T_VISIBLESTRING:
504 if (!in_char_context()) {
505 error("Value range constraint must be inside a permitted alphabet or size constraint");
506 return;
507 }
508 break;
509 default:
510 error("Value range constraint is not allowed for type `%s'", my_type->get_typename().c_str());
511 return;
512 }
513 break;
514 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING:
515 switch (my_type->get_type_refd_last()->get_typetype()) {
516 case Type::T_UTF8STRING:
517 case Type::T_UNIVERSALSTRING:
518 case Type::T_BMPSTRING:
519 if (!in_char_context()) {
520 error("Value range constraint must be inside a permitted alphabet or size constraint");
521 return;
522 }
523 break;
524 default:
525 error("Value range constraint is not allowed for type `%s'", my_type->get_typename().c_str());
526 return;
527 }
528 break;
529 default:
530 error("Value range constraint is not allowed for type `%s'", my_type->get_typename().c_str());
531 return;
532 }
533 lower_endpoint->chk(my_type, this);
534 upper_endpoint->chk(my_type, this);
535 Value* vmin = lower_endpoint->get_value();
536 if (vmin) vmin = vmin->get_value_refd_last();
537 Value* vmax = upper_endpoint->get_value();
538 if (vmax) vmax = vmax->get_value_refd_last();
539 // the subtype of the Constraints object at the time of calling this chk()
540 // function is constructed from all the previously calculated constraints
541 // (it is not yet the final subtype). This is needed to calculate the
542 // current MIN and MAX values.
543 SubtypeConstraint* parent_subtype = get_my_cons()->get_subtype();
544 subtype = SubtypeConstraint::create_from_asn_range(
545 vmin, lower_endpoint->get_exclusive(),
546 vmax, upper_endpoint->get_exclusive(),
547 this, my_subtype_type,
548 in_inner_constraint() ? NULL /*the parent is invalid for an inner field*/ : parent_subtype);
549 }
550
551 void ValueRangeConstraint::set_fullname(const string& p_fullname)
552 {
553 Node::set_fullname(p_fullname);
554 lower_endpoint->set_fullname(p_fullname+".<lower_endpoint>");
555 upper_endpoint->set_fullname(p_fullname+".<upper_endpoint>");
556 }
557
558 // =================================
559 // ===== SizeConstraint
560 // =================================
561
562 SizeConstraint::SizeConstraint(const SizeConstraint& p)
563 : Constraint(p)
564 {
565 constraint = p.constraint ? p.constraint->clone() : 0;
566 }
567
568 SizeConstraint::SizeConstraint(Constraint* p)
569 : Constraint(CT_SIZE), constraint(p)
570 {
571 if (!p) FATAL_ERROR("SizeConstraint::SizeConstraint()");
572 }
573
574 void SizeConstraint::chk()
575 {
576 if (checked) return;
577 checked = true;
578 if (!constraint || !my_type) FATAL_ERROR("SizeConstraint::chk()");
579 Error_Context cntxt(this, "While checking size constraint");
580 constraint->set_my_type(Type::get_pooltype(Type::T_INT_A));
581 constraint->set_my_scope(get_my_scope());
582 constraint->set_my_parent(this);
583 constraint->chk();
584 subtype = SubtypeConstraint::create_asn_size_constraint(
585 constraint->get_subtype(), in_char_context(), my_type, this);
586 extendable = constraint->is_extendable();
587 if (constraint->get_extension()) {
588 extension = SubtypeConstraint::create_asn_size_constraint(
589 constraint->get_extension(), in_char_context(), my_type, this);
590 }
591 }
592
593 void SizeConstraint::set_fullname(const string& p_fullname)
594 {
595 Node::set_fullname(p_fullname);
596 constraint->set_fullname(p_fullname+".<"+string(constraint->get_name())+">");
597 }
598
599 // =================================
600 // ===== PermittedAlphabetConstraint
601 // =================================
602
603 PermittedAlphabetConstraint::PermittedAlphabetConstraint(const PermittedAlphabetConstraint& p)
604 : Constraint(p)
605 {
606 constraint = p.constraint ? p.constraint->clone() : 0;
607 }
608
609 PermittedAlphabetConstraint::PermittedAlphabetConstraint(Constraint* p)
610 : Constraint(CT_PERMITTEDALPHABET), constraint(p)
611 {
612 if (!p) FATAL_ERROR("PermittedAlphabetConstraint::PermittedAlphabetConstraint()");
613 }
614
615 void PermittedAlphabetConstraint::chk()
616 {
617 if (checked) return;
618 checked = true;
619 if (!constraint || !my_type) FATAL_ERROR("PermittedAlphabetConstraint::chk()");
620 Error_Context cntxt(this, "While checking permitted alphabet constraint");
621 constraint->set_my_type(my_type);
622 constraint->set_my_scope(get_my_scope());
623 constraint->set_my_parent(this);
624 constraint->chk();
625 subtype = SubtypeConstraint::create_permitted_alphabet_constraint(
626 constraint->get_subtype(), in_char_context(), my_type, this);
627 extendable = constraint->is_extendable();
628 if (constraint->get_extension()) {
629 extension = SubtypeConstraint::create_permitted_alphabet_constraint(
630 constraint->get_extension(), in_char_context(), my_type, this);
631 }
632 }
633
634 void PermittedAlphabetConstraint::set_fullname(const string& p_fullname)
635 {
636 Node::set_fullname(p_fullname);
637 constraint->set_fullname(p_fullname+".<"+string(constraint->get_name())+">");
638 }
639
640 // =================================
641 // ===== SetOperationConstraint
642 // =================================
643
644 SetOperationConstraint::SetOperationConstraint(const SetOperationConstraint& p)
645 : Constraint(p), operationtype(p.operationtype)
646 {
647 operand_a = p.operand_a ? p.operand_a->clone() : 0;
648 operand_b = p.operand_b ? p.operand_b->clone() : 0;
649 }
650
651 void SetOperationConstraint::set_first_operand(Constraint* p_a)
652 {
653 if (operand_a || !p_a) FATAL_ERROR("SetOperationConstraint::set_first_operand()");
654 operand_a = p_a;
655 }
656
657 SetOperationConstraint::SetOperationConstraint(Constraint* p_a, operationtype_t p_optype, Constraint* p_b)
658 : Constraint(CT_SETOPERATION), operationtype(p_optype), operand_a(p_a), operand_b(p_b)
659 {
660 // p_a can be null
661 if (!p_b) FATAL_ERROR("SetOperationConstraint::SetOperationConstraint()");
662 }
663
664 const char* SetOperationConstraint::get_operationtype_str() const
665 {
666 switch (operationtype) {
667 case UNION:
668 return "union";
669 case INTERSECTION:
670 return "intersection";
671 case EXCEPT:
672 return "except";
673 }
674 return "<invalid>";
675 }
676
677 void SetOperationConstraint::chk()
678 {
679 if (checked) return;
680 checked = true;
681 if (!operand_a || !operand_b || !my_type) FATAL_ERROR("SetOperationConstraint::chk()");
682 Error_Context cntxt(this, "While checking %s operation", get_operationtype_str());
683 operand_a->set_my_type(my_type);
684 operand_b->set_my_type(my_type);
685 operand_a->set_my_scope(get_my_scope());
686 operand_b->set_my_scope(get_my_scope());
687 operand_a->set_my_parent(this);
688 operand_b->set_my_parent(this);
689 operand_a->chk();
690 operand_b->chk();
691
692 extendable = (operationtype!=EXCEPT) ?
693 (operand_a->is_extendable() || operand_b->is_extendable()) :
694 operand_a->is_extendable();
695 SubtypeConstraint::subtype_t my_subtype_type = my_type->get_subtype_type();
696 // naming ((r1,x1),...,(r2,x2)) according to X.680(11/2008) I.4.3.8
697 SubtypeConstraint* r1 = operand_a->get_subtype();
698 SubtypeConstraint* x1 = operand_a->get_extension();
699 SubtypeConstraint* r2 = operand_b->get_subtype();
700 SubtypeConstraint* x2 = operand_b->get_extension();
701 if (!r1 || !r2) return; // something invalid, error already reported there
702 subtype = new SubtypeConstraint(my_subtype_type);
703 subtype->copy(r1);
704 switch (operationtype) {
705 case UNION:
706 subtype->union_(r2);
707 if (x1 || x2) {
708 extension = new SubtypeConstraint(my_subtype_type);
709 if (x1 && x2) {
710 extension->copy(subtype);
711 extension->union_(x1);
712 extension->union_(x2);
713 extension->except(subtype);
714 } else {
715 extension->copy(x1?x1:x2);
716 }
717 }
718 break;
719 case INTERSECTION:
720 subtype->intersection(r2);
721 if (x1 || x2) {
722 extension = new SubtypeConstraint(my_subtype_type);
723 if (x1 && x2) {
724 extension->copy(r1);
725 extension->union_(x1);
726 SubtypeConstraint* ext_tmp = new SubtypeConstraint(my_subtype_type);
727 ext_tmp->copy(r2);
728 ext_tmp->union_(x2);
729 extension->intersection(ext_tmp);
730 delete ext_tmp;
731 extension->except(subtype);
732 } else {
733 extension->copy(r1);
734 extension->intersection(x1?x1:x2);
735 }
736 }
737 break;
738 case EXCEPT:
739 subtype->except(r2);
740 if (x1) {
741 extension = new SubtypeConstraint(my_subtype_type);
742 if (x2) {
743 extension->copy(x1);
744 SubtypeConstraint* ext_tmp = new SubtypeConstraint(my_subtype_type);
745 ext_tmp->copy(r2);
746 ext_tmp->union_(x2);
747 extension->except(ext_tmp);
748 delete ext_tmp;
749 extension->except(subtype);
750 } else {
751 extension->copy(x1);
752 extension->except(r2);
753 extension->except(subtype);
754 }
755 }
756 break;
757 default:
758 FATAL_ERROR("SetOperationConstraint::chk()");
759 }
760 }
761
762 void SetOperationConstraint::set_fullname(const string& p_fullname)
763 {
764 Node::set_fullname(p_fullname);
765 operand_a->set_fullname(p_fullname+".<first_operand>.<"+string(operand_a->get_name())+">");
766 operand_b->set_fullname(p_fullname+".<second_operand>.<"+string(operand_b->get_name())+">");
767 }
768
769 // =================================
770 // ===== FullSetConstraint
771 // =================================
772
773 void FullSetConstraint::chk()
774 {
775 SubtypeConstraint::subtype_t my_subtype_type = my_type->get_subtype_type();
776 subtype = new SubtypeConstraint(my_subtype_type);
777 }
778
779 // =================================
780 // ===== PatternConstraint
781 // =================================
782
783 PatternConstraint::PatternConstraint(const PatternConstraint& p)
784 : Constraint(p)
785 {
786 value = p.value ? p.value->clone() : 0;
787 }
788
789 PatternConstraint::~PatternConstraint()
790 {
791 delete value;
792 }
793
794 PatternConstraint::PatternConstraint(Value* p_value)
795 : Constraint(CT_PATTERN), value(p_value)
796 {
797 if (!p_value) FATAL_ERROR("PatternConstraint::PatternConstraint()");
798 }
799
800 void PatternConstraint::chk()
801 {
802 if (checked) return;
803 checked = true;
804 if (!value || !my_type) FATAL_ERROR("PatternConstraint::chk()");
805 Error_Context cntxt(this, "While checking pattern constraint");
806 switch (my_type->get_subtype_type()) {
807 case SubtypeConstraint::ST_CHARSTRING:
808 case SubtypeConstraint::ST_UNIVERSAL_CHARSTRING:
809 break;
810 default:
811 error("Pattern constraint is not allowed for type `%s'", my_type->get_typename().c_str());
812 return;
813 }
814 value->set_my_scope(get_my_scope());
815 value->set_my_governor(my_type);
816 my_type->chk_this_value_ref(value);
817 my_type->chk_this_value(value, 0, Type::EXPECTED_CONSTANT,
818 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK);
819 // ignore ASN.1 pattern constraint (9.1 Transformation rules, point 4.)
820 if (in_char_context()) {
821 error("%s not allowed inside a permitted alphabet constraint", get_name());
822 return;
823 } else {
824 if (my_parent) warning("%s inside a %s is treated as `ALL' (constraint is dropped)",
825 get_name(), my_parent->get_name());
826 else warning("%s is ignored", get_name());
827 }
828 subtype = new SubtypeConstraint(my_type->get_subtype_type());
829 }
830
831 void PatternConstraint::set_fullname(const string& p_fullname)
832 {
833 Node::set_fullname(p_fullname);
834 value->set_fullname(p_fullname+".<value>");
835 }
836
837 // =================================
838 // ===== SingleInnerTypeConstraint
839 // =================================
840
841 SingleInnerTypeConstraint::SingleInnerTypeConstraint(const SingleInnerTypeConstraint& p)
842 : Constraint(p)
843 {
844 constraint = p.constraint ? p.constraint->clone() : 0;
845 }
846
847 SingleInnerTypeConstraint::SingleInnerTypeConstraint(Constraint* p)
848 : Constraint(CT_SINGLEINNERTYPE), constraint(p)
849 {
850 if (!p) FATAL_ERROR("SingleInnerTypeConstraint::SingleInnerTypeConstraint()");
851 }
852
853 void SingleInnerTypeConstraint::chk()
854 {
855 if (checked) return;
856 checked = true;
857 if (!constraint || !my_type) FATAL_ERROR("SingleInnerTypeConstraint::chk()");
858 Error_Context cntxt(this, "While checking inner type constraint");
859 Type* t = my_type->get_type_refd_last();
860 if (!t->is_seof()) {
861 error("Single inner type constraint (WITH COMPONENT) cannot be used on type `%s'", my_type->get_typename().c_str());
862 return;
863 }
864 Type* field_type = t->get_ofType(); // determine the type of the field to which it refers
865 constraint->set_my_type(field_type);
866 constraint->set_my_scope(get_my_scope());
867 constraint->set_my_parent(this);
868 constraint->chk();
869 //if (constraint->get_subtype()) { // if the constraint was not erroneous
870 // TODO: this could be added to the a tree structure constraint on my_type,
871 // tree structure needed because of set operations, constraint cannot
872 // be added to field_type
873 //}
874 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
875 subtype = new SubtypeConstraint(my_type->get_subtype_type());
876 }
877
878 void SingleInnerTypeConstraint::set_fullname(const string& p_fullname)
879 {
880 Node::set_fullname(p_fullname);
881 constraint->set_fullname(p_fullname+".<"+string(constraint->get_name())+">");
882 }
883
884 // =================================
885 // ===== NamedConstraint
886 // =================================
887
888 NamedConstraint::NamedConstraint(Identifier* p_id, Constraint* p_value_constraint, presence_constraint_t p_presence_constraint):
889 Constraint(CT_NAMED), id(p_id), value_constraint(p_value_constraint), presence_constraint(p_presence_constraint)
890 {
891 if (!id) FATAL_ERROR("NamedConstraint::NamedConstraint()");
892 }
893
894 NamedConstraint::NamedConstraint(const NamedConstraint& p)
895 : Constraint(p)
896 {
897 id = p.id->clone();
898 value_constraint = p.value_constraint ? p.value_constraint->clone() : 0;
899 presence_constraint = p.presence_constraint;
900 }
901
902 NamedConstraint::~NamedConstraint()
903 {
904 delete id;
905 delete value_constraint;
906 }
907
908 const char* NamedConstraint::get_presence_constraint_name() const
909 {
910 switch (presence_constraint) {
911 case PC_NONE: return "";
912 case PC_PRESENT: return "PRESENT";
913 case PC_ABSENT: return "ABSENT";
914 case PC_OPTIONAL: return "OPTIONAL";
915 default: FATAL_ERROR("NamedConstraint::get_presence_constraint_name()");
916 }
917 }
918
919 void NamedConstraint::chk()
920 {
921 if (checked) return;
922 checked = true;
923 if (!my_type) FATAL_ERROR("NamedConstraint::chk()");
924 Error_Context cntxt(this, "While checking named constraint");
925 if (value_constraint) {
926 value_constraint->set_my_type(my_type);
927 value_constraint->set_my_scope(get_my_scope());
928 value_constraint->set_my_parent(this);
929 value_constraint->chk();
930 }
931 subtype = new SubtypeConstraint(my_type->get_subtype_type()); // ignored
932 }
933
934 void NamedConstraint::set_fullname(const string& p_fullname)
935 {
936 Node::set_fullname(p_fullname);
937 if (value_constraint) {
938 value_constraint->set_fullname(p_fullname+".<"+string(value_constraint->get_name())+">");
939 }
940 }
941
942 // =================================
943 // ===== MultipleInnerTypeConstraint
944 // =================================
945
946 MultipleInnerTypeConstraint::MultipleInnerTypeConstraint(const MultipleInnerTypeConstraint& p)
947 : Constraint(p)
948 {
949 partial = p.partial;
950 for (size_t i=0; i<p.named_con_vec.size(); i++) {
951 named_con_vec.add( p.named_con_vec[i]->clone() );
952 }
953 }
954
955 MultipleInnerTypeConstraint::~MultipleInnerTypeConstraint()
956 {
957 named_con_map.clear();
958 for (size_t i=0; i<named_con_vec.size(); i++) {
959 delete named_con_vec[i];
960 }
961 named_con_vec.clear();
962 }
963
964 void MultipleInnerTypeConstraint::addNamedConstraint(NamedConstraint* named_con)
965 {
966 if (!named_con) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
967 if (checked) FATAL_ERROR("MultipleInnerTypeConstraint::addNamedConstraint()");
968 named_con_vec.add(named_con);
969 }
970
971 void MultipleInnerTypeConstraint::chk()
972 {
973 if (checked) return;
974 checked = true;
975 if (!my_type) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
976 Type* t = my_type->get_type_refd_last();
977
978 switch (t->get_typetype()) {
979 case Type::T_REAL: { // associated ASN.1 type is a SEQUENCE
980 Identifier t_id(Identifier::ID_ASN, string("REAL"));
981 t = t->get_my_scope()->get_scope_asss()->get_local_ass_byId(t_id)->get_Type();
982 if (t->get_typetype()!=Type::T_SEQ_A) FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
983 } break;
984 case Type::T_CHOICE_A:
985 case Type::T_SEQ_A: // T_EXTERNAL, T_EMBEDDED_PDV, T_UNRESTRICTEDSTRING
986 case Type::T_SET_A:
987 break;
988 default:
989 FATAL_ERROR("MultipleInnerTypeConstraint::chk()");
990 }
991 // check that all NamedConstraints refer to an existing component
992 // if it exists add it to the map<> and check uniqueness
993 // for SEQUENCE check order of fields
994 size_t max_idx = 0; // current highest field index, to detect invalid order
995 bool invalid_order = false;
996 size_t present_count = 0;
997 size_t absent_count = 0;
998 for (size_t i=0; i<named_con_vec.size(); i++) {
999 const Identifier& id = named_con_vec[i]->get_id();
1000 if (t->has_comp_withName(id)) {
1001 if (named_con_map.has_key(id)) {
1002 named_con_vec[i]->error("Duplicate reference to field `%s' of type `%s'",
1003 id.get_dispname().c_str(), my_type->get_typename().c_str());
1004 named_con_map[id]->note("Previous reference to field `%s' is here",
1005 id.get_dispname().c_str());
1006 } else {
1007 named_con_map.add(id, named_con_vec[i]);
1008 if (t->get_typetype()==Type::T_SEQ_A) {
1009 size_t curr_idx = t->get_comp_index_byName(id);
1010 if (curr_idx<max_idx) invalid_order = true;
1011 else max_idx = curr_idx;
1012 }
1013 switch (named_con_vec[i]->get_presence_constraint()) {
1014 case NamedConstraint::PC_PRESENT:
1015 present_count++;
1016 break;
1017 case NamedConstraint::PC_ABSENT:
1018 absent_count++;
1019 break;
1020 default:
1021 break;
1022 }
1023 }
1024 CompField* cf = t->get_comp_byName(id);
1025 switch (t->get_typetype()) {
1026 case Type::T_SEQ_A:
1027 case Type::T_SET_A:
1028 if (!cf->get_is_optional() && (named_con_vec[i]->get_presence_constraint()!=NamedConstraint::PC_NONE)) {
1029 named_con_vec[i]->error("Presence constraint `%s' cannot be used on mandatory field `%s'",
1030 named_con_vec[i]->get_presence_constraint_name(), id.get_dispname().c_str());
1031 }
1032 break;
1033 default:
1034 break;
1035 }
1036 Type* field_type = cf->get_type();
1037 named_con_vec[i]->set_my_type(field_type);
1038 named_con_vec[i]->set_my_scope(get_my_scope());
1039 named_con_vec[i]->set_my_parent(this);
1040 named_con_vec[i]->chk();
1041 } else {
1042 named_con_vec[i]->error("Type `%s' does not have a field named `%s'",
1043 my_type->get_typename().c_str(), id.get_dispname().c_str());
1044 }
1045 }
1046 if (invalid_order) {
1047 error("The order of fields must be the same as in the definition of type `%s'",
1048 my_type->get_typename().c_str());
1049 }
1050 if (t->get_typetype()==Type::T_CHOICE_A) {
1051 if (present_count>1) {
1052 error("CHOICE type `%s' cannot have more than one `PRESENT' field", my_type->get_typename().c_str());
1053 }
1054 // in FullSpecification all not listed fields that can be absent are implicitly ABSENT
1055 size_t real_absent_count = absent_count + ((!get_partial())?(t->get_nof_comps()-named_con_map.size()):0);
1056 if (real_absent_count>=t->get_nof_comps()) {
1057 error("All fields of CHOICE type `%s' are `ABSENT'", my_type->get_typename().c_str());
1058 if (real_absent_count>absent_count) {
1059 note("%ld not listed field%s implicitly `ABSENT' because FullSpecification was used",
1060 (long)(real_absent_count-absent_count), ((real_absent_count-absent_count)>1)?"s are":" is");
1061 }
1062 }
1063 }
1064
1065 // inner subtype is ignored ( ETSI ES 201 873-7 V4.1.2 -> 9.1 Transformation rules )
1066 subtype = new SubtypeConstraint(my_type->get_subtype_type());
1067 }
1068
1069 void MultipleInnerTypeConstraint::set_fullname(const string& p_fullname)
1070 {
1071 Node::set_fullname(p_fullname);
1072 for (size_t i=0; i<named_con_vec.size(); i++) {
1073 named_con_vec[i]->set_fullname(p_fullname+".<"+string(named_con_vec[i]->get_name())+" "+Int2string(i)+">");
1074 }
1075 }
1076
1077 // =================================
1078 // ===== UnparsedMultipleInnerTypeConstraint
1079 // =================================
1080
1081 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(const UnparsedMultipleInnerTypeConstraint& p)
1082 : Constraint(p)
1083 {
1084 block = p.block ? p.block->clone() : 0;
1085 constraint = 0;
1086 }
1087
1088 UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint(Block* p_block)
1089 : Constraint(CT_UNPARSEDMULTIPLEINNERTYPE), block(p_block), constraint(0)
1090 {
1091 if (!block) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::UnparsedMultipleInnerTypeConstraint()");
1092 }
1093
1094 UnparsedMultipleInnerTypeConstraint::~UnparsedMultipleInnerTypeConstraint()
1095 {
1096 delete block;
1097 delete constraint;
1098 }
1099
1100 void UnparsedMultipleInnerTypeConstraint::chk()
1101 {
1102 if (checked) return;
1103 checked = true;
1104 if (!my_type) FATAL_ERROR("UnparsedMultipleInnerTypeConstraint::chk()");
1105 Error_Context cntxt(this, "While checking inner type constraint");
1106 Type* t = my_type->get_type_refd_last();
1107 switch (t->get_typetype()) {
1108 case Type::T_REAL: // associated ASN.1 type is a SEQUENCE
1109 case Type::T_CHOICE_A:
1110 case Type::T_SEQ_A: // also refd by T_EXTERNAL, T_EMBEDDED_PDV and T_UNRESTRICTEDSTRING
1111 case Type::T_SET_A:
1112 break;
1113 default:
1114 error("Multiple inner type constraint (WITH COMPONENTS) cannot be used on type `%s'", my_type->get_typename().c_str());
1115 return;
1116 }
1117 Node *node = block->parse(KW_Block_MultipleTypeConstraints);
1118 constraint = dynamic_cast<MultipleInnerTypeConstraint*>(node);
1119 if (!constraint) {
1120 delete node;
1121 return; // parsing error was already reported
1122 }
1123 constraint->set_my_type(my_type);
1124 constraint->set_my_scope(get_my_scope());
1125 constraint->set_my_parent(this);
1126 constraint->chk();
1127 subtype = new SubtypeConstraint(my_type->get_subtype_type()); // ignored
1128 }
1129
1130 void UnparsedMultipleInnerTypeConstraint::set_fullname(const string& p_fullname)
1131 {
1132 Node::set_fullname(p_fullname);
1133 block->set_fullname(p_fullname);
1134 if (constraint) constraint->set_fullname(p_fullname);
1135 }
1136
1137 } // namespace Common
This page took 0.056182 seconds and 5 git commands to generate.