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