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