xsd2ttcn: fixed enumeration restriction (bug 494987)
[deliverable/titan.core.git] / xsdconvert / ComplexType.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 * Beres, Szabolcs
11 * Godar, Marton
12 * Ormandi, Matyas
13 * Raduly, Csaba
14 * Szabo, Bence Janos
15 *
16 ******************************************************************************/
17 #include "ComplexType.hh"
18
19 #include "GeneralFunctions.hh"
20 #include "XMLParser.hh"
21 #include "TTCN3Module.hh"
22 #include "TTCN3ModuleInventory.hh"
23 #include "Annotation.hh"
24
25 #include <assert.h>
26
27 ComplexType::ComplexType(XMLParser * a_parser, TTCN3Module * a_module, ConstructType a_construct)
28 : SimpleType(a_parser, a_module, a_construct)
29 , top(true)
30 , nillable(false)
31 , enumerated(false)
32 , embed(false)
33 , with_union(false)
34 , first_child(false)
35 , fromAll(false)
36 , max_alt(0)
37 , skipback(0)
38 , list(false)
39 , lastType()
40 , actualPath(empty_string)
41 , actfield(this)
42 , nameDep(NULL)
43 , nillable_field(NULL)
44 , basefield(NULL)
45 , cmode(CT_undefined_mode)
46 , resolved(No)
47 , parentTypeSubsGroup(NULL)
48 , complexfields()
49 , attribfields()
50 , enumfields()
51 , tagNames() {
52 xsdtype = n_complexType;
53 }
54
55 ComplexType::ComplexType(ComplexType & other)
56 : SimpleType(other)
57 , top(other.top)
58 , nillable(other.nillable)
59 , enumerated(other.enumerated)
60 , embed(other.embed)
61 , with_union(other.with_union)
62 , first_child(other.first_child)
63 , fromAll(other.fromAll)
64 , max_alt(other.max_alt)
65 , skipback(other.skipback)
66 , list(other.list)
67 , lastType(other.lastType)
68 , actualPath(other.actualPath)
69 , actfield(this)
70 , nameDep(other.nameDep)
71 , nillable_field(NULL)
72 , basefield(NULL)
73 , cmode(other.cmode)
74 , resolved(other.resolved)
75 , parentTypeSubsGroup(other.parentTypeSubsGroup) {
76 type.originalValueWoPrefix = other.type.originalValueWoPrefix;
77 for (List<AttributeType*>::iterator attr = other.attribfields.begin(); attr; attr = attr->Next) {
78 attribfields.push_back(new AttributeType(*attr->Data));
79 attribfields.back()->parent = this;
80 }
81
82 for (List<ComplexType*>::iterator field = other.complexfields.begin(); field; field = field->Next) {
83 complexfields.push_back(new ComplexType(*field->Data));
84 complexfields.back()->parent = this;
85 if(field->Data == other.basefield){
86 basefield = complexfields.back();
87 }else if(field->Data == other.nillable_field){
88 nillable_field = complexfields.back();
89 }
90 }
91
92 if (other.nameDep != NULL) {
93 SimpleType* dep = other.nameDep;
94 if(dep->getSubstitution() != NULL){
95 dep->getSubstitution()->addToNameDepList(this);
96 nameDep = dep->getSubstitution();
97 }else {
98 other.nameDep->addToNameDepList(this);
99 }
100 }
101 }
102
103 ComplexType::ComplexType(ComplexType * other)
104 : SimpleType(other->getParser(), other->getModule(), c_unknown)
105 , top(false)
106 , nillable(false)
107 , enumerated(false)
108 , embed(false)
109 , with_union(false)
110 , first_child(false)
111 , fromAll(false)
112 , max_alt(0)
113 , skipback(0)
114 , list(false)
115 , lastType()
116 , actualPath(empty_string)
117 , actfield(this)
118 , nameDep(NULL)
119 , nillable_field(NULL)
120 , basefield(NULL)
121 , cmode(CT_undefined_mode)
122 , resolved(No)
123 , parentTypeSubsGroup(NULL)
124 , complexfields()
125 , attribfields()
126 , enumfields()
127 , tagNames() {
128 xsdtype = n_complexType;
129 parent = other;
130 outside_reference = ReferenceData();
131 }
132
133 ComplexType::ComplexType(const SimpleType & other, CT_fromST c)
134 : SimpleType(other)
135 , top(true)
136 , nillable(false)
137 , enumerated(false)
138 , embed(false)
139 , with_union(false)
140 , first_child(false)
141 , fromAll(false)
142 , max_alt(0)
143 , skipback(0)
144 , list(false)
145 , lastType()
146 , actualPath(empty_string)
147 , actfield(this)
148 , nameDep(NULL)
149 , nillable_field(NULL)
150 , basefield(NULL)
151 , cmode(CT_simpletype_mode)
152 , resolved(No)
153 , parentTypeSubsGroup(NULL)
154 , complexfields()
155 , attribfields()
156 , enumfields()
157 , tagNames() {
158
159 if(c != fromTagSubstitution && c != fromTypeSubstitution){
160 module->replaceLastMainType(this);
161 module->setActualXsdConstruct(c_complexType);
162 }
163 construct = c_complexType;
164
165 switch (c) {
166 case fromTagUnion:
167 type.upload(Mstring("union"));
168 with_union = true;
169 xsdtype = n_union;
170 break;
171 case fromTagNillable:
172 addVariant(V_useNil);
173 type.upload(Mstring("record"));
174 break;
175 case fromTagComplexType:
176 type.upload(Mstring("record"));
177 xsdtype = n_complexType;
178 break;
179 case fromTagSubstitution:
180 type.upload(Mstring("union"));
181 name.upload(getName().originalValueWoPrefix + Mstring("_group"));
182 xsdtype = n_union;
183 subsGroup = this;
184 variant.clear();
185 hidden_variant.clear();
186 enumeration.modified = false;
187 value.modified = false;
188 pattern.modified = false;
189 length.modified = false;
190 whitespace.modified = false;
191 break;
192 case fromTypeSubstitution:
193 type.upload(Mstring("union"));
194 name.upload(getName().originalValueWoPrefix + Mstring("_derivations"));
195 xsdtype = n_union;
196 substitutionGroup = empty_string;
197 typeSubsGroup = this;
198 variant.clear();
199 hidden_variant.clear();
200 enumeration.modified = false;
201 value.modified = false;
202 pattern.modified = false;
203 length.modified = false;
204 whitespace.modified = false;
205 }
206 }
207
208 ComplexType::~ComplexType() {
209 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
210 delete field->Data;
211 field->Data = NULL;
212 }
213 complexfields.clear();
214
215 for (List<AttributeType*>::iterator field = attribfields.begin(); field; field = field->Next) {
216 delete field->Data;
217 field->Data = NULL;
218 }
219 attribfields.clear();
220 }
221
222 void ComplexType::loadWithValues() {
223 //Find the last field where the tag is found
224 if (this != actfield) {
225 actfield->loadWithValues();
226 return;
227 }
228
229 const XMLParser::TagAttributes & atts = parser->getActualTagAttributes();
230
231 switch (parser->getActualTagName()) {
232 case n_sequence:
233 if (!top && xsdtype != n_sequence && xsdtype != n_complexType && xsdtype != n_extension && xsdtype != n_restriction && xsdtype != n_element) {
234 //Create new record
235 ComplexType * rec = new ComplexType(this);
236 rec->type.upload(Mstring("record"));
237 rec->name.upload(Mstring("sequence"));
238 rec->addVariant(V_untagged);
239 rec->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
240 rec->setXsdtype(n_sequence);
241 complexfields.push_back(rec);
242 actfield = rec;
243 } else {
244 //Do not create new record, it is an embedded sequence
245 if (xsdtype == n_sequence && atts.minOccurs == 1 && atts.maxOccurs == 1) {
246 skipback += 1;
247 }
248 type.upload(Mstring("record"));
249 xsdtype = n_sequence;
250 setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
251 }
252 break;
253 case n_choice:
254 if (!top || xsdtype != n_group) {
255 //Create new union field
256 ComplexType * choice = new ComplexType(this);
257 choice->type.upload(Mstring("union"));
258 choice->name.upload(Mstring("choice"));
259 choice->setXsdtype(n_choice);
260 choice->addVariant(V_untagged);
261 choice->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
262 actfield = choice;
263 complexfields.push_back(choice);
264 } else {
265 xsdtype = n_choice;
266 type.upload(Mstring("union"));
267 }
268 break;
269 case n_all:
270 {
271 //Create the record of enumerated field
272 xsdtype = n_all;
273 ComplexType * enumField = new ComplexType(this);
274 enumField->setTypeValue(Mstring("enumerated"));
275 enumField->setNameValue(Mstring("order"));
276 enumField->setBuiltInBase(Mstring("string"));
277 enumField->enumerated = true;
278 enumField->setMinMaxOccurs(0, ULLONG_MAX, false);
279 setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
280 addVariant(V_useOrder);
281 complexfields.push_back(enumField);
282 if (atts.minOccurs == 0) {
283 isOptional = true;
284 }
285 break;
286 }
287 case n_restriction:
288 mode = restrictionMode;
289 //If it is an xsd:union then call SimpleType::loadWithValues
290 if (parent != NULL && parent->with_union) {
291 SimpleType::loadWithValues();
292 break;
293 }
294 if (cmode == CT_simpletype_mode) {
295 //if it is from a SimpleType, then create a base field
296 ComplexType * f = new ComplexType(this);
297 f->name.upload(Mstring("base"));
298 f->type.upload(atts.base);
299 f->setReference(atts.base);
300 f->addVariant(V_untagged);
301 complexfields.push_back(f);
302 basefield = f;
303 actfield = f;
304 } else if (cmode == CT_complextype_mode) {
305 setReference(atts.base);
306 xsdtype = n_restriction;
307 }
308 break;
309 case n_extension:
310 mode = extensionMode;
311 if (cmode == CT_simpletype_mode) {
312 //if it is from a SimpleType, then create a base field
313 ComplexType * f = new ComplexType(this);
314 f->name.upload(Mstring("base"));
315 f->type.upload(atts.base);
316 f->setReference(atts.base);
317 f->addVariant(V_untagged);
318 complexfields.push_back(f);
319 basefield = f;
320 actfield = f;
321 } else if (cmode == CT_complextype_mode) {
322 setReference(atts.base);
323 xsdtype = n_extension;
324 }
325 break;
326 case n_element:
327 {
328 if (atts.nillable) {
329 if(cmode == CT_simpletype_mode){
330 //If a simple top level element is nillable
331 ComplexType * nilrec = new ComplexType(this);
332 if (atts.type.empty()) {
333 nilrec->type.upload(Mstring("record"));
334 } else {
335 nilrec->type.upload(atts.type);
336 }
337 nilrec->name.upload(Mstring("content"));
338 nilrec->isOptional = true;
339 nilrec->nillable = true;
340 setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
341 complexfields.push_back(nilrec);
342 type.upload(Mstring("record"));
343 name.upload(atts.name);
344 actfield = nilrec;
345 nillable_field = nilrec;
346 } else {
347 //From a complexType element is nillable
348 ComplexType * record = new ComplexType(this);
349 ComplexType * nilrec = new ComplexType(record);
350 if (atts.type.empty()) {
351 nilrec->type.upload(Mstring("record"));
352 } else {
353 nilrec->type.upload(atts.type);
354 }
355 record->name.upload(atts.name);
356 record->type.upload(Mstring("record"));
357 record->complexfields.push_back(nilrec);
358 record->addVariant(V_useNil);
359 record->nillable_field = nilrec;
360 record->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
361
362 nilrec->name.upload(Mstring("content"));
363 nilrec->nillable = true;
364 nilrec->isOptional = true;
365 nilrec->tagNames.push_back(parser->getActualTagName());
366 complexfields.push_back(record);
367 actfield = nilrec;
368 }
369 }else {
370 //It is a simple element
371 ComplexType* c = new ComplexType(this);
372 c->setXsdtype(n_element);
373 c->type.upload(atts.type);
374 c->name.upload(atts.name);
375 c->setReference(atts.type);
376 c->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
377 c->applyDefaultAttribute(atts.default_);
378 c->applyFixedAttribute(atts.fixed);
379 c->setElementFormAs(atts.form);
380 if (atts.ref.empty()) {
381 c->setReference(atts.type);
382 } else {
383 c->applyRefAttribute(atts.ref);
384 c->name.upload(atts.ref.getValueWithoutPrefix(':'));
385 c->type.upload(atts.ref);
386 }
387 c->applySubstitionGroupAttribute(atts.substitionGroup);
388 c->applyBlockAttribute(atts.block);
389 actfield = c;
390
391 //Inside all have some special conditions
392 if (xsdtype == n_all) {
393 if (atts.minOccurs > 1) {
394 printError(getModule()->getSchemaname(), name.convertedValue,
395 Mstring("Inside <all>, minOccurs must be 0 or 1"));
396 TTCN3ModuleInventory::incrNumErrors();
397 }
398 if (atts.maxOccurs != 1) {
399 printError(getModule()->getSchemaname(), name.convertedValue,
400 Mstring("Inside <all>, maxOccurs must be 1"));
401 TTCN3ModuleInventory::incrNumErrors();
402 }
403 c->fromAll = true;
404 complexfields.push_back(c);
405 if (isOptional) {
406 c->isOptional = true;
407 }
408 } else {
409 complexfields.push_back(c);
410 }
411 }
412 break;
413 }
414 case n_attribute:
415 {
416 AttributeType * attribute = new AttributeType(this);
417 attribute->addVariant(V_attribute);
418 attribute->applyMinMaxOccursAttribute(0, 1);
419 attribute->setXsdtype(n_attribute);
420 attribute->applyDefaultAttribute(atts.default_);
421 attribute->applyFixedAttribute(atts.fixed);
422 attribute->setUseVal(atts.use);
423 attribute->setAttributeFormAs(atts.form);
424 lastType = n_attribute;
425 if (atts.ref.empty()) {
426 attribute->setNameOfField(atts.name);
427 attribute->setTypeOfField(atts.type);
428 attribute->setReference(atts.type, true);
429 } else {
430 attribute->applyRefAttribute(atts.ref);
431 }
432 actfield = attribute;
433
434 //In case of nillable parent it is difficult...
435 if (nillable && parent != NULL) {
436 parent->attribfields.push_back(attribute);
437 attribute->parent = parent;
438 } else if (nillable && !complexfields.empty() && parent == NULL) {
439 complexfields.back()->attribfields.push_back(attribute);
440 } else if (parent != NULL && (parent->mode == extensionMode || parent->mode == restrictionMode) && name.convertedValue == Mstring("base")) {
441 parent->attribfields.push_back(attribute);
442 attribute->parent = parent;
443 } else {
444 attribfields.push_back(attribute);
445 }
446 break;
447 }
448 case n_any:
449 {
450 ComplexType * any = new ComplexType(this);
451 any->name.upload(Mstring("elem"));
452 any->type.upload(Mstring("xsd:string"));
453 any->applyNamespaceAttribute(V_anyElement, atts.namespace_);
454 any->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
455 any->setXsdtype(n_any);
456 complexfields.push_back(any);
457 break;
458 }
459 case n_anyAttribute:
460 {
461 AttributeType * anyattr = new AttributeType(this);
462 anyattr->setXsdtype(n_anyAttribute);
463 anyattr->setNameOfField(Mstring("attr"));
464 anyattr->setTypeValue(Mstring("xsd:string"));
465 anyattr->setToAnyAttribute();
466 anyattr->applyMinMaxOccursAttribute(0, ULLONG_MAX);
467 anyattr->addNameSpaceAttribute(atts.namespace_);
468 actfield = anyattr;
469
470 //In case of nillable parent it is difficult...
471 if (nillable && parent != NULL) {
472 parent->attribfields.push_back(anyattr);
473 anyattr->parent = parent;
474 } else if (nillable && !complexfields.empty() && parent == NULL) {
475 complexfields.back()->attribfields.push_back(anyattr);
476 } else if (parent != NULL && (parent->mode == extensionMode || parent->mode == restrictionMode) && name.convertedValue == Mstring("base")) {
477 parent->attribfields.push_back(anyattr);
478 anyattr->parent = parent;
479 } else {
480 attribfields.push_back(anyattr);
481 }
482 break;
483 }
484 case n_attributeGroup:
485 if (!atts.ref.empty()) {
486 ComplexType * g = new ComplexType(this);
487 g->setXsdtype(n_attributeGroup);
488 g->setReference(atts.ref);
489 complexfields.push_back(g);
490 actfield = g;
491 } else {
492 xsdtype = n_attributeGroup;
493 name.upload(Mstring(atts.name));
494 setInvisible();
495 }
496 break;
497 case n_group:
498 if (atts.ref.empty()) {
499 //It is a definition
500 xsdtype = n_group;
501 name.upload(atts.name);
502 } else {
503 //It is a reference
504 ComplexType* group = new ComplexType(this);
505 group->setXsdtype(n_group);
506 group->name.upload(atts.name);
507 group->setReference(Mstring(atts.ref));
508 group->setMinMaxOccurs(atts.minOccurs, atts.maxOccurs);
509 complexfields.push_back(group);
510 actfield = group;
511 }
512 break;
513 case n_union:
514 {
515 with_union = true;
516 xsdtype = n_union;
517 type.upload(Mstring("union"));
518 addVariant(V_useUnion);
519 if (!atts.memberTypes.empty()) {
520 List<Mstring> types;
521 //Get the union values
522 expstring_t valueToSplitIntoTokens = mcopystr(atts.memberTypes.c_str());
523 char * token;
524 token = strtok(valueToSplitIntoTokens, " ");
525 while (token != NULL) {
526 types.push_back(Mstring(token));
527 token = strtok(NULL, " ");
528 }
529 Free(valueToSplitIntoTokens);
530
531 //Create the union elements and push into the container
532 for (List<Mstring>::iterator memberType = types.begin(); memberType; memberType = memberType->Next) {
533 Mstring tmp_name = memberType->Data.getValueWithoutPrefix(':');
534 ComplexType * f = new ComplexType(this);
535 f->name.upload(tmp_name);
536 f->type.upload(memberType->Data);
537 f->setXsdtype(n_simpleType);
538 f->setReference(memberType->Data);
539 complexfields.push_back(f);
540 }
541 }
542 break;
543 }
544 case n_simpleType:
545 case n_simpleContent:
546 {
547 xsdtype = parser->getActualTagName();
548 cmode = CT_simpletype_mode;
549 Mstring fieldname;
550 if (with_union) {
551 if (max_alt == 0) {
552 fieldname = Mstring("alt_");
553 } else {
554 fieldname = mprintf("alt_%d", max_alt);
555 }
556 max_alt++;
557 ComplexType * field = new ComplexType(this);
558 field->name.upload(fieldname);
559 field->setXsdtype(n_simpleType);
560 field->addVariant(V_nameAs, empty_string, true);
561 complexfields.push_back(field);
562 actfield = field;
563 }
564 break;
565 }
566 case n_complexType:
567 name.upload(atts.name);
568 type.upload(Mstring("record"));
569 applyAbstractAttribute(atts.abstract);
570 applySubstitionGroupAttribute(atts.substitionGroup);
571 applyBlockAttribute(atts.block);
572 // fall through
573 case n_complexContent:
574 tagNames.push_back(parser->getActualTagName());
575 cmode = CT_complextype_mode;
576 if (atts.mixed) {
577 ComplexType * mixed = new ComplexType(this);
578 mixed->name.upload(Mstring("embed_values"));
579 mixed->type.upload(Mstring("xsd:string"));
580 mixed->setMinMaxOccurs(0, ULLONG_MAX, false);
581 mixed->embed = true;
582 complexfields.push_back(mixed);
583 addVariant(V_embedValues);
584 }
585 break;
586 case n_list:
587 if (parent != NULL && parent->basefield == this) {
588 parent->list = true;
589 parent->SimpleType::loadWithValues();
590 parent->basefield = NULL;
591 setInvisible();
592 break;
593 }
594 case n_length:
595 case n_minLength:
596 case n_maxLength:
597 case n_pattern:
598 case n_enumeration:
599 case n_whiteSpace:
600 case n_minInclusive:
601 case n_maxInclusive:
602 case n_minExclusive:
603 case n_maxExclusive:
604 case n_totalDigits:
605 case n_fractionDigits:
606 SimpleType::loadWithValues();
607 break;
608 case n_label:
609 addComment(Mstring("LABEL:"));
610 break;
611 case n_definition:
612 addComment(Mstring("DEFINITION:"));
613 break;
614 default:
615 break;
616 }
617 }
618
619 // called from endelementHandler
620 void ComplexType::modifyValues() {
621 if (this != actfield) {
622 actfield->modifyValues();
623 return;
624 }
625 if (xsdtype == n_sequence) {
626 skipback = skipback - 1;
627 }
628
629 //embedded simpletype with list in element
630 if(xsdtype == n_simpleType && list) {
631 list = false;
632 return;
633 }
634
635
636 if ( parent != NULL &&
637 (xsdtype == n_element ||
638 xsdtype == n_complexType ||
639 xsdtype == n_complexContent ||
640 xsdtype == n_all ||
641 xsdtype == n_attribute ||
642 xsdtype == n_anyAttribute ||
643 xsdtype == n_choice ||
644 xsdtype == n_group ||
645 xsdtype == n_attributeGroup ||
646 xsdtype == n_extension ||
647 xsdtype == n_restriction ||
648 (xsdtype == n_simpleType && !list) ||
649 xsdtype == n_simpleContent ||
650 (xsdtype == n_sequence && skipback < 0)
651 )) {
652 if (!tagNames.empty() && tagNames.back() == parser->getParentTagName()) {
653 if (nillable && tagNames.back() == n_element) {
654 parent->modifyValues();
655 }
656 tagNames.pop_back();
657 } else if (tagNames.empty()) {
658 parent->actfield = parent;
659 parent->lastType = xsdtype;
660 }
661 }
662 }
663
664 void ComplexType::referenceResolving() {
665 if (resolved != No) return; // nothing to do
666 if(this == subsGroup){
667 resolved = Yes;
668 return;
669 }
670 resolved = InProgress;
671 for (List<ComplexType*>::iterator ct = complexfields.begin(); ct; ct = ct->Next) {
672 // Referenece resolving of ComplexTypes
673 ct->Data->referenceResolving();
674 }
675 for (List<AttributeType*>::iterator attr = attribfields.begin(); attr; attr = attr->Next) {
676 //Reference resolving for Attributes
677 resolveAttribute(attr->Data);
678 }
679
680 reference_resolving_funtion();
681
682 if(!substitutionGroup.empty()){
683 addToSubstitutions();
684 }
685 resolved = Yes;
686 }
687
688 void ComplexType::reference_resolving_funtion() {
689 //Every child element references are resolved here.
690 if (outside_reference.empty() && basefield == NULL) {
691 //Its not in the resolveElement function because we need the built in type
692 //reference too, and then the outside_reference is empty.
693 if(xsdtype == n_element){
694 collectElementTypes(NULL, NULL);
695 }
696 return;
697 }
698
699 SimpleType * st = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(this, want_BOTH);
700 if (st == NULL && basefield == NULL) {
701 printError(module->getSchemaname(), name.convertedValue,
702 "Reference for a non-defined type: " + getReference().repr());
703 TTCN3ModuleInventory::getInstance().incrNumErrors();
704 outside_reference.set_resolved(NULL);
705 return;
706 }
707
708 resolveAttributeGroup(st);
709
710 resolveGroup(st);
711
712 resolveElement(st);
713
714 resolveSimpleTypeExtension();
715
716 resolveSimpleTypeRestriction();
717
718 resolveComplexTypeExtension();
719
720 resolveComplexTypeRestriction();
721
722 resolveUnion(st);
723
724 addToTypeSubstitutions();
725
726 }
727
728 void ComplexType::setParent(ComplexType * par, SimpleType * child) {
729 child->parent = par;
730 }
731
732 void ComplexType::applyReference(const SimpleType & other, const bool on_attributes) {
733 type.convertedValue = other.getType().convertedValue;
734 type.originalValueWoPrefix = other.getType().convertedValue.getValueWithoutPrefix(':');
735
736 if (other.getMinOccurs() > minOccurs || other.getMaxOccurs() < maxOccurs) {
737 if (!on_attributes) {
738 expstring_t temp = memptystr();
739 temp = mputprintf(
740 temp,
741 "The occurrence range (%llu .. %llu) of the element (%s) is not compatible "
742 "with the occurrence range (%llu .. %llu) of the referenced element.",
743 minOccurs,
744 maxOccurs,
745 name.originalValueWoPrefix.c_str(),
746 other.getMinOccurs(),
747 other.getMaxOccurs());
748 printError(module->getSchemaname(), parent->getName().originalValueWoPrefix,
749 Mstring(temp));
750 Free(temp);
751 TTCN3ModuleInventory::getInstance().incrNumErrors();
752 }
753 } else {
754 minOccurs = llmax(minOccurs, other.getMinOccurs());
755 maxOccurs = llmin(maxOccurs, other.getMaxOccurs());
756 }
757
758 for (List<Mstring>::iterator var = other.getVariantRef().begin(); var; var = var->Next) {
759 bool found = false;
760 for (List<Mstring>::iterator var1 = variant.begin(); var1; var1 = var1->Next) {
761 if (var->Data == var1->Data) {
762 found = true;
763 break;
764 }
765 }
766 if (!found) {
767 variant.push_back(var->Data);
768 variant_ref.push_back(var->Data);
769 }
770 }
771
772 builtInBase = other.getBuiltInBase();
773
774 length.applyReference(other.getLength());
775 pattern.applyReference(other.getPattern());
776 enumeration.applyReference(other.getEnumeration());
777 whitespace.applyReference(other.getWhitespace());
778 value.applyReference(other.getValue());
779 }
780
781 void ComplexType::nameConversion(NameConversionMode conversion_mode, const List<NamespaceType> & ns) {
782 if(!visible) return;
783 switch (conversion_mode) {
784 case nameMode:
785 nameConversion_names(ns);
786 break;
787 case typeMode:
788 nameConversion_types(ns);
789 break;
790 case fieldMode:
791 nameConversion_fields(ns);
792 break;
793 }
794 }
795
796 void ComplexType::nameConversion_names(const List<NamespaceType> &) {
797 Mstring res, var(module->getTargetNamespace());
798 XSDName2TTCN3Name(name.convertedValue, TTCN3ModuleInventory::getInstance().getTypenames(), type_name, res, var);
799 name.convertedValue = res;
800 bool found = false;
801 for (List<Mstring>::iterator vari = variant.begin(); vari; vari = vari->Next) {
802 if (vari->Data == "\"untagged\"") {
803 found = true;
804 break;
805 }
806 }
807 if (!found) {
808 addVariant(V_onlyValue, var);
809 }
810 for (List<SimpleType*>::iterator dep = nameDepList.begin(); dep; dep = dep->Next) {
811 dep->Data->setTypeValue(res);
812 }
813 }
814
815 void ComplexType::nameConversion_types(const List<NamespaceType> & ns) {
816 attribfields.sort(compareAttributeNameSpaces);
817 attribfields.sort(compareAttributeTypes);
818 for (List<AttributeType*>::iterator field = attribfields.begin(); field; field = field->Next) {
819 field->Data->nameConversion(typeMode, ns);
820 }
821
822 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
823 field->Data->nameConversion_types(ns);
824 }
825
826 Mstring prefix, uri, typeValue;
827
828 if (type.convertedValue == "record" ||
829 type.convertedValue == "set" ||
830 type.convertedValue == "union" ||
831 type.convertedValue == "enumerated") {
832 return;
833 }
834
835 prefix = type.convertedValue.getPrefix(':');
836 typeValue = type.convertedValue.getValueWithoutPrefix(':');
837
838 for (List<NamespaceType>::iterator namesp = ns.begin(); namesp; namesp = namesp->Next) {
839 if (prefix == namesp->Data.prefix) {
840 uri = namesp->Data.uri;
841 break;
842 }
843 }
844
845 QualifiedName in(uri, typeValue); // ns uri + original name
846
847 // Check all known types
848 QualifiedNames::iterator origTN = TTCN3ModuleInventory::getInstance().getTypenames().begin();
849 for (; origTN; origTN = origTN->Next) {
850 if (origTN->Data == in) {
851 QualifiedName tmp_name(module->getTargetNamespace(), name.convertedValue);
852 if (origTN->Data != tmp_name){
853 break;
854 }
855 }
856 }
857
858 if (origTN != NULL) {
859 setTypeValue(origTN->Data.name);
860 } else {
861 Mstring res, var;
862 XSDName2TTCN3Name(typeValue, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name, res, var, type.no_replace);
863 setTypeValue(res);
864 }
865 }
866
867 void ComplexType::nameConversion_fields(const List<NamespaceType> & ns) {
868 QualifiedNames used_field_names;
869
870 for (List<AttributeType*>::iterator field = attribfields.begin(); field; field = field->Next) {
871 field->Data->nameConversion_names(used_field_names);
872 }
873
874 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
875 if (field->Data->getMinOccurs() == 0 && field->Data->getMaxOccurs() == 0) {
876 continue;
877 }
878 if (!field->Data->isVisible()) {
879 continue;
880 }
881
882 field->Data->nameConversion_fields(ns);
883
884 Mstring prefix = field->Data->getType().convertedValue.getPrefix(':');
885 Mstring typeValue = field->Data->getType().convertedValue.getValueWithoutPrefix(':');
886
887 Mstring res, var;
888 var = getModule()->getTargetNamespace();
889 XSDName2TTCN3Name(typeValue, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name, res, var);
890
891 field->Data->addVariant(V_onlyValue, var);
892 var = getModule()->getTargetNamespace();
893
894 if (field->Data->getName().list_extension) {
895 field->Data->useNameListProperty();
896 XSDName2TTCN3Name(field->Data->getName().convertedValue,
897 used_field_names, field_name, res, var);
898 field->Data->setNameValue(res);
899 bool found_in_variant = false;
900 for (List<Mstring>::iterator vari = field->Data->getVariant().begin(); vari; vari = vari->Next) {
901 if (vari->Data == Mstring("\"untagged\"")) {
902 found_in_variant = true;
903 break;
904 }
905 }
906 if (!field->Data->getName().originalValueWoPrefix.empty() &&
907 field->Data->getName().originalValueWoPrefix != "sequence" &&
908 field->Data->getName().originalValueWoPrefix != "choice" &&
909 field->Data->getName().originalValueWoPrefix != "elem" &&
910 !found_in_variant) {
911 field->Data->addVariant(V_nameAs, field->Data->getName().originalValueWoPrefix);
912 }
913
914
915 if (!found_in_variant) {
916 field->Data->addVariant(V_untagged, empty_string, true);
917 }
918 } else {
919 XSDName2TTCN3Name(field->Data->getName().convertedValue,
920 used_field_names, field_name, res, var);
921 field->Data->setNameValue(res);
922 field->Data->addVariant(V_onlyValue, var);
923 }
924
925 }
926 }
927
928 void ComplexType::setFieldPaths(Mstring path) {
929 if (path.empty()) {
930 if (!top) {
931 Mstring field_prefix = empty_string;
932 if(parent->minOccurs == 0 && parent->maxOccurs == ULLONG_MAX){
933 field_prefix = "[-].";
934 }
935 path = field_prefix + getName().convertedValue;
936 actualPath = field_prefix + getName().convertedValue;
937 }else {
938 actualPath = getName().convertedValue;
939 }
940 } else if (parent != NULL && (parent->getMinOccurs() != 1 || parent->getMaxOccurs() != 1) &&
941 (parent->getName().list_extension || parent->mode == listMode)) {
942 path = path + Mstring("[-].") + getName().convertedValue;
943 actualPath = path;
944 } else {
945 path = path + Mstring(".") + getName().convertedValue;
946 actualPath = path;
947 }
948
949 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
950 field->Data->setFieldPaths(path);
951 }
952 for (List<AttributeType*>::iterator attr = attribfields.begin(); attr; attr = attr->Next) {
953 attr->Data->setFieldPath(path);
954 }
955 }
956
957 void ComplexType::finalModification2() {
958 //Call SimpleType finalModification
959 SimpleType::finalModification();
960
961 //Set isOptional field
962 isOptional = isOptional || (minOccurs == 0 && maxOccurs == 1);
963
964 //
965 List<Mstring> enumNames;
966 for (List<ComplexType*>::iterator field = complexfields.begin(), nextField; field; field = nextField) {
967 nextField = field->Next;
968 //Remove invisible fields
969 if ((field->Data->minOccurs == 0 && field->Data->maxOccurs == 0) || !field->Data->isVisible()) {
970 delete field->Data;
971 field->Data = NULL;
972 complexfields.remove(field);
973 } else {
974 //Recursive call
975 field->Data->finalModification2();
976 //collect <xsd:all> elements
977 if (field->Data->fromAll) {
978 enumNames.push_back(field->Data->getName().convertedValue);
979 }
980 }
981 }
982
983 ComplexType * embedField = NULL;
984 ComplexType * enumField = NULL;
985
986 //Find the embed and order fields, and remove them
987 for (List<ComplexType*>::iterator field = complexfields.begin(), nextField; field; field = nextField) {
988 nextField = field->Next;
989 if (field->Data->embed) {
990 embedField = new ComplexType(*field->Data);
991 embedField->parent = this;
992 delete field->Data;
993 field->Data = NULL;
994 complexfields.remove(field);
995 } else if (field->Data->enumerated) {
996 enumField = new ComplexType(*field->Data);
997 enumField->parent = this;
998 delete field->Data;
999 field->Data = NULL;
1000 complexfields.remove(field);
1001 }
1002 }
1003
1004 if (enumField != NULL) {
1005 //Insert the order field in the front
1006 complexfields.push_front(enumField);
1007 //Push the field names into the order field
1008 for (List<Mstring>::iterator field = enumNames.begin(); field; field = field->Next) {
1009 enumField->enumfields.push_back(field->Data);
1010 }
1011 }
1012
1013 if (embedField != NULL) {
1014 //Insert the embed field to the front
1015 complexfields.push_front(embedField);
1016 }
1017
1018 if (with_union) {
1019 unsigned number = 0;
1020 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
1021 if (field->Data->name.convertedValue.foundAt("alt_") == field->Data->name.convertedValue.c_str()) {
1022 if (number == 0) {
1023 field->Data->name.upload(Mstring("alt_"));
1024 } else {
1025 field->Data->name.upload(Mstring(mprintf("alt_%d", number)));
1026 }
1027 number++;
1028 }
1029 }
1030 }
1031
1032 AttributeType * anyAttr = NULL;
1033 for (List<AttributeType*>::iterator field = attribfields.begin(), nextField; field; field = nextField) {
1034 nextField = field->Next;
1035 field->Data->applyUseAttribute();
1036 //Find anyattribute, and remove it
1037 if (field->Data->isAnyAttribute()) {
1038 anyAttr = new AttributeType(*field->Data);
1039 setParent(this, anyAttr);
1040 delete field->Data;
1041 field->Data = NULL;
1042 attribfields.remove(field);
1043 } else if (field->Data->getUseVal() == prohibited || !field->Data->isVisible()) {
1044 //Not visible attribute removed
1045 delete field->Data;
1046 field->Data = NULL;
1047 attribfields.remove(field);
1048 } else {
1049 field->Data->SimpleType::finalModification();
1050 }
1051 }
1052
1053 //Push anyattribute to the front
1054 if (anyAttr != NULL) {
1055 anyAttr->applyNamespaceAttribute(V_anyAttributes);
1056 attribfields.push_back(anyAttr);
1057 }
1058
1059 //Substitution group ordering
1060 if(subsGroup == this || typeSubsGroup == this){ //We are a generated substitution group
1061 //Substitution group never empty
1062 ComplexType * front = complexfields.front();
1063 List<ComplexType*>::iterator it = complexfields.begin();
1064 complexfields.remove(it);
1065 complexfields.sort(compareComplexTypeNameSpaces);
1066 complexfields.sort(compareTypes);
1067 complexfields.push_front(front);
1068 }
1069 }
1070
1071 void ComplexType::finalModification() {
1072 finalModification2();
1073 setFieldPaths(empty_string);
1074 List<Mstring> container;
1075 collectVariants(container);
1076 variant.clear();
1077 variant = container;
1078 }
1079
1080 void ComplexType::printToFile(FILE * file) {
1081 printToFile(file, 0, false);
1082 }
1083
1084 void ComplexType::printToFile(FILE * file, const unsigned level, const bool is_union) {
1085 if (!isVisible()) {
1086 return;
1087 }
1088 printComment(file, level);
1089 if (top) {
1090 fprintf(file, "type ");
1091 if(mode == listMode){
1092 printMinOccursMaxOccurs(file, is_union);
1093 fprintf(file, "%s", type.convertedValue.c_str());
1094 }else {
1095 fprintf(file, "%s %s", type.convertedValue.c_str(), name.convertedValue.c_str());
1096 }
1097 fprintf(file, "\n{\n");
1098
1099 if (attribfields.empty() && complexfields.empty()) {
1100 fprintf(file, "\n");
1101 }
1102
1103 for (List<ComplexType*>::iterator c = complexfields.begin(), nextField; c; c = nextField) {
1104 nextField = c->Next;
1105 if (c->Data->embed || c->Data->enumerated) {
1106 c->Data->printToFile(file, level + 1, is_union);
1107 if (c->Next != NULL || !attribfields.empty()) {
1108 fprintf(file, ",\n");
1109 } else {
1110 fprintf(file, "\n");
1111 }
1112 delete c->Data;
1113 c->Data = NULL;
1114 complexfields.remove(c);
1115 }
1116 }
1117
1118 for (List<AttributeType*>::iterator f = attribfields.begin(); f; f = f->Next) {
1119 f->Data->printToFile(file, level + 1);
1120 if (f->Next != NULL || !complexfields.empty()) {
1121 fprintf(file, ",\n");
1122 } else {
1123 fprintf(file, "\n");
1124 }
1125 }
1126
1127 for (List<ComplexType*>::iterator c = complexfields.begin(); c; c = c->Next) {
1128 c->Data->printToFile(file, level + 1, is_union);
1129 if (c->Next != NULL) {
1130 fprintf(file, ",\n");
1131 } else {
1132 fprintf(file, "\n");
1133 }
1134 }
1135 } else {
1136 const bool field_is_record = getType().convertedValue == Mstring("record");
1137 const bool field_is_union = getType().convertedValue == "union";
1138 if (complexfields.empty() && attribfields.empty() && (field_is_record || field_is_union)) {
1139 if (field_is_record) {
1140 indent(file, level);
1141 printMinOccursMaxOccurs(file, is_union);
1142 fprintf(file, "%s {\n", getType().convertedValue.c_str());
1143 indent(file, level);
1144 fprintf(file, "} %s", getName().convertedValue.c_str());
1145 if (isOptional) {
1146 fprintf(file, " optional");
1147 }
1148 } else if (field_is_union) {
1149 indent(file, level);
1150 printMinOccursMaxOccurs(file, is_union);
1151 fprintf(file, "%s {\n", getType().convertedValue.c_str());
1152 indent(file, level + 1);
1153 fprintf(file, "record length(0 .. 1) of enumerated { NULL_ } choice\n");
1154 indent(file, level);
1155 fprintf(file, "} %s", getName().convertedValue.c_str());
1156 if (isOptional) {
1157 fprintf(file, " optional");
1158 }
1159 }
1160 } else {
1161 indent(file, level);
1162 if (getEnumeration().modified) {
1163 if (isFloatType(getBuiltInBase())) {
1164 fprintf(file, "%s (", type.convertedValue.c_str());
1165 getEnumeration().sortFacets();
1166 getEnumeration().printToFile(file);
1167 fprintf(file, ")");
1168 } else {
1169 printMinOccursMaxOccurs(file, with_union);
1170 fprintf(file, "enumerated {\n");
1171 //getEnumeration().sortFacets();
1172 getEnumeration().printToFile(file, level);
1173 fprintf(file, "\n");
1174 indent(file, level);
1175 fprintf(file, "} ");
1176 }
1177 } else {
1178 int multiplicity = multi(module, getReference(), this);
1179 if ((multiplicity > 1) && getReference().get_ref()) {
1180 fprintf(file, "%s.", getReference().get_ref()->getModule()->getModulename().c_str());
1181 }
1182 if (field_is_record || field_is_union) {
1183 printMinOccursMaxOccurs(file, with_union, !first_child || parent->getXsdtype() != n_choice);
1184 fprintf(file, "%s {\n", getType().convertedValue.c_str());
1185 for (List<AttributeType*>::iterator f = attribfields.begin(); f; f = f->Next) {
1186 f->Data->printToFile(file, level + 1);
1187 if (f->Next != NULL || !complexfields.empty()) {
1188 fprintf(file, ",\n");
1189 } else {
1190 fprintf(file, "\n");
1191 }
1192 }
1193
1194 for (List<ComplexType*>::iterator c = complexfields.begin(); c; c = c->Next) {
1195 c->Data->printToFile(file, level + 1, is_union);
1196 if (c->Next != NULL) {
1197 fprintf(file, ",\n");
1198 } else {
1199 fprintf(file, "\n");
1200 }
1201 }
1202 } else {
1203 printMinOccursMaxOccurs(file, with_union, !first_child);
1204 fprintf(file, "%s ", getType().convertedValue.c_str());
1205 if (getName().convertedValue == Mstring("order") && getType().convertedValue == Mstring("enumerated")) {
1206 fprintf(file, "{\n");
1207 for (List<Mstring>::iterator e = enumfields.begin(); e; e = e->Next) {
1208 indent(file, level + 1);
1209 fprintf(file, "%s", e->Data.c_str());
1210 if (e->Next != NULL) {
1211 fprintf(file, ",\n");
1212 } else {
1213 fprintf(file, "\n");
1214 }
1215 }
1216 indent(file, level);
1217 fprintf(file, "} ");
1218 }
1219 }
1220 }
1221 if (field_is_record || field_is_union) {
1222 indent(file, level);
1223 fprintf(file, "} ");
1224 }
1225
1226 fprintf(file, "%s", getName().convertedValue.c_str());
1227 getPattern().printToFile(file);
1228 getValue().printToFile(file);
1229 getLength().printToFile(file);
1230 if (!with_union && isOptional) {
1231 fprintf(file, " optional");
1232 }
1233 }
1234 }
1235
1236 if (top) {
1237 fprintf(file, "}");
1238 if(mode == listMode){
1239 fprintf(file, " %s", name.convertedValue.c_str());
1240 }
1241 printVariant(file);
1242 fprintf(file, ";\n\n\n");
1243 }
1244 }
1245
1246 void ComplexType::collectVariants(List<Mstring>& container) {
1247
1248 if (e_flag_used || !isVisible()) {
1249 return;
1250 }
1251
1252 if (top) {
1253 bool useUnionVariantWhenMainTypeIsRecordOf = false;
1254 for (List<Mstring>::iterator var = variant.end(); var; var = var->Prev) {
1255 if ((minOccurs != 1 || maxOccurs != 1) && (var->Data == "\"useUnion\"")) { // main type is a record of
1256 useUnionVariantWhenMainTypeIsRecordOf = true; // TR HL15893
1257 } else {
1258 container.push_back(Mstring("variant ") + Mstring(var->Data.c_str()) + Mstring(";\n"));
1259 }
1260 }
1261 if (useUnionVariantWhenMainTypeIsRecordOf) {
1262 container.push_back(Mstring("variant ([-]) \"useUnion\";\n"));
1263 }
1264 for (List<Mstring>::iterator var = hidden_variant.end(); var; var = var->Prev) {
1265 container.push_back(Mstring("//variant ") + Mstring(var->Data.c_str()) + Mstring(";\n"));
1266 }
1267 }
1268
1269 //Collect variants of attributes
1270 for (List<AttributeType*>::iterator field = attribfields.begin(); field; field = field->Next) {
1271 field->Data->collectVariants(container);
1272 }
1273
1274 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
1275
1276 if (!field->Data->isVisible()) {
1277 continue;
1278 }
1279
1280 if (field->Data->getVariant().empty() && field->Data->getHiddenVariant().empty() &&
1281 field->Data->complexfields.empty() && field->Data->attribfields.empty() &&
1282 field->Data->enumeration.variants.empty()) {
1283 continue;
1284 }
1285
1286 bool already_used = false;
1287
1288 for (List<Mstring>::iterator var2 = field->Data->getVariant().end(); var2; var2 = var2->Prev) {
1289 if (var2->Data == "\"untagged\"" && !already_used) {
1290 container.push_back(Mstring("variant (") + field->Data->actualPath + Mstring(") ") + Mstring(var2->Data.c_str()) + Mstring(";\n"));
1291 already_used = true;
1292 } else {
1293 if ((field->Data->getMinOccurs() != 1 || field->Data->getMaxOccurs() != 1) &&
1294 (field->Data->getName().list_extension || var2->Data == "\"useUnion\"")) {
1295 container.push_back(Mstring("variant (") + field->Data->actualPath + Mstring("[-]) ") + Mstring(var2->Data.c_str()) + Mstring(";\n"));
1296 } else if (var2->Data != "\"untagged\"") {
1297 container.push_back(Mstring("variant (") + field->Data->actualPath + Mstring(") ") + Mstring(var2->Data.c_str()) + Mstring(";\n"));
1298 }
1299 }
1300 }
1301 for (List<Mstring>::iterator hidden_var = field->Data->getHiddenVariant().end();
1302 hidden_var; hidden_var = hidden_var->Prev) {
1303 if ((field->Data->getMinOccurs() != 1 || field->Data->getMaxOccurs() != 1) &&
1304 field->Data->getName().list_extension) {
1305 container.push_back(Mstring("//variant (") + field->Data->actualPath + Mstring("[-]) ") + Mstring(hidden_var->Data.c_str()) + Mstring(";\n"));
1306 } else {
1307 container.push_back(Mstring("//variant (") + field->Data->actualPath + Mstring(") ") + Mstring(hidden_var->Data.c_str()) + Mstring(";\n"));
1308 }
1309 }
1310
1311 if(field->Data->enumeration.modified){
1312 Mstring path = empty_string;
1313 if(field->Data->getMinOccurs() != 1 && field->Data->getMaxOccurs() != 1){
1314 path = field->Data->actualPath + Mstring("[-]");
1315 }else {
1316 path = field->Data->actualPath;
1317 }
1318 for(List<Mstring>::iterator var = field->Data->enumeration.variants.end(); var; var = var->Prev){
1319 if(var->Data.empty()) continue;
1320 container.push_back("variant (" + path + ") " + var->Data + ";\n");
1321 }
1322 }
1323 //Recursive call
1324 field->Data->collectVariants(container);
1325 }
1326 }
1327
1328 void ComplexType::printVariant(FILE * file) {
1329 if (e_flag_used) {
1330 return;
1331 }
1332
1333 bool foundAtLeastOneVariant = false;
1334 bool foundAtLeastOneHiddenVariant = false;
1335
1336 if (!variant.empty()) {
1337 for (List<Mstring>::iterator var = variant.begin(); var; var = var->Next) {
1338 if (foundAtLeastOneVariant && foundAtLeastOneHiddenVariant) {
1339 break;
1340 }
1341 if (var->Data[0] != '/') {
1342 foundAtLeastOneVariant = true;
1343 } else {
1344 foundAtLeastOneHiddenVariant = true;
1345 }
1346 }
1347 }
1348
1349 if (!foundAtLeastOneVariant && !foundAtLeastOneHiddenVariant) {
1350 return;
1351 }
1352
1353 if (!foundAtLeastOneVariant) {
1354 //No other variants, only commented, so the 'with' must be commented also.
1355 fprintf(file, ";\n//with {\n");
1356 } else {
1357 fprintf(file, "\nwith {\n");
1358 }
1359
1360 for (List<Mstring>::iterator var = variant.begin(); var; var = var->Next) {
1361 fprintf(file, " %s", var->Data.c_str());
1362 }
1363
1364 if (!foundAtLeastOneVariant) {
1365 fprintf(file, "//");
1366 }
1367 fprintf(file, "}");
1368 }
1369
1370 void ComplexType::dump(unsigned int depth) const {
1371 fprintf(stderr, "%*s %sComplexType at %p | Top:%s\n", depth * 2, "", isVisible() ? "" : "(hidden)", (const void*) this, top ? "true" : "false");
1372 if (parent != NULL) {
1373 fprintf(stderr, "%*s parent: %p | parent xsdtype: %i | my xsdtype: %i\n", depth * 2, "", (const void*) parent, parent->getXsdtype(), xsdtype);
1374 } else {
1375 fprintf(stderr, "%*s parent: %p | parent xsdtype: %s | my xsdtype: %i\n", depth * 2, "", "NULL", "NULL", xsdtype);
1376 }
1377 fprintf(stderr, "%*s name='%s' -> '%s', type='%s' %d complexfields | %s | %s | %s\n", depth * 2, "",
1378 name.originalValueWoPrefix.c_str(), name.convertedValue.c_str(), type.convertedValue.c_str(), (int) complexfields.size(),
1379 outside_reference.empty() ? "" : outside_reference.get_val().c_str(), mode == restrictionMode ? "restriction" : "",
1380 mode == extensionMode ? "extension" : "");
1381 for (List<ComplexType*>::iterator field = complexfields.begin(); field; field = field->Next) {
1382 field->Data->dump(depth + 1);
1383 }
1384 fprintf(stderr, "%*s %d attribields\n", depth * 2, "", (int) attribfields.size());
1385 for (List<AttributeType*>::iterator field = attribfields.begin(); field; field = field->Next) {
1386 field->Data->dump(depth + 1);
1387 }
1388 fprintf(stderr, "%*s %d enumfields\n", depth * 2, "", (int) enumfields.size());
1389 for (List<Mstring>::iterator field = enumfields.begin(); field; field = field->Next) {
1390 fprintf(stderr, "%*s enum: %s\n", depth * 2 + depth, "", field->Data.c_str());
1391 }
1392 fprintf(stderr, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth + 1) * 2, "", minOccurs, maxOccurs, isOptional ? "true" : "false", name.list_extension ? "true" : "false");
1393 fprintf(stderr, "%*s %d variants: ", (depth + 1) * 2, "", (int) variant.size());
1394 for (List<Mstring>::iterator var = variant.begin(); var; var = var->Next) {
1395 fprintf(stderr, "%s, ", var->Data.c_str());
1396 }
1397 fprintf(stderr, "%*s pattern:%s | length:%i \n ", (depth + 1) * 2, "", this->pattern.facet.c_str(), (int) (this->length.facet_maxLength));
1398 fprintf(stderr, "%*s enum: %i \n", (depth + 1)*2, "", (int) this->enumeration.facets.size());
1399 fprintf(stderr, "\n");
1400 }
1401
1402 void ComplexType::setMinMaxOccurs(const unsigned long long min, const unsigned long long max, const bool generate_list_postfix) {
1403
1404 if (min != 1 || max != 1) {
1405 if (xsdtype == n_choice) {
1406 minOccurs = min;
1407 maxOccurs = max;
1408 addVariant(V_untagged);
1409 first_child = false;
1410 } else if (xsdtype == n_sequence) {
1411 ComplexType * rec = new ComplexType(this);
1412 rec->type.upload(Mstring("record"));
1413 rec->name.upload(Mstring("sequence"));
1414 rec->setXsdtype(n_sequence);
1415 rec->addVariant(V_untagged);
1416 rec->addVariant(V_untagged);
1417 rec->minOccurs = min;
1418 rec->maxOccurs = max;
1419 complexfields.push_back(rec);
1420 actfield = rec;
1421 if ((rec->minOccurs == 0 && rec->maxOccurs > 1) || rec->minOccurs > 0) {
1422 rec->name.list_extension = true;
1423 }
1424 } else {
1425 minOccurs = min;
1426 maxOccurs = max;
1427 if ((minOccurs == 0 && maxOccurs > 1) || minOccurs > 0) {
1428 if (generate_list_postfix) {
1429 name.list_extension = true;
1430 }
1431 }
1432 if (parent != NULL && parent->getXsdtype() == n_choice) {
1433 name.list_extension = true;
1434 if ((parent != NULL && parent->getXsdtype() == n_choice)) {
1435 if (parent->first_child == false && minOccurs == 0) {
1436 parent->first_child = true;
1437 with_union = true;
1438 first_child = false;
1439 } else {
1440 with_union = true;
1441 first_child = true;
1442 }
1443 }
1444 }
1445 }
1446 }
1447
1448 if (maxOccurs > 1 && generate_list_postfix) {
1449 name.list_extension = true;
1450 }
1451 }
1452
1453 void ComplexType::applyNamespaceAttribute(VariantMode varLabel, const Mstring& ns_list) {
1454 List<Mstring> namespaces;
1455 if (!ns_list.empty()) {
1456 expstring_t valueToSplitIntoTokens = mcopystr(ns_list.c_str());
1457 char * token;
1458 token = strtok(valueToSplitIntoTokens, " ");
1459 while (token != NULL) {
1460 namespaces.push_back(Mstring(token));
1461 token = strtok(NULL, " ");
1462 }
1463 Free(valueToSplitIntoTokens);
1464 }
1465
1466 Mstring any_ns;
1467 bool first = true;
1468 // Note: libxml2 will verify the namespace list according to the schema
1469 // of XML Schema. It is either ##any, ##other, ##local, ##targetNamespace,
1470 // or a list of (namespace reference | ##local | ##targetNamespace).
1471 for (List<Mstring>::iterator ns = namespaces.begin(); ns; ns = ns->Next) {
1472 static const Mstring xxany("##any"), xxother("##other"), xxlocal("##local"),
1473 xxtargetNamespace("##targetNamespace");
1474 if (!first) any_ns += ',';
1475
1476 if (ns->Data == xxany) {
1477 }// this must be the only element, nothing to add
1478 else if (ns->Data == xxother) { // this must be the only element
1479 any_ns += " except unqualified";
1480 if (module->getTargetNamespace() != "NoTargetNamespace") {
1481 any_ns += ", \'";
1482 any_ns += parent->getModule()->getTargetNamespace();
1483 any_ns += '\'';
1484 }
1485 }// The three cases below can happen multiple times
1486 else {
1487 if (first) any_ns += " from ";
1488 // else a comma was already added
1489 if (ns->Data == xxtargetNamespace) {
1490 any_ns += '\'';
1491 any_ns += parent->getModule()->getTargetNamespace();
1492 any_ns += '\'';
1493 } else if (ns->Data == xxlocal) {
1494 any_ns += "unqualified";
1495 } else {
1496 any_ns += '\'';
1497 any_ns += ns->Data;
1498 any_ns += '\'';
1499 }
1500 }
1501
1502 first = false;
1503 }
1504
1505 addVariant(varLabel, any_ns, true);
1506 }
1507
1508 void ComplexType::addComment(const Mstring& text) {
1509 if (this == actfield) {
1510 if (lastType == n_attribute) { // ez nem teljesen jo, stb, tobb lehetoseg, es rossy sorrend
1511 if (!attribfields.empty()) {
1512 attribfields.back()->addComment(text);
1513 }
1514 } else {
1515 if (actfield->getName().convertedValue == Mstring("base") && parent != NULL) {
1516 parent->getComment().push_back(Mstring("/* " + text + " */\n"));
1517 } else {
1518 comment.push_back(Mstring("/* " + text + " */\n"));
1519 }
1520 }
1521 } else {
1522 actfield->addComment(text);
1523 return;
1524 }
1525 }
1526
1527 //Attribute extension logic when extending complextypes
1528 void ComplexType::applyAttributeExtension(ComplexType * found_CT, AttributeType * anyAttrib /* = NULL */) {
1529 for (List<AttributeType*>::iterator attr = found_CT->attribfields.begin(); attr; attr = attr->Next) {
1530 bool l = false;
1531 if (anyAttrib != NULL && attr->Data->isAnyAttribute()) {
1532 anyAttrib->addNameSpaceAttribute(attr->Data->getNameSpaceAttribute());
1533 l = true;
1534 } else {
1535 for (List<AttributeType*>::iterator attr2 = attribfields.begin(); attr2; attr2 = attr2->Next) {
1536 if (attr->Data->getName().convertedValue == attr2->Data->getName().convertedValue &&
1537 attr->Data->getType().convertedValue == attr2->Data->getType().convertedValue) {
1538 if (attr->Data->getUseVal() == optional) {
1539 attr2->Data->setUseVal(optional);
1540 }
1541 l = true;
1542 break;
1543 }
1544 }
1545 }
1546 if (!l) {
1547 AttributeType * newAttrib = new AttributeType(*attr->Data);
1548 attribfields.push_back(newAttrib);
1549 setParent(this, newAttrib);
1550 }
1551 }
1552 }
1553
1554 //Attribute restriction logic when restricting complextypes
1555 void ComplexType::applyAttributeRestriction(ComplexType * found_CT) {
1556 for (List<AttributeType*>::iterator attr = attribfields.begin(), nextAttr; attr; attr = nextAttr) {
1557 nextAttr = attr->Next;
1558 bool l = false;
1559 for (List<AttributeType*>::iterator attr2 = found_CT->attribfields.begin(); attr2; attr2 = attr2->Next) {
1560 if (attr->Data->getName().convertedValue == attr2->Data->getName().convertedValue &&
1561 attr->Data->getType().convertedValue == attr2->Data->getType().convertedValue) {
1562 l = true;
1563 break;
1564 }
1565 }
1566 if (!l) {
1567 delete attr->Data;
1568 attr->Data = NULL;
1569 attribfields.remove(attr);
1570 }
1571 }
1572 size_t size = found_CT->attribfields.size();
1573 size_t size2 = attribfields.size();
1574 size_t i = 0;
1575 List<AttributeType*>::iterator attr = found_CT->attribfields.begin();
1576 for (; i < size; attr = attr->Next, i = i + 1) {
1577 bool l = false;
1578 size_t j = 0;
1579 List<AttributeType*>::iterator attr2 = attribfields.begin();
1580 for (; j < size2; attr2 = attr2->Next, j = j + 1) {
1581 if (attr->Data->getName().convertedValue == attr2->Data->getName().convertedValue &&
1582 attr->Data->getType().convertedValue == attr2->Data->getType().convertedValue && !attr2->Data->getUsed()) {
1583 l = true;
1584 attr2->Data->setUsed(true);
1585 break;
1586 }
1587 }
1588 if (!l) {
1589 AttributeType * newAttrib = new AttributeType(*attr->Data);
1590 attribfields.push_back(newAttrib);
1591 setParent(this, newAttrib);
1592 }
1593 }
1594 }
1595
1596 void ComplexType::addNameSpaceAsVariant(RootType * root, RootType * other) {
1597 if (other->getModule()->getTargetNamespace() != root->getModule()->getTargetNamespace() &&
1598 other->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1599 root->addVariant(V_namespaceAs, other->getModule()->getTargetNamespace());
1600 }
1601 }
1602
1603 void ComplexType::resolveAttribute(AttributeType* attr) {
1604 if (attr->getXsdtype() == n_attribute && !attr->getReference().empty()) {
1605 SimpleType * st = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(attr, want_BOTH);
1606 if (st != NULL) {
1607 if (attr->isFromRef()) {
1608 addNameSpaceAsVariant(attr, st);
1609 attr->setTypeOfField(st->getName().convertedValue);
1610 attr->setNameOfField(st->getName().originalValueWoPrefix);
1611 attr->setOrigModule(st->getModule());
1612 } else {
1613 attr->setTypeOfField(st->getName().convertedValue);
1614 if (st->getType().convertedValue == "record" || st->getType().convertedValue == "union") {
1615 st->addToNameDepList(attr);
1616 }
1617 }
1618 } else {
1619 printError(module->getSchemaname(), name.convertedValue,
1620 "Reference for a non-defined type: " + attr->getReference().repr());
1621 TTCN3ModuleInventory::getInstance().incrNumErrors();
1622 }
1623 }
1624 }
1625
1626 void ComplexType::resolveAttributeGroup(SimpleType * st) {
1627 if (xsdtype == n_attributeGroup && !outside_reference.empty()) {
1628 ComplexType * ct = (ComplexType*) st;
1629 if(ct->resolved == No){
1630 ct->referenceResolving();
1631 }
1632 outside_reference.set_resolved(ct);
1633 setInvisible();
1634 bool addNameSpaceas = false;
1635 if (ct->getModule()->getTargetNamespace() != module->getTargetNamespace() &&
1636 ct->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1637 addNameSpaceas = true;
1638 }
1639 ComplexType * par;
1640 if(parent->nillable && parent->parent != NULL){
1641 par = parent->parent;
1642 }else {
1643 par = parent;
1644 }
1645 List<AttributeType*>::iterator anyAttrib = par->attribfields.begin();
1646 for (; anyAttrib; anyAttrib = anyAttrib->Next) {
1647 if (anyAttrib->Data->isAnyAttribute()) {
1648 break;
1649 }
1650 }
1651 for (List<AttributeType*>::iterator attr = ct->attribfields.begin(); attr; attr = attr->Next) {
1652 AttributeType * attrib = new AttributeType(*attr->Data);
1653 attr->Data->setOrigModule(ct->getModule());
1654 if (addNameSpaceas) {
1655 attrib->addVariant(V_namespaceAs, ct->getModule()->getTargetNamespace());
1656 }
1657 if (anyAttrib != NULL && attr->Data->isAnyAttribute()) {
1658 anyAttrib->Data->addNameSpaceAttribute(attr->Data->getNameSpaceAttribute());
1659 } else {
1660 //Nillable attribute placement is hard...
1661 if (parent->nillable && parent->parent != NULL) {
1662 parent->parent->attribfields.push_back(attrib);
1663 attrib->parent = parent->parent;
1664 setParent(parent->parent, attrib);
1665 } else if (parent->nillable && !parent->complexfields.empty()) {
1666 parent->complexfields.back()->attribfields.push_back(attrib);
1667 attrib->parent = parent->complexfields.back();
1668 } else if (parent->parent != NULL && (parent->parent->mode == extensionMode || parent->parent->mode == restrictionMode)) {
1669 parent->parent->attribfields.push_back(attrib);
1670 setParent(parent->parent, attrib);
1671 } else {
1672 parent->attribfields.push_back(attrib);
1673 setParent(parent, attrib);
1674 }
1675 }
1676 }
1677 }
1678 }
1679
1680 void ComplexType::resolveGroup(SimpleType *st) {
1681 if (xsdtype == n_group && !outside_reference.empty()) {
1682 ComplexType * ct = (ComplexType*) st;
1683 outside_reference.set_resolved(ct);
1684 setInvisible();
1685 if(ct->resolved == No){
1686 ct->referenceResolving();
1687 }
1688 //Decide if namespaceas variant needs to be added
1689 bool addNameSpaceas = false;
1690 if (ct->getModule()->getTargetNamespace() != module->getTargetNamespace() &&
1691 ct->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1692 addNameSpaceas = true;
1693 }
1694 if (ct->getXsdtype() == n_sequence && minOccurs == 1 && maxOccurs == 1 && (parent->getXsdtype() == n_complexType || parent->getXsdtype() == n_sequence)) {
1695 for (List<ComplexType*>::iterator c = ct->complexfields.begin(); c; c = c->Next) {
1696 ComplexType * newField = new ComplexType(*c->Data);
1697 parent->complexfields.push_back(newField);
1698 setParent(parent, newField);
1699 parent->complexfields.back()->setModule(getModule());
1700 if (addNameSpaceas) {
1701 parent->complexfields.back()->addVariant(V_namespaceAs, ct->getModule()->getTargetNamespace());
1702 }
1703 }
1704 } else if (ct->getXsdtype() == n_all) {
1705 //If the parent optional, then every field is optional
1706 for (List<ComplexType*>::iterator c = ct->complexfields.begin(); c; c = c->Next) {
1707 ComplexType* f = new ComplexType(*c->Data);
1708 if (minOccurs == 0 && !f->enumerated) {
1709 f->isOptional = true;
1710 }
1711 ((ComplexType*) parent)->complexfields.push_back(f);
1712 setParent(parent, f);
1713 f->setModule(getModule());
1714 if (addNameSpaceas) {
1715 f->addVariant(V_namespaceAs, ct->getModule()->getTargetNamespace());
1716 }
1717 }
1718 parent->addVariant(V_useOrder);
1719 } else {
1720 if (name.list_extension) {
1721 addVariant(V_untagged);
1722 }
1723 type.upload(ct->getName().convertedValue);
1724 name.upload(ct->getName().convertedValue);
1725 ct->addToNameDepList(this);
1726 nameDep = ct;
1727 visible = true;
1728 if (addNameSpaceas) {
1729 addVariant(V_namespaceAs, ct->getModule()->getTargetNamespace());
1730 }
1731 }
1732 }
1733 }
1734
1735 void ComplexType::resolveElement(SimpleType *st) {
1736 if (xsdtype == n_element && !outside_reference.empty()) {
1737 outside_reference.set_resolved(st);
1738 type.upload(st->getModule()->getTargetNamespaceConnector() + Mstring(":") + st->getName().convertedValue);
1739 if (name.originalValueWoPrefix.empty()) {
1740 name.upload(st->getName().convertedValue);
1741 }
1742 if (fromRef) {
1743 addNameSpaceAsVariant(this, st);
1744 }
1745
1746 collectElementTypes(st, NULL);
1747
1748 //Namedep is added to the substitutions, if any
1749 if(st->getSubstitution() != NULL){
1750 st->getSubstitution()->addToNameDepList(this);
1751 nameDep = st->getSubstitution();
1752 }if(st->getTypeSubstitution() != NULL){
1753 st->getTypeSubstitution()->addToNameDepList(this);
1754 nameDep = st->getTypeSubstitution();
1755 }else {
1756 st->addToNameDepList(this);
1757 nameDep = st;
1758 }
1759 }
1760 }
1761
1762 void ComplexType::resolveSimpleTypeExtension() {
1763 if (mode == extensionMode && cmode == CT_simpletype_mode && basefield != NULL) {
1764 SimpleType * st = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(basefield, want_BOTH);
1765 if (st != NULL) {
1766 if (st->getXsdtype() != n_NOTSET && ((ComplexType*) st)->basefield != NULL) { // if the xsdtype != simpletype
1767 ComplexType * ct = (ComplexType*) st;
1768 if (ct->resolved == No) {
1769 ct->referenceResolving();
1770 }
1771 basefield->outside_reference.set_resolved(ct);
1772 ct->basefield->addToNameDepList(basefield);
1773 basefield->nameDep = ct->basefield;
1774 basefield->mode = extensionMode;
1775 basefield->applyReference(*ct->basefield, true);
1776 addNameSpaceAsVariant(basefield, ct->basefield);
1777 applyAttributeExtension(ct);
1778 } else {
1779 if (!st->getReference().empty() && !st->getReference().is_resolved()) {
1780 st->referenceResolving();
1781 }
1782 st->addToNameDepList(basefield);
1783 basefield->nameDep = st;
1784 addNameSpaceAsVariant(basefield, st);
1785 const Mstring old_type = basefield->getType().originalValueWoPrefix;
1786 basefield->applyReference(*st);
1787 // If st has enumeration then the type is restored to the original value
1788 // because enumerations cannot be extended here and this way we just
1789 // we just create an alias.
1790 if (st->getEnumeration().modified) {
1791 basefield->setTypeValue(old_type);
1792 basefield->getEnumeration().modified = false;
1793 }
1794 }
1795 } else if(!isBuiltInType(basefield->getType().convertedValue)){
1796 printError(module->getSchemaname(), name.convertedValue,
1797 "Reference for a non-defined type: " + basefield->getReference().repr());
1798 TTCN3ModuleInventory::getInstance().incrNumErrors();
1799 return;
1800 }
1801
1802 }
1803 }
1804
1805 void ComplexType::resolveSimpleTypeRestriction() {
1806 if (mode == restrictionMode && cmode == CT_simpletype_mode && basefield != NULL && !basefield->outside_reference.empty()) {
1807 SimpleType * st = (SimpleType*) TTCN3ModuleInventory::getInstance().lookup(basefield, want_BOTH);
1808 if (st == NULL) {
1809 printError(module->getSchemaname(), name.convertedValue,
1810 "Reference for a non-defined type: " + basefield->getReference().repr());
1811 TTCN3ModuleInventory::getInstance().incrNumErrors();
1812 return;
1813 }
1814 basefield->outside_reference.set_resolved(st);
1815 if (st->getXsdtype() != n_NOTSET) {
1816 ComplexType * ct = (ComplexType*) st;
1817 if (ct->resolved == No) {
1818 ct->referenceResolving();
1819 }
1820 applyAttributeRestriction(ct);
1821 basefield->mode = restrictionMode;
1822 if (ct->cmode == CT_complextype_mode) {
1823 applyReference(*ct, true);
1824 type.upload(ct->getName().convertedValue);
1825 basefield->setInvisible();
1826 } else if (ct->basefield != NULL) {
1827 basefield->applyReference(*ct->basefield);
1828 addNameSpaceAsVariant(basefield, ct->basefield);
1829 } else if (ct->basefield == NULL) {
1830 basefield->applyReference(*ct);
1831 addNameSpaceAsVariant(basefield, ct);
1832 }
1833 } else {
1834 if (!st->getReference().empty() && !st->getReference().is_resolved()) {
1835 st->referenceResolving();
1836 }
1837 if(xsdtype == n_simpleContent){
1838 basefield->applyReference(*st, true);
1839 addNameSpaceAsVariant(basefield, st);
1840 basefield->mode = restrictionMode;
1841 }else if(xsdtype == n_simpleType){
1842 basefield->setInvisible();
1843 applyReference(*basefield, true);
1844 applyReference(*st, true);
1845 addNameSpaceAsVariant(this, st);
1846 basefield->mode = restrictionMode;
1847 }
1848 }
1849 } else if (mode == restrictionMode && cmode == CT_simpletype_mode && basefield != NULL) {
1850 ComplexType * ct = (ComplexType*) TTCN3ModuleInventory::getInstance().lookup(basefield, want_CT);
1851 if (ct == NULL && !isBuiltInType(basefield->getType().convertedValue)) {
1852 printError(module->getSchemaname(), name.convertedValue,
1853 "Reference for a non-defined type: " + basefield->getReference().repr());
1854 TTCN3ModuleInventory::getInstance().incrNumErrors();
1855 return;
1856 }
1857
1858 basefield->outside_reference.set_resolved(ct);
1859 if (ct != NULL) {
1860 if (ct->resolved == No) {
1861 ct->referenceResolving();
1862 }
1863 for (List<AttributeType*>::iterator f = ct->attribfields.begin(); f; f = f->Next) {
1864 AttributeType * attr = new AttributeType(*f->Data);
1865 attribfields.push_back(attr);
1866 setParent(this, attr);
1867 }
1868 addNameSpaceAsVariant(this, ct);
1869 }
1870 if(!basefield->parent->top){
1871 applyReference(*basefield, true);
1872 basefield->setInvisible();
1873 }
1874 }
1875 }
1876
1877 void ComplexType::resolveComplexTypeExtension() {
1878 if (mode == extensionMode && cmode == CT_complextype_mode && !outside_reference.empty()) {
1879 ComplexType * ct = (ComplexType*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT);
1880 if (ct == NULL) {
1881 printError(module->getSchemaname(), name.convertedValue,
1882 "Reference for a non-defined type: " + getReference().repr());
1883 TTCN3ModuleInventory::getInstance().incrNumErrors();
1884 return;
1885 }
1886 if(ct->getXsdtype() != n_NOTSET){
1887 outside_reference.set_resolved(ct);
1888 if (ct->resolved == No) {
1889 ct->referenceResolving();
1890 }
1891 List<AttributeType*>::iterator anyAttr = attribfields.begin();
1892 for (; anyAttr; anyAttr = anyAttr->Next) {
1893 if (anyAttr->Data->isAnyAttribute()) {
1894 break;
1895 }
1896 }
1897
1898 if (anyAttr != NULL) {
1899 applyAttributeExtension(ct, anyAttr->Data);
1900 } else {
1901 applyAttributeExtension(ct);
1902 }
1903
1904 if (ct->getName().convertedValue == outside_reference.get_val() && ct->getModule()->getTargetNamespace() == outside_reference.get_uri()) {
1905 //Self recursion
1906 outside_reference.set_resolved(ct);
1907 for (List<ComplexType*>::iterator f = ct->complexfields.end(); f; f = f->Prev) {
1908 if (f->Data != this) { //not a self recursive field
1909 ComplexType * newField = new ComplexType(*f->Data);
1910 complexfields.push_front(newField);
1911 setParent(this, newField);
1912 } else {
1913 //Self recursive field
1914 ComplexType * field = new ComplexType(this);
1915 field->name.upload(f->Data->getName().convertedValue);
1916 field->applyReference(*f->Data);
1917 field->type.upload(ct->getName().convertedValue + Mstring(".") + f->Data->getName().convertedValue);
1918 field->type.no_replace = true;
1919 field->minOccurs = f->Data->minOccurs;
1920 field->maxOccurs = f->Data->maxOccurs;
1921 complexfields.push_front(field);
1922 setParent(this, field);
1923 }
1924 }
1925 } else {
1926 //Normal extension
1927 for (List<ComplexType*>::iterator f = ct->complexfields.end(); f; f = f->Prev) {
1928 ComplexType * newField = new ComplexType(*f->Data);
1929 complexfields.push_front(newField);
1930 setParent(this, newField);
1931 }
1932 }
1933 }
1934 }
1935 }
1936
1937 void ComplexType::resolveComplexTypeRestriction() {
1938 if (mode == restrictionMode && cmode == CT_complextype_mode && !outside_reference.empty()) {
1939 ComplexType * ct = (ComplexType*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT);
1940 if(ct->getXsdtype() != n_NOTSET){
1941 if (ct->resolved == No) {
1942 ct->referenceResolving();
1943 }
1944 outside_reference.set_resolved(ct);
1945 applyAttributeRestriction(ct);
1946
1947 size_t size = complexfields.size();
1948 size_t i = 0;
1949 List<ComplexType*>::iterator field = complexfields.begin();
1950 for (; i < size; field = field->Next, i = i + 1){
1951 List<ComplexType*>::iterator field2 = ct->complexfields.begin();
1952 for (; field2; field2 = field2->Next) {
1953 if (field->Data->getName().convertedValue == field2->Data->getName().convertedValue &&
1954 field->Data->getType().convertedValue == field2->Data->getType().convertedValue) {
1955 field->Data->applyReference(*field2->Data, false);
1956 break;
1957 }
1958 }
1959 if(field2 == NULL){
1960 field->Data->setInvisible();
1961 }
1962 }
1963 }
1964 }
1965 }
1966
1967 void ComplexType::resolveUnion(SimpleType *st) {
1968 if (parent != NULL && parent->with_union && xsdtype == n_simpleType && !outside_reference.empty()) {
1969 if (st->getXsdtype() != n_NOTSET) {
1970 ComplexType * ct = (ComplexType*) st;
1971 outside_reference.set_resolved(ct);
1972 for (List<ComplexType*>::iterator field = ct->complexfields.begin(); field; field = field->Next) {
1973 ComplexType * newField = new ComplexType(*field->Data);
1974 parent->complexfields.push_back(newField);
1975 setParent(parent, newField);
1976 }
1977 setInvisible();
1978 }
1979 }
1980 }
1981
1982 void ComplexType::modifyAttributeParent() {
1983 if (nillable_field != NULL) {
1984 ((ComplexType*) nillable_field)->actfield = nillable_field;
1985 } else {
1986 actfield = this;
1987 }
1988 }
1989
1990 //Element substitution
1991 void ComplexType::addSubstitution(SimpleType * st){
1992 ComplexType * element;
1993 if(st->getXsdtype() == n_NOTSET || !complexfields.empty()){
1994 element = new ComplexType(*st, fromTagSubstitution);
1995 }else {
1996 element = new ComplexType(*(ComplexType*)st);
1997 element->variant.clear();
1998 }
1999 element->subsGroup = this;
2000 element->parent = this;
2001 if(complexfields.empty()){ //The first element(head) is the st
2002 element->setTypeValue(st->getType().convertedValue);
2003 if(st->hasVariant(Mstring("\"abstract\""))){
2004 element->addVariant(V_abstract);
2005 }
2006 if(st->getReference().get_ref() != NULL){
2007 ((SimpleType*)st->getReference().get_ref())->addToNameDepList(element);
2008 nameDep = ((SimpleType*)st->getReference().get_ref());
2009 }
2010 module->addElementType(element->getType().convertedValue, element);
2011 element->addVariant(V_formAs, Mstring("qualified"));
2012 }else {
2013 Mstring newType;
2014 if(st->getType().convertedValue == "anyType"){
2015 newType = complexfields.front()->getType().convertedValue;
2016 }else {
2017 newType = st->getName().convertedValue;
2018 st->addToNameDepList(element);
2019 element->nameDep = st;
2020 }
2021 element->setTypeValue(newType);
2022 BlockValue front_block = complexfields.front()->getBlock();
2023 if(front_block == all || front_block == substitution){
2024 element->addVariant(V_block);
2025 }else if(front_block == restriction || front_block == extension){
2026 const Mstring& head_type = complexfields.front()->getType().convertedValue.getValueWithoutPrefix(':');
2027 //To decide if they came from a common ancestor
2028 Mstring elem_type = findRoot(front_block, st, head_type, true);
2029 if(head_type == elem_type){
2030 element->addVariant(V_block);
2031 }
2032 }
2033 }
2034
2035 element->setNameValue(st->getName().convertedValue);
2036 element->top = false;
2037 complexfields.push_back(element);
2038 }
2039
2040 void ComplexType::addTypeSubstitution(SimpleType * st){
2041 ComplexType * element;
2042 if(st->getXsdtype() == n_NOTSET || !complexfields.empty()){
2043 element = new ComplexType(*st, fromTypeSubstitution);
2044 }else {
2045 //Only need a plain complextype
2046 //Head element
2047 element = new ComplexType(this);
2048 //Just the block needed from st
2049 element->block = st->getBlock();
2050 }
2051 st->addToNameDepList(element);
2052 element->nameDep = st;
2053 element->typeSubsGroup = this;
2054 element->parent = this;
2055 if(complexfields.empty()){ //The first element(head) is the st
2056 if(st->hasVariant(Mstring("\"abstract\""))){
2057 element->addVariant(V_abstract);
2058 }
2059 }else {
2060 BlockValue front_block = complexfields.front()->getBlock();
2061 if(front_block == all){
2062 element->addVariant(V_block);
2063 }else if(front_block == restriction || front_block == extension){
2064 const Mstring& head_type = complexfields.front()->getType().convertedValue.getValueWithoutPrefix(':');
2065 //To decide if they came from a common ancestor
2066 Mstring elem_type = findRoot(front_block, st, head_type, true);
2067 if(head_type == elem_type){
2068 element->addVariant(V_block);
2069 }
2070 }
2071 }
2072 //Cascading to parent type substitution
2073 if(parentTypeSubsGroup != NULL && !complexfields.empty()){
2074 parentTypeSubsGroup->addTypeSubstitution(st);
2075 }
2076 element->top = false;
2077 complexfields.push_back(element);
2078 element->setTypeValue(st->getName().convertedValue.getValueWithoutPrefix(':'));
2079 element->setNameValue(st->getName().convertedValue.getValueWithoutPrefix(':'));
2080 }
2081
2082 Mstring ComplexType::findRoot(const BlockValue block_value, SimpleType* elem, const Mstring& head_type, const bool first){
2083 const Mstring elemName = elem->getName().convertedValue.getValueWithoutPrefix(':');
2084 const Mstring elemType = elem->getType().convertedValue.getValueWithoutPrefix(':');
2085
2086 if(!first && !isFromRef() && elemType == head_type){
2087 return elemType;
2088 }else if((isFromRef() &&
2089 ((elem->getMode() == restrictionMode && block_value == restriction) ||
2090 (elem->getMode() == extensionMode && block_value == extension))) && elemType == head_type){
2091 return elemType;
2092 }else if(!first && elemName == head_type){
2093 return elemName;
2094 }else {
2095 SimpleType * st = NULL;
2096 if((elem->getMode() == restrictionMode && block_value == restriction) ||
2097 (elem->getMode() == extensionMode && block_value == extension)){
2098 if(!elem->getReference().is_resolved()){
2099 elem->referenceResolving();
2100 }
2101 if(elem->getXsdtype() != n_NOTSET){
2102 ComplexType * ct = (ComplexType*)elem;
2103 if(ct->basefield != NULL && ct->basefield->getType().convertedValue.getValueWithoutPrefix(':') == head_type){
2104 return head_type;
2105 }else if(ct->basefield != NULL){
2106 st = (SimpleType*)TTCN3ModuleInventory::getInstance().lookup(ct->basefield, want_BOTH);
2107 }
2108 }
2109 if(st == NULL){
2110 st = (SimpleType*)(elem->getReference().get_ref());
2111 }
2112 }else if(elem->getMode() == noMode && (block_value == restriction || block_value == extension)){
2113 st = (SimpleType*)TTCN3ModuleInventory::getInstance().lookup(this, elem->getType().convertedValue, want_BOTH);
2114 }
2115 if(st != NULL && elem != st){
2116 return findRoot(block_value, st, head_type, false);
2117 }
2118 }
2119 if(elem->getMode() == noMode && !first){
2120 return elemType;
2121 }else {
2122 return empty_string;
2123 }
2124 }
2125
This page took 0.078588 seconds and 5 git commands to generate.