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