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"
10 #include "GeneralFunctions.hh"
11 #include "XMLParser.hh"
12 #include "TTCN3Module.hh"
13 #include "TTCN3ModuleInventory.hh"
14 #include "Annotation.hh"
18 ComplexType::ComplexType(XMLParser
* a_parser
, TTCN3Module
* a_module
, ConstructType a_construct
)
19 : SimpleType(a_parser
, a_module
, a_construct
)
30 , actualPath(empty_string
)
33 , nillable_field(NULL
)
35 , cmode(CT_undefined_mode
)
41 xsdtype
= n_complexType
;
44 ComplexType::ComplexType(ComplexType
& other
)
47 , nillable(other
.nillable
)
48 , enumerated(other
.enumerated
)
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
)
58 , nameDep(other
.nameDep
)
59 , nillable_field(NULL
)
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;
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();
79 if (other
.nameDep
!= NULL
) {
80 SimpleType
* dep
= other
.nameDep
;
81 if(dep
->getSubstitution() != NULL
){
82 dep
->getSubstitution()->addToNameDepList(this);
83 nameDep
= dep
->getSubstitution();
85 other
.nameDep
->addToNameDepList(this);
90 ComplexType::ComplexType(ComplexType
* other
)
91 : SimpleType(other
->getParser(), other
->getModule(), c_unknown
)
102 , actualPath(empty_string
)
105 , nillable_field(NULL
)
107 , cmode(CT_undefined_mode
)
113 xsdtype
= n_complexType
;
115 outside_reference
= ReferenceData();
118 ComplexType::ComplexType(const SimpleType
& other
, CT_fromST c
)
130 , actualPath(empty_string
)
133 , nillable_field(NULL
)
135 , cmode(CT_simpletype_mode
)
142 if(c
!= fromTagSubstitution
&& c
!= fromTypeSubstitution
){
143 module
->replaceLastMainType(this);
144 module
->setActualXsdConstruct(c_complexType
);
146 construct
= c_complexType
;
150 type
.upload(Mstring("union"));
154 case fromTagNillable
:
155 addVariant(V_useNil
);
156 type
.upload(Mstring("record"));
158 case fromTagComplexType
:
159 type
.upload(Mstring("record"));
160 xsdtype
= n_complexType
;
162 case fromTagSubstitution
:
163 type
.upload(Mstring("union"));
164 name
.upload(getName().originalValueWoPrefix
+ Mstring("_group"));
168 hidden_variant
.clear();
169 enumeration
.modified
= false;
170 value
.modified
= false;
171 pattern
.modified
= false;
172 length
.modified
= false;
173 whitespace
.modified
= false;
175 case fromTypeSubstitution
:
176 type
.upload(Mstring("union"));
177 name
.upload(getName().originalValueWoPrefix
+ Mstring("_derivations"));
179 substitutionGroup
= empty_string
;
180 typeSubsGroup
= this;
182 hidden_variant
.clear();
183 enumeration
.modified
= false;
184 value
.modified
= false;
185 pattern
.modified
= false;
186 length
.modified
= false;
187 whitespace
.modified
= false;
191 ComplexType::~ComplexType() {
192 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
196 complexfields
.clear();
198 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
202 attribfields
.clear();
205 void ComplexType::loadWithValues() {
206 //Find the last field where the tag is found
207 if (this != actfield
) {
208 actfield
->loadWithValues();
212 const XMLParser::TagAttributes
& atts
= parser
->getActualTagAttributes();
214 switch (parser
->getActualTagName()) {
216 if (!top
&& xsdtype
!= n_sequence
&& xsdtype
!= n_complexType
&& xsdtype
!= n_extension
&& xsdtype
!= n_restriction
&& xsdtype
!= n_element
) {
218 ComplexType
* rec
= new ComplexType(this);
219 rec
->type
.upload(Mstring("record"));
220 rec
->name
.upload(Mstring("sequence"));
221 rec
->addVariant(V_untagged
);
222 rec
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
223 rec
->setXsdtype(n_sequence
);
224 complexfields
.push_back(rec
);
227 //Do not create new record, it is an embedded sequence
228 if (xsdtype
== n_sequence
&& atts
.minOccurs
== 1 && atts
.maxOccurs
== 1) {
231 type
.upload(Mstring("record"));
232 xsdtype
= n_sequence
;
233 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
237 if (!top
|| xsdtype
!= n_group
) {
238 //Create new union field
239 ComplexType
* choice
= new ComplexType(this);
240 choice
->type
.upload(Mstring("union"));
241 choice
->name
.upload(Mstring("choice"));
242 choice
->setXsdtype(n_choice
);
243 choice
->addVariant(V_untagged
);
244 choice
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
246 complexfields
.push_back(choice
);
249 type
.upload(Mstring("union"));
254 //Create the record of enumerated field
256 ComplexType
* enumField
= new ComplexType(this);
257 enumField
->setTypeValue(Mstring("enumerated"));
258 enumField
->setNameValue(Mstring("order"));
259 enumField
->setBuiltInBase(Mstring("string"));
260 enumField
->enumerated
= true;
261 enumField
->setMinMaxOccurs(0, ULLONG_MAX
, false);
262 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
263 addVariant(V_useOrder
);
264 complexfields
.push_back(enumField
);
265 if (atts
.minOccurs
== 0) {
271 mode
= restrictionMode
;
272 //If it is an xsd:union then call SimpleType::loadWithValues
273 if (parent
!= NULL
&& parent
->with_union
) {
274 SimpleType::loadWithValues();
277 if (cmode
== CT_simpletype_mode
) {
278 //if it is from a SimpleType, then create a base field
279 ComplexType
* f
= new ComplexType(this);
280 f
->name
.upload(Mstring("base"));
281 f
->type
.upload(atts
.base
);
282 f
->setReference(atts
.base
);
283 f
->addVariant(V_untagged
);
284 complexfields
.push_back(f
);
287 } else if (cmode
== CT_complextype_mode
) {
288 setReference(atts
.base
);
289 xsdtype
= n_restriction
;
293 mode
= extensionMode
;
294 if (cmode
== CT_simpletype_mode
) {
295 //if it is from a SimpleType, then create a base field
296 ComplexType
* f
= new ComplexType(this);
297 f
->name
.upload(Mstring("base"));
298 f
->type
.upload(atts
.base
);
299 f
->setReference(atts
.base
);
300 f
->addVariant(V_untagged
);
301 complexfields
.push_back(f
);
304 } else if (cmode
== CT_complextype_mode
) {
305 setReference(atts
.base
);
306 xsdtype
= n_extension
;
312 if(cmode
== CT_simpletype_mode
){
313 //If a simple top level element is nillable
314 ComplexType
* nilrec
= new ComplexType(this);
315 if (atts
.type
.empty()) {
316 nilrec
->type
.upload(Mstring("record"));
318 nilrec
->type
.upload(atts
.type
);
320 nilrec
->name
.upload(Mstring("content"));
321 nilrec
->isOptional
= true;
322 nilrec
->nillable
= true;
323 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
324 complexfields
.push_back(nilrec
);
325 type
.upload(Mstring("record"));
326 name
.upload(atts
.name
);
328 nillable_field
= nilrec
;
330 //From a complexType element is nillable
331 ComplexType
* record
= new ComplexType(this);
332 ComplexType
* nilrec
= new ComplexType(record
);
333 if (atts
.type
.empty()) {
334 nilrec
->type
.upload(Mstring("record"));
336 nilrec
->type
.upload(atts
.type
);
338 record
->name
.upload(atts
.name
);
339 record
->type
.upload(Mstring("record"));
340 record
->complexfields
.push_back(nilrec
);
341 record
->addVariant(V_useNil
);
342 record
->nillable_field
= nilrec
;
343 record
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
345 nilrec
->name
.upload(Mstring("content"));
346 nilrec
->nillable
= true;
347 nilrec
->isOptional
= true;
348 nilrec
->tagNames
.push_back(parser
->getActualTagName());
349 complexfields
.push_back(record
);
353 //It is a simple element
354 ComplexType
* c
= new ComplexType(this);
355 c
->setXsdtype(n_element
);
356 c
->type
.upload(atts
.type
);
357 c
->name
.upload(atts
.name
);
358 c
->setReference(atts
.type
);
359 c
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
360 c
->applyDefaultAttribute(atts
.default_
);
361 c
->applyFixedAttribute(atts
.fixed
);
362 c
->setElementFormAs(atts
.form
);
363 if (atts
.ref
.empty()) {
364 c
->setReference(atts
.type
);
366 c
->applyRefAttribute(atts
.ref
);
367 c
->name
.upload(atts
.ref
.getValueWithoutPrefix(':'));
368 c
->type
.upload(atts
.ref
);
370 c
->applySubstitionGroupAttribute(atts
.substitionGroup
);
371 c
->applyBlockAttribute(atts
.block
);
374 //Inside all have some special conditions
375 if (xsdtype
== n_all
) {
376 if (atts
.minOccurs
> 1) {
377 printError(getModule()->getSchemaname(), name
.convertedValue
,
378 Mstring("Inside <all>, minOccurs must be 0 or 1"));
379 TTCN3ModuleInventory::incrNumErrors();
381 if (atts
.maxOccurs
!= 1) {
382 printError(getModule()->getSchemaname(), name
.convertedValue
,
383 Mstring("Inside <all>, maxOccurs must be 1"));
384 TTCN3ModuleInventory::incrNumErrors();
387 complexfields
.push_back(c
);
389 c
->isOptional
= true;
392 complexfields
.push_back(c
);
399 AttributeType
* attribute
= new AttributeType(this);
400 attribute
->addVariant(V_attribute
);
401 attribute
->applyMinMaxOccursAttribute(0, 1);
402 attribute
->setXsdtype(n_attribute
);
403 attribute
->applyDefaultAttribute(atts
.default_
);
404 attribute
->applyFixedAttribute(atts
.fixed
);
405 attribute
->setUseVal(atts
.use
);
406 attribute
->setAttributeFormAs(atts
.form
);
407 lastType
= n_attribute
;
408 if (atts
.ref
.empty()) {
409 attribute
->setNameOfField(atts
.name
);
410 attribute
->setTypeOfField(atts
.type
);
411 attribute
->setReference(atts
.type
, true);
413 attribute
->applyRefAttribute(atts
.ref
);
415 actfield
= attribute
;
417 //In case of nillable parent it is difficult...
418 if (nillable
&& parent
!= NULL
) {
419 parent
->attribfields
.push_back(attribute
);
420 attribute
->parent
= parent
;
421 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
422 complexfields
.back()->attribfields
.push_back(attribute
);
423 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
424 parent
->attribfields
.push_back(attribute
);
425 attribute
->parent
= parent
;
427 attribfields
.push_back(attribute
);
433 ComplexType
* any
= new ComplexType(this);
434 any
->name
.upload(Mstring("elem"));
435 any
->type
.upload(Mstring("xsd:string"));
436 any
->applyNamespaceAttribute(V_anyElement
, atts
.namespace_
);
437 any
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
438 any
->setXsdtype(n_any
);
439 complexfields
.push_back(any
);
444 AttributeType
* anyattr
= new AttributeType(this);
445 anyattr
->setXsdtype(n_anyAttribute
);
446 anyattr
->setNameOfField(Mstring("attr"));
447 anyattr
->setTypeValue(Mstring("xsd:string"));
448 anyattr
->setToAnyAttribute();
449 anyattr
->applyMinMaxOccursAttribute(0, ULLONG_MAX
);
450 anyattr
->addNameSpaceAttribute(atts
.namespace_
);
453 //In case of nillable parent it is difficult...
454 if (nillable
&& parent
!= NULL
) {
455 parent
->attribfields
.push_back(anyattr
);
456 anyattr
->parent
= parent
;
457 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
458 complexfields
.back()->attribfields
.push_back(anyattr
);
459 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
460 parent
->attribfields
.push_back(anyattr
);
461 anyattr
->parent
= parent
;
463 attribfields
.push_back(anyattr
);
467 case n_attributeGroup
:
468 if (!atts
.ref
.empty()) {
469 ComplexType
* g
= new ComplexType(this);
470 g
->setXsdtype(n_attributeGroup
);
471 g
->setReference(atts
.ref
);
472 complexfields
.push_back(g
);
475 xsdtype
= n_attributeGroup
;
476 name
.upload(Mstring(atts
.name
));
481 if (atts
.ref
.empty()) {
484 name
.upload(atts
.name
);
487 ComplexType
* group
= new ComplexType(this);
488 group
->setXsdtype(n_group
);
489 group
->name
.upload(atts
.name
);
490 group
->setReference(Mstring(atts
.ref
));
491 group
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
492 complexfields
.push_back(group
);
500 type
.upload(Mstring("union"));
501 addVariant(V_useUnion
);
502 if (!atts
.memberTypes
.empty()) {
504 //Get the union values
505 expstring_t valueToSplitIntoTokens
= mcopystr(atts
.memberTypes
.c_str());
507 token
= strtok(valueToSplitIntoTokens
, " ");
508 while (token
!= NULL
) {
509 types
.push_back(Mstring(token
));
510 token
= strtok(NULL
, " ");
512 Free(valueToSplitIntoTokens
);
514 //Create the union elements and push into the container
515 for (List
<Mstring
>::iterator memberType
= types
.begin(); memberType
; memberType
= memberType
->Next
) {
516 Mstring tmp_name
= memberType
->Data
.getValueWithoutPrefix(':');
517 ComplexType
* f
= new ComplexType(this);
518 f
->name
.upload(tmp_name
);
519 f
->type
.upload(memberType
->Data
);
520 f
->setXsdtype(n_simpleType
);
521 f
->setReference(memberType
->Data
);
522 complexfields
.push_back(f
);
528 case n_simpleContent
:
530 xsdtype
= parser
->getActualTagName();
531 cmode
= CT_simpletype_mode
;
535 fieldname
= Mstring("alt_");
537 fieldname
= mprintf("alt_%d", max_alt
);
540 ComplexType
* field
= new ComplexType(this);
541 field
->name
.upload(fieldname
);
542 field
->setXsdtype(n_simpleType
);
543 field
->addVariant(V_nameAs
, empty_string
, true);
544 complexfields
.push_back(field
);
550 name
.upload(atts
.name
);
551 type
.upload(Mstring("record"));
552 applyAbstractAttribute(atts
.abstract
);
553 applySubstitionGroupAttribute(atts
.substitionGroup
);
554 applyBlockAttribute(atts
.block
);
556 case n_complexContent
:
557 tagNames
.push_back(parser
->getActualTagName());
558 cmode
= CT_complextype_mode
;
560 ComplexType
* mixed
= new ComplexType(this);
561 mixed
->name
.upload(Mstring("embed_values"));
562 mixed
->type
.upload(Mstring("xsd:string"));
563 mixed
->setMinMaxOccurs(0, ULLONG_MAX
, false);
565 complexfields
.push_back(mixed
);
566 addVariant(V_embedValues
);
581 case n_fractionDigits
:
582 SimpleType::loadWithValues();
585 addComment(Mstring("LABEL:"));
588 addComment(Mstring("DEFINITION:"));
595 // called from endelementHandler
596 void ComplexType::modifyValues() {
597 if (this != actfield
) {
598 actfield
->modifyValues();
601 if (xsdtype
== n_sequence
) {
602 skipback
= skipback
- 1;
605 if ((xsdtype
== n_element
||
606 xsdtype
== n_complexType
||
607 xsdtype
== n_complexContent
||
609 xsdtype
== n_attribute
||
610 xsdtype
== n_anyAttribute
||
611 xsdtype
== n_choice
||
612 xsdtype
== n_group
||
613 xsdtype
== n_attributeGroup
||
614 xsdtype
== n_extension
||
615 xsdtype
== n_restriction
||
616 xsdtype
== n_simpleType
||
617 xsdtype
== n_simpleContent
||
618 (xsdtype
== n_sequence
&& skipback
< 0)
621 if (!tagNames
.empty() && tagNames
.back() == parser
->getParentTagName()) {
622 if (nillable
&& tagNames
.back() == n_element
) {
623 parent
->modifyValues();
626 } else if (tagNames
.empty()) {
627 parent
->actfield
= parent
;
628 parent
->lastType
= xsdtype
;
633 void ComplexType::referenceResolving() {
634 if (resolved
!= No
) return; // nothing to do
635 if(this == subsGroup
){
639 resolved
= InProgress
;
640 for (List
<ComplexType
*>::iterator ct
= complexfields
.begin(); ct
; ct
= ct
->Next
) {
641 // Referenece resolving of ComplexTypes
642 ct
->Data
->referenceResolving();
644 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
645 //Reference resolving for Attributes
646 resolveAttribute(attr
->Data
);
649 reference_resolving_funtion();
651 if(!substitutionGroup
.empty()){
652 addToSubstitutions();
657 void ComplexType::reference_resolving_funtion() {
658 //Every child element references are resolved here.
659 if (outside_reference
.empty() && basefield
== NULL
) {
660 //Its not in the resolveElement function because we need the built in type
661 //reference too, and then the outside_reference is empty.
662 if(xsdtype
== n_element
){
663 collectElementTypes(NULL
, NULL
);
668 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_BOTH
);
669 if (st
== NULL
&& basefield
== NULL
) {
670 printError(module
->getSchemaname(), name
.convertedValue
,
671 "Reference for a non-defined type: " + getReference().repr());
672 TTCN3ModuleInventory::getInstance().incrNumErrors();
673 outside_reference
.set_resolved(NULL
);
677 resolveAttributeGroup(st
);
683 resolveSimpleTypeExtension();
685 resolveSimpleTypeRestriction();
687 resolveComplexTypeExtension();
689 resolveComplexTypeRestriction();
693 addToTypeSubstitutions();
697 void ComplexType::setParent(ComplexType
* par
, SimpleType
* child
) {
701 void ComplexType::applyReference(const SimpleType
& other
, const bool on_attributes
) {
702 type
.convertedValue
= other
.getType().convertedValue
;
703 type
.originalValueWoPrefix
= other
.getType().convertedValue
.getValueWithoutPrefix(':');
705 if (other
.getMinOccurs() > minOccurs
|| other
.getMaxOccurs() < maxOccurs
) {
706 if (!on_attributes
) {
707 expstring_t temp
= memptystr();
710 "The occurrence range (%llu .. %llu) of the element (%s) is not compatible "
711 "with the occurrence range (%llu .. %llu) of the referenced element.",
714 name
.originalValueWoPrefix
.c_str(),
715 other
.getMinOccurs(),
716 other
.getMaxOccurs());
717 printError(module
->getSchemaname(), parent
->getName().originalValueWoPrefix
,
720 TTCN3ModuleInventory::getInstance().incrNumErrors();
723 minOccurs
= llmax(minOccurs
, other
.getMinOccurs());
724 maxOccurs
= llmin(maxOccurs
, other
.getMaxOccurs());
727 for (List
<Mstring
>::iterator var
= other
.getVariantRef().begin(); var
; var
= var
->Next
) {
729 for (List
<Mstring
>::iterator var1
= variant
.begin(); var1
; var1
= var1
->Next
) {
730 if (var
->Data
== var1
->Data
) {
736 variant
.push_back(var
->Data
);
737 variant_ref
.push_back(var
->Data
);
741 builtInBase
= other
.getBuiltInBase();
743 length
.applyReference(other
.getLength());
744 pattern
.applyReference(other
.getPattern());
745 enumeration
.applyReference(other
.getEnumeration());
746 whitespace
.applyReference(other
.getWhitespace());
747 value
.applyReference(other
.getValue());
750 void ComplexType::nameConversion(NameConversionMode conversion_mode
, const List
<NamespaceType
> & ns
) {
752 switch (conversion_mode
) {
754 nameConversion_names(ns
);
757 nameConversion_types(ns
);
760 nameConversion_fields(ns
);
765 void ComplexType::nameConversion_names(const List
<NamespaceType
> &) {
766 Mstring res
, var(module
->getTargetNamespace());
767 XSDName2TTCN3Name(name
.convertedValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_name
, res
, var
);
768 name
.convertedValue
= res
;
770 for (List
<Mstring
>::iterator vari
= variant
.begin(); vari
; vari
= vari
->Next
) {
771 if (vari
->Data
== "\"untagged\"") {
777 addVariant(V_onlyValue
, var
);
779 for (List
<SimpleType
*>::iterator dep
= nameDepList
.begin(); dep
; dep
= dep
->Next
) {
780 dep
->Data
->setTypeValue(res
);
784 void ComplexType::nameConversion_types(const List
<NamespaceType
> & ns
) {
785 attribfields
.sort(compareAttributeNameSpaces
);
786 attribfields
.sort(compareAttributeTypes
);
787 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
788 field
->Data
->nameConversion(typeMode
, ns
);
791 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
792 field
->Data
->nameConversion_types(ns
);
795 Mstring prefix
, uri
, typeValue
;
797 if (type
.convertedValue
== "record" ||
798 type
.convertedValue
== "set" ||
799 type
.convertedValue
== "union" ||
800 type
.convertedValue
== "enumerated") {
804 prefix
= type
.convertedValue
.getPrefix(':');
805 typeValue
= type
.convertedValue
.getValueWithoutPrefix(':');
807 for (List
<NamespaceType
>::iterator namesp
= ns
.begin(); namesp
; namesp
= namesp
->Next
) {
808 if (prefix
== namesp
->Data
.prefix
) {
809 uri
= namesp
->Data
.uri
;
814 QualifiedName
in(uri
, typeValue
); // ns uri + original name
816 // Check all known types
817 QualifiedNames::iterator origTN
= TTCN3ModuleInventory::getInstance().getTypenames().begin();
818 for (; origTN
; origTN
= origTN
->Next
) {
819 if (origTN
->Data
== in
) {
820 QualifiedName
tmp_name(module
->getTargetNamespace(), name
.convertedValue
);
821 if (origTN
->Data
!= tmp_name
){
827 if (origTN
!= NULL
) {
828 setTypeValue(origTN
->Data
.name
);
831 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
, type
.no_replace
);
836 void ComplexType::nameConversion_fields(const List
<NamespaceType
> & ns
) {
837 QualifiedNames used_field_names
;
839 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
840 field
->Data
->nameConversion_names(used_field_names
);
843 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
844 if (field
->Data
->getMinOccurs() == 0 && field
->Data
->getMaxOccurs() == 0) {
847 if (!field
->Data
->isVisible()) {
851 field
->Data
->nameConversion_fields(ns
);
853 Mstring prefix
= field
->Data
->getType().convertedValue
.getPrefix(':');
854 Mstring typeValue
= field
->Data
->getType().convertedValue
.getValueWithoutPrefix(':');
857 var
= getModule()->getTargetNamespace();
858 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
);
860 field
->Data
->addVariant(V_onlyValue
, var
);
861 var
= getModule()->getTargetNamespace();
863 if (field
->Data
->getName().list_extension
) {
864 field
->Data
->useNameListProperty();
865 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
866 used_field_names
, field_name
, res
, var
);
867 field
->Data
->setNameValue(res
);
868 bool found_in_variant
= false;
869 for (List
<Mstring
>::iterator vari
= field
->Data
->getVariant().begin(); vari
; vari
= vari
->Next
) {
870 if (vari
->Data
== Mstring("\"untagged\"")) {
871 found_in_variant
= true;
875 if (!field
->Data
->getName().originalValueWoPrefix
.empty() &&
876 field
->Data
->getName().originalValueWoPrefix
!= "sequence" &&
877 field
->Data
->getName().originalValueWoPrefix
!= "choice" &&
878 field
->Data
->getName().originalValueWoPrefix
!= "elem" &&
880 field
->Data
->addVariant(V_nameAs
, field
->Data
->getName().originalValueWoPrefix
);
884 if (!found_in_variant
) {
885 field
->Data
->addVariant(V_untagged
, empty_string
, true);
888 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
889 used_field_names
, field_name
, res
, var
);
890 field
->Data
->setNameValue(res
);
891 field
->Data
->addVariant(V_onlyValue
, var
);
897 void ComplexType::setFieldPaths(Mstring path
) {
900 Mstring field_prefix
= empty_string
;
901 if(parent
->minOccurs
== 0 && parent
->maxOccurs
== ULLONG_MAX
){
902 field_prefix
= "[-].";
904 path
= field_prefix
+ getName().convertedValue
;
905 actualPath
= field_prefix
+ getName().convertedValue
;
907 actualPath
= getName().convertedValue
;
909 } else if (parent
!= NULL
&& (parent
->getMinOccurs() != 1 || parent
->getMaxOccurs() != 1) &&
910 (parent
->getName().list_extension
|| parent
->mode
== listMode
)) {
911 path
= path
+ Mstring("[-].") + getName().convertedValue
;
914 path
= path
+ Mstring(".") + getName().convertedValue
;
918 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
919 field
->Data
->setFieldPaths(path
);
921 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
922 attr
->Data
->setFieldPath(path
);
926 void ComplexType::finalModification2() {
927 //Call SimpleType finalModification
928 SimpleType::finalModification();
930 //Set isOptional field
931 isOptional
= isOptional
|| (minOccurs
== 0 && maxOccurs
== 1);
934 List
<Mstring
> enumNames
;
935 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
936 nextField
= field
->Next
;
937 //Remove invisible fields
938 if ((field
->Data
->minOccurs
== 0 && field
->Data
->maxOccurs
== 0) || !field
->Data
->isVisible()) {
941 complexfields
.remove(field
);
944 field
->Data
->finalModification2();
945 //collect <xsd:all> elements
946 if (field
->Data
->fromAll
) {
947 enumNames
.push_back(field
->Data
->getName().convertedValue
);
952 ComplexType
* embedField
= NULL
;
953 ComplexType
* enumField
= NULL
;
955 //Find the embed and order fields, and remove them
956 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
957 nextField
= field
->Next
;
958 if (field
->Data
->embed
) {
959 embedField
= new ComplexType(*field
->Data
);
960 embedField
->parent
= this;
963 complexfields
.remove(field
);
964 } else if (field
->Data
->enumerated
) {
965 enumField
= new ComplexType(*field
->Data
);
966 enumField
->parent
= this;
969 complexfields
.remove(field
);
973 if (enumField
!= NULL
) {
974 //Insert the order field in the front
975 complexfields
.push_front(enumField
);
976 //Push the field names into the order field
977 for (List
<Mstring
>::iterator field
= enumNames
.begin(); field
; field
= field
->Next
) {
978 enumField
->enumfields
.push_back(field
->Data
);
982 if (embedField
!= NULL
) {
983 //Insert the embed field to the front
984 complexfields
.push_front(embedField
);
989 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
990 if (field
->Data
->name
.convertedValue
.foundAt("alt_") == field
->Data
->name
.convertedValue
.c_str()) {
992 field
->Data
->name
.upload(Mstring("alt_"));
994 field
->Data
->name
.upload(Mstring(mprintf("alt_%d", number
)));
1001 AttributeType
* anyAttr
= NULL
;
1002 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(), nextField
; field
; field
= nextField
) {
1003 nextField
= field
->Next
;
1004 field
->Data
->applyUseAttribute();
1005 //Find anyattribute, and remove it
1006 if (field
->Data
->isAnyAttribute()) {
1007 anyAttr
= new AttributeType(*field
->Data
);
1008 setParent(this, anyAttr
);
1011 attribfields
.remove(field
);
1012 } else if (field
->Data
->getUseVal() == prohibited
|| !field
->Data
->isVisible()) {
1013 //Not visible attribute removed
1016 attribfields
.remove(field
);
1018 field
->Data
->SimpleType::finalModification();
1022 //Push anyattribute to the front
1023 if (anyAttr
!= NULL
) {
1024 anyAttr
->applyNamespaceAttribute(V_anyAttributes
);
1025 attribfields
.push_back(anyAttr
);
1028 //Substitution group ordering
1029 if(subsGroup
== this || typeSubsGroup
== this){ //We are a generated substitution group
1030 //Substitution group never empty
1031 ComplexType
* front
= complexfields
.front();
1032 List
<ComplexType
*>::iterator it
= complexfields
.begin();
1033 complexfields
.remove(it
);
1034 complexfields
.sort(compareComplexTypeNameSpaces
);
1035 complexfields
.sort(compareTypes
);
1036 complexfields
.push_front(front
);
1040 void ComplexType::finalModification() {
1041 finalModification2();
1042 setFieldPaths(empty_string
);
1043 List
<Mstring
> container
;
1044 collectVariants(container
);
1046 variant
= container
;
1049 void ComplexType::printToFile(FILE * file
) {
1050 printToFile(file
, 0, false);
1053 void ComplexType::printToFile(FILE * file
, const unsigned level
, const bool is_union
) {
1057 printComment(file
, level
);
1059 fprintf(file
, "type ");
1060 if(mode
== listMode
){
1061 printMinOccursMaxOccurs(file
, is_union
);
1062 fprintf(file
, "%s", type
.convertedValue
.c_str());
1064 fprintf(file
, "%s %s", type
.convertedValue
.c_str(), name
.convertedValue
.c_str());
1066 fprintf(file
, "\n{\n");
1068 if (attribfields
.empty() && complexfields
.empty()) {
1069 fprintf(file
, "\n");
1072 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(), nextField
; c
; c
= nextField
) {
1073 nextField
= c
->Next
;
1074 if (c
->Data
->embed
|| c
->Data
->enumerated
) {
1075 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1076 if (c
->Next
!= NULL
|| !attribfields
.empty()) {
1077 fprintf(file
, ",\n");
1079 fprintf(file
, "\n");
1083 complexfields
.remove(c
);
1087 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1088 f
->Data
->printToFile(file
, level
+ 1);
1089 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1090 fprintf(file
, ",\n");
1092 fprintf(file
, "\n");
1096 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1097 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1098 if (c
->Next
!= NULL
) {
1099 fprintf(file
, ",\n");
1101 fprintf(file
, "\n");
1105 const bool field_is_record
= getType().convertedValue
== Mstring("record");
1106 const bool field_is_union
= getType().convertedValue
== "union";
1107 if (complexfields
.empty() && attribfields
.empty() && (field_is_record
|| field_is_union
)) {
1108 if (field_is_record
) {
1109 indent(file
, level
);
1110 printMinOccursMaxOccurs(file
, is_union
);
1111 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1112 indent(file
, level
);
1113 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1115 fprintf(file
, " optional");
1117 } else if (field_is_union
) {
1118 indent(file
, level
);
1119 printMinOccursMaxOccurs(file
, is_union
);
1120 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1121 indent(file
, level
+ 1);
1122 fprintf(file
, "record length(0 .. 1) of enumerated { NULL_ } choice\n");
1123 indent(file
, level
);
1124 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1126 fprintf(file
, " optional");
1130 indent(file
, level
);
1131 if (getEnumeration().modified
) {
1132 if (isFloatType(getBuiltInBase())) {
1133 fprintf(file
, "%s (", type
.convertedValue
.c_str());
1134 getEnumeration().sortFacets();
1135 getEnumeration().printToFile(file
);
1138 printMinOccursMaxOccurs(file
, with_union
);
1139 fprintf(file
, "enumerated {\n");
1140 //getEnumeration().sortFacets();
1141 getEnumeration().printToFile(file
, level
);
1142 fprintf(file
, "\n");
1143 indent(file
, level
);
1144 fprintf(file
, "} ");
1147 int multiplicity
= multi(module
, getReference(), this);
1148 if ((multiplicity
> 1) && getReference().get_ref()) {
1149 fprintf(file
, "%s.", getReference().get_ref()->getModule()->getModulename().c_str());
1151 if (field_is_record
|| field_is_union
) {
1152 printMinOccursMaxOccurs(file
, with_union
, !first_child
|| parent
->getXsdtype() != n_choice
);
1153 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1154 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1155 f
->Data
->printToFile(file
, level
+ 1);
1156 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1157 fprintf(file
, ",\n");
1159 fprintf(file
, "\n");
1163 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1164 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1165 if (c
->Next
!= NULL
) {
1166 fprintf(file
, ",\n");
1168 fprintf(file
, "\n");
1172 printMinOccursMaxOccurs(file
, with_union
, !first_child
);
1173 fprintf(file
, "%s ", getType().convertedValue
.c_str());
1174 if (getName().convertedValue
== Mstring("order") && getType().convertedValue
== Mstring("enumerated")) {
1175 fprintf(file
, "{\n");
1176 for (List
<Mstring
>::iterator e
= enumfields
.begin(); e
; e
= e
->Next
) {
1177 indent(file
, level
+ 1);
1178 fprintf(file
, "%s", e
->Data
.c_str());
1179 if (e
->Next
!= NULL
) {
1180 fprintf(file
, ",\n");
1182 fprintf(file
, "\n");
1185 indent(file
, level
);
1186 fprintf(file
, "} ");
1190 if (field_is_record
|| field_is_union
) {
1191 indent(file
, level
);
1192 fprintf(file
, "} ");
1195 fprintf(file
, "%s", getName().convertedValue
.c_str());
1196 getPattern().printToFile(file
);
1197 getValue().printToFile(file
);
1198 getLength().printToFile(file
);
1199 if (!with_union
&& isOptional
) {
1200 fprintf(file
, " optional");
1207 if(mode
== listMode
){
1208 fprintf(file
, " %s", name
.convertedValue
.c_str());
1211 fprintf(file
, ";\n\n\n");
1215 void ComplexType::collectVariants(List
<Mstring
>& container
) {
1217 if (e_flag_used
|| !isVisible()) {
1222 bool useUnionVariantWhenMainTypeIsRecordOf
= false;
1223 for (List
<Mstring
>::iterator var
= variant
.end(); var
; var
= var
->Prev
) {
1224 if ((minOccurs
!= 1 || maxOccurs
!= 1) && (var
->Data
== "\"useUnion\"")) { // main type is a record of
1225 useUnionVariantWhenMainTypeIsRecordOf
= true; // TR HL15893
1227 container
.push_back(Mstring("variant ") + Mstring(var
->Data
.c_str()) + Mstring(";\n"));
1230 if (useUnionVariantWhenMainTypeIsRecordOf
) {
1231 container
.push_back(Mstring("variant ([-]) \"useUnion\";\n"));
1233 for (List
<Mstring
>::iterator var
= hidden_variant
.end(); var
; var
= var
->Prev
) {
1234 container
.push_back(Mstring("//variant ") + Mstring(var
->Data
.c_str()) + Mstring(";\n"));
1238 //Collect variants of attributes
1239 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1240 field
->Data
->collectVariants(container
);
1243 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1245 if (!field
->Data
->isVisible()) {
1249 if (field
->Data
->getVariant().empty() && field
->Data
->getHiddenVariant().empty() &&
1250 field
->Data
->complexfields
.empty() && field
->Data
->attribfields
.empty() &&
1251 field
->Data
->enumeration
.variants
.empty()) {
1255 bool already_used
= false;
1257 for (List
<Mstring
>::iterator var2
= field
->Data
->getVariant().end(); var2
; var2
= var2
->Prev
) {
1258 if (var2
->Data
== "\"untagged\"" && !already_used
) {
1259 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1260 already_used
= true;
1262 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1263 (field
->Data
->getName().list_extension
|| var2
->Data
== "\"useUnion\"")) {
1264 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1265 } else if (var2
->Data
!= "\"untagged\"") {
1266 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1270 for (List
<Mstring
>::iterator hidden_var
= field
->Data
->getHiddenVariant().end();
1271 hidden_var
; hidden_var
= hidden_var
->Prev
) {
1272 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1273 field
->Data
->getName().list_extension
) {
1274 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1276 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1280 if(field
->Data
->enumeration
.modified
){
1281 Mstring path
= empty_string
;
1282 if(field
->Data
->getMinOccurs() != 1 && field
->Data
->getMaxOccurs() != 1){
1283 path
= field
->Data
->actualPath
+ Mstring("[-]");
1285 path
= field
->Data
->actualPath
;
1287 for(List
<Mstring
>::iterator var
= field
->Data
->enumeration
.variants
.end(); var
; var
= var
->Prev
){
1288 if(var
->Data
.empty()) continue;
1289 container
.push_back("variant (" + path
+ ") " + var
->Data
+ ";\n");
1293 field
->Data
->collectVariants(container
);
1297 void ComplexType::printVariant(FILE * file
) {
1302 bool foundAtLeastOneVariant
= false;
1303 bool foundAtLeastOneHiddenVariant
= false;
1305 if (!variant
.empty()) {
1306 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1307 if (foundAtLeastOneVariant
&& foundAtLeastOneHiddenVariant
) {
1310 if (var
->Data
[0] != '/') {
1311 foundAtLeastOneVariant
= true;
1313 foundAtLeastOneHiddenVariant
= true;
1318 if (!foundAtLeastOneVariant
&& !foundAtLeastOneHiddenVariant
) {
1322 if (!foundAtLeastOneVariant
) {
1323 //No other variants, only commented, so the 'with' must be commented also.
1324 fprintf(file
, ";\n//with {\n");
1326 fprintf(file
, "\nwith {\n");
1329 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1330 fprintf(file
, "%s", var
->Data
.c_str());
1333 if (!foundAtLeastOneVariant
) {
1334 fprintf(file
, "//");
1339 void ComplexType::dump(unsigned int depth
) const {
1340 fprintf(stderr
, "%*s %sComplexType at %p | Top:%s\n", depth
* 2, "", isVisible() ? "" : "(hidden)", (const void*) this, top
? "true" : "false");
1341 if (parent
!= NULL
) {
1342 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %i | my xsdtype: %i\n", depth
* 2, "", (const void*) parent
, parent
->getXsdtype(), xsdtype
);
1344 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %s | my xsdtype: %i\n", depth
* 2, "", "NULL", "NULL", xsdtype
);
1346 fprintf(stderr
, "%*s name='%s' -> '%s', type='%s' %d complexfields | %s | %s | %s\n", depth
* 2, "",
1347 name
.originalValueWoPrefix
.c_str(), name
.convertedValue
.c_str(), type
.convertedValue
.c_str(), (int) complexfields
.size(),
1348 outside_reference
.empty() ? "" : outside_reference
.get_val().c_str(), mode
== restrictionMode
? "restriction" : "",
1349 mode
== extensionMode
? "extension" : "");
1350 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1351 field
->Data
->dump(depth
+ 1);
1353 fprintf(stderr
, "%*s %d attribields\n", depth
* 2, "", (int) attribfields
.size());
1354 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1355 field
->Data
->dump(depth
+ 1);
1357 fprintf(stderr
, "%*s %d enumfields\n", depth
* 2, "", (int) enumfields
.size());
1358 for (List
<Mstring
>::iterator field
= enumfields
.begin(); field
; field
= field
->Next
) {
1359 fprintf(stderr
, "%*s enum: %s\n", depth
* 2 + depth
, "", field
->Data
.c_str());
1361 fprintf(stderr
, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth
+ 1) * 2, "", minOccurs
, maxOccurs
, isOptional
? "true" : "false", name
.list_extension
? "true" : "false");
1362 fprintf(stderr
, "%*s %d variants: ", (depth
+ 1) * 2, "", (int) variant
.size());
1363 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1364 fprintf(stderr
, "%s, ", var
->Data
.c_str());
1366 fprintf(stderr
, "%*s pattern:%s | length:%i \n ", (depth
+ 1) * 2, "", this->pattern
.facet
.c_str(), (int) (this->length
.facet_maxLength
));
1367 fprintf(stderr
, "%*s enum: %i \n", (depth
+ 1)*2, "", (int) this->enumeration
.facets
.size());
1368 fprintf(stderr
, "\n");
1371 void ComplexType::setMinMaxOccurs(const unsigned long long min
, const unsigned long long max
, const bool generate_list_postfix
) {
1373 if (min
!= 1 || max
!= 1) {
1374 if (xsdtype
== n_choice
) {
1377 addVariant(V_untagged
);
1378 first_child
= false;
1379 } else if (xsdtype
== n_sequence
) {
1380 ComplexType
* rec
= new ComplexType(this);
1381 rec
->type
.upload(Mstring("record"));
1382 rec
->name
.upload(Mstring("sequence"));
1383 rec
->setXsdtype(n_sequence
);
1384 rec
->addVariant(V_untagged
);
1385 rec
->addVariant(V_untagged
);
1386 rec
->minOccurs
= min
;
1387 rec
->maxOccurs
= max
;
1388 complexfields
.push_back(rec
);
1390 if ((rec
->minOccurs
== 0 && rec
->maxOccurs
> 1) || rec
->minOccurs
> 0) {
1391 rec
->name
.list_extension
= true;
1396 if ((minOccurs
== 0 && maxOccurs
> 1) || minOccurs
> 0) {
1397 if (generate_list_postfix
) {
1398 name
.list_extension
= true;
1401 if (parent
!= NULL
&& parent
->getXsdtype() == n_choice
) {
1402 name
.list_extension
= true;
1403 if ((parent
!= NULL
&& parent
->getXsdtype() == n_choice
)) {
1404 if (parent
->first_child
== false && minOccurs
== 0) {
1405 parent
->first_child
= true;
1407 first_child
= false;
1417 if (maxOccurs
> 1 && generate_list_postfix
) {
1418 name
.list_extension
= true;
1422 void ComplexType::applyNamespaceAttribute(VariantMode varLabel
, const Mstring
& ns_list
) {
1423 List
<Mstring
> namespaces
;
1424 if (!ns_list
.empty()) {
1425 expstring_t valueToSplitIntoTokens
= mcopystr(ns_list
.c_str());
1427 token
= strtok(valueToSplitIntoTokens
, " ");
1428 while (token
!= NULL
) {
1429 namespaces
.push_back(Mstring(token
));
1430 token
= strtok(NULL
, " ");
1432 Free(valueToSplitIntoTokens
);
1437 // Note: libxml2 will verify the namespace list according to the schema
1438 // of XML Schema. It is either ##any, ##other, ##local, ##targetNamespace,
1439 // or a list of (namespace reference | ##local | ##targetNamespace).
1440 for (List
<Mstring
>::iterator ns
= namespaces
.begin(); ns
; ns
= ns
->Next
) {
1441 static const Mstring
xxany("##any"), xxother("##other"), xxlocal("##local"),
1442 xxtargetNamespace("##targetNamespace");
1443 if (!first
) any_ns
+= ',';
1445 if (ns
->Data
== xxany
) {
1446 }// this must be the only element, nothing to add
1447 else if (ns
->Data
== xxother
) { // this must be the only element
1448 any_ns
+= " except unqualified";
1449 if (module
->getTargetNamespace() != "NoTargetNamespace") {
1451 any_ns
+= parent
->getModule()->getTargetNamespace();
1454 }// The three cases below can happen multiple times
1456 if (first
) any_ns
+= " from ";
1457 // else a comma was already added
1458 if (ns
->Data
== xxtargetNamespace
) {
1460 any_ns
+= parent
->getModule()->getTargetNamespace();
1462 } else if (ns
->Data
== xxlocal
) {
1463 any_ns
+= "unqualified";
1474 addVariant(varLabel
, any_ns
, true);
1477 void ComplexType::addComment(const Mstring
& text
) {
1478 if (this == actfield
) {
1479 if (lastType
== n_attribute
) { // ez nem teljesen jo, stb, tobb lehetoseg, es rossy sorrend
1480 if (!attribfields
.empty()) {
1481 attribfields
.back()->addComment(text
);
1484 if (actfield
->getName().convertedValue
== Mstring("base") && parent
!= NULL
) {
1485 parent
->getComment().push_back(Mstring("/* " + text
+ " */\n"));
1487 comment
.push_back(Mstring("/* " + text
+ " */\n"));
1491 actfield
->addComment(text
);
1496 //Attribute extension logic when extending complextypes
1497 void ComplexType::applyAttributeExtension(ComplexType
* found_CT
, AttributeType
* anyAttrib
/* = NULL */) {
1498 for (List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1500 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1501 anyAttrib
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1504 for (List
<AttributeType
*>::iterator attr2
= 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 if (attr
->Data
->getUseVal() == optional
) {
1508 attr2
->Data
->setUseVal(optional
);
1516 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1517 attribfields
.push_back(newAttrib
);
1518 setParent(this, newAttrib
);
1523 //Attribute restriction logic when restricting complextypes
1524 void ComplexType::applyAttributeRestriction(ComplexType
* found_CT
) {
1525 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(), nextAttr
; attr
; attr
= nextAttr
) {
1526 nextAttr
= attr
->Next
;
1528 for (List
<AttributeType
*>::iterator attr2
= found_CT
->attribfields
.begin(); attr2
; attr2
= attr2
->Next
) {
1529 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1530 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
) {
1538 attribfields
.remove(attr
);
1541 size_t size
= found_CT
->attribfields
.size();
1542 size_t size2
= attribfields
.size();
1544 List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin();
1545 for (; i
< size
; attr
= attr
->Next
, i
= i
+ 1) {
1548 List
<AttributeType
*>::iterator attr2
= attribfields
.begin();
1549 for (; j
< size2
; attr2
= attr2
->Next
, j
= j
+ 1) {
1550 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1551 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
&& !attr2
->Data
->getUsed()) {
1553 attr2
->Data
->setUsed(true);
1558 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1559 attribfields
.push_back(newAttrib
);
1560 setParent(this, newAttrib
);
1565 void ComplexType::addNameSpaceAsVariant(RootType
* root
, RootType
* other
) {
1566 if (other
->getModule()->getTargetNamespace() != root
->getModule()->getTargetNamespace() &&
1567 other
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1568 root
->addVariant(V_namespaceAs
, other
->getModule()->getTargetNamespace());
1572 void ComplexType::resolveAttribute(AttributeType
* attr
) {
1573 if (attr
->getXsdtype() == n_attribute
&& !attr
->getReference().empty()) {
1574 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(attr
, want_BOTH
);
1576 if (attr
->isFromRef()) {
1577 addNameSpaceAsVariant(attr
, st
);
1578 attr
->setTypeOfField(st
->getName().convertedValue
);
1579 attr
->setNameOfField(st
->getName().originalValueWoPrefix
);
1580 attr
->setOrigModule(st
->getModule());
1582 attr
->setTypeOfField(st
->getName().convertedValue
);
1583 if (st
->getType().convertedValue
== "record" || st
->getType().convertedValue
== "union") {
1584 st
->addToNameDepList(attr
);
1588 printError(module
->getSchemaname(), name
.convertedValue
,
1589 "Reference for a non-defined type: " + attr
->getReference().repr());
1590 TTCN3ModuleInventory::getInstance().incrNumErrors();
1595 void ComplexType::resolveAttributeGroup(SimpleType
* st
) {
1596 if (xsdtype
== n_attributeGroup
&& !outside_reference
.empty()) {
1597 ComplexType
* ct
= (ComplexType
*) st
;
1598 if(ct
->resolved
== No
){
1599 ct
->referenceResolving();
1601 outside_reference
.set_resolved(ct
);
1603 bool addNameSpaceas
= false;
1604 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1605 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1606 addNameSpaceas
= true;
1609 if(parent
->nillable
&& parent
->parent
!= NULL
){
1610 par
= parent
->parent
;
1614 List
<AttributeType
*>::iterator anyAttrib
= par
->attribfields
.begin();
1615 for (; anyAttrib
; anyAttrib
= anyAttrib
->Next
) {
1616 if (anyAttrib
->Data
->isAnyAttribute()) {
1620 for (List
<AttributeType
*>::iterator attr
= ct
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1621 AttributeType
* attrib
= new AttributeType(*attr
->Data
);
1622 attr
->Data
->setOrigModule(ct
->getModule());
1623 if (addNameSpaceas
) {
1624 attrib
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1626 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1627 anyAttrib
->Data
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1629 //Nillable attribute placement is hard...
1630 if (parent
->nillable
&& parent
->parent
!= NULL
) {
1631 parent
->parent
->attribfields
.push_back(attrib
);
1632 attrib
->parent
= parent
->parent
;
1633 setParent(parent
->parent
, attrib
);
1634 } else if (parent
->nillable
&& !parent
->complexfields
.empty()) {
1635 parent
->complexfields
.back()->attribfields
.push_back(attrib
);
1636 attrib
->parent
= parent
->complexfields
.back();
1637 } else if (parent
->parent
!= NULL
&& (parent
->parent
->mode
== extensionMode
|| parent
->parent
->mode
== restrictionMode
)) {
1638 parent
->parent
->attribfields
.push_back(attrib
);
1639 setParent(parent
->parent
, attrib
);
1641 parent
->attribfields
.push_back(attrib
);
1642 setParent(parent
, attrib
);
1649 void ComplexType::resolveGroup(SimpleType
*st
) {
1650 if (xsdtype
== n_group
&& !outside_reference
.empty()) {
1651 ComplexType
* ct
= (ComplexType
*) st
;
1652 outside_reference
.set_resolved(ct
);
1654 if(ct
->resolved
== No
){
1655 ct
->referenceResolving();
1657 //Decide if namespaceas variant needs to be added
1658 bool addNameSpaceas
= false;
1659 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1660 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1661 addNameSpaceas
= true;
1663 if (ct
->getXsdtype() == n_sequence
&& minOccurs
== 1 && maxOccurs
== 1 && (parent
->getXsdtype() == n_complexType
|| parent
->getXsdtype() == n_sequence
)) {
1664 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1665 ComplexType
* newField
= new ComplexType(*c
->Data
);
1666 parent
->complexfields
.push_back(newField
);
1667 setParent(parent
, newField
);
1668 parent
->complexfields
.back()->setModule(getModule());
1669 if (addNameSpaceas
) {
1670 parent
->complexfields
.back()->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1673 } else if (ct
->getXsdtype() == n_all
) {
1674 //If the parent optional, then every field is optional
1675 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1676 ComplexType
* f
= new ComplexType(*c
->Data
);
1677 if (minOccurs
== 0 && !f
->enumerated
) {
1678 f
->isOptional
= true;
1680 ((ComplexType
*) parent
)->complexfields
.push_back(f
);
1681 setParent(parent
, f
);
1682 f
->setModule(getModule());
1683 if (addNameSpaceas
) {
1684 f
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1687 parent
->addVariant(V_useOrder
);
1689 if (name
.list_extension
) {
1690 addVariant(V_untagged
);
1692 type
.upload(ct
->getName().convertedValue
);
1693 name
.upload(ct
->getName().convertedValue
);
1694 ct
->addToNameDepList(this);
1697 if (addNameSpaceas
) {
1698 addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1704 void ComplexType::resolveElement(SimpleType
*st
) {
1705 if (xsdtype
== n_element
&& !outside_reference
.empty()) {
1706 outside_reference
.set_resolved(st
);
1707 type
.upload(st
->getModule()->getTargetNamespaceConnector() + Mstring(":") + st
->getName().convertedValue
);
1708 if (name
.originalValueWoPrefix
.empty()) {
1709 name
.upload(st
->getName().convertedValue
);
1712 addNameSpaceAsVariant(this, st
);
1715 collectElementTypes(st
, NULL
);
1717 //Namedep is added to the substitutions, if any
1718 if(st
->getSubstitution() != NULL
){
1719 st
->getSubstitution()->addToNameDepList(this);
1720 nameDep
= st
->getSubstitution();
1721 }if(st
->getTypeSubstitution() != NULL
){
1722 st
->getTypeSubstitution()->addToNameDepList(this);
1723 nameDep
= st
->getTypeSubstitution();
1725 st
->addToNameDepList(this);
1731 void ComplexType::resolveSimpleTypeExtension() {
1732 if (mode
== extensionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1733 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1735 if (st
->getXsdtype() != n_NOTSET
&& ((ComplexType
*) st
)->basefield
!= NULL
) { // if the xsdtype != simpletype
1736 ComplexType
* ct
= (ComplexType
*) st
;
1737 if (ct
->resolved
== No
) {
1738 ct
->referenceResolving();
1740 basefield
->outside_reference
.set_resolved(ct
);
1741 ct
->basefield
->addToNameDepList(basefield
);
1742 basefield
->nameDep
= ct
->basefield
;
1743 basefield
->mode
= extensionMode
;
1744 basefield
->applyReference(*ct
->basefield
, true);
1745 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1746 applyAttributeExtension(ct
);
1748 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1749 st
->referenceResolving();
1751 st
->addToNameDepList(basefield
);
1752 basefield
->nameDep
= st
;
1753 addNameSpaceAsVariant(basefield
, st
);
1755 } else if(!isBuiltInType(basefield
->getType().convertedValue
)){
1756 printError(module
->getSchemaname(), name
.convertedValue
,
1757 "Reference for a non-defined type: " + basefield
->getReference().repr());
1758 TTCN3ModuleInventory::getInstance().incrNumErrors();
1765 void ComplexType::resolveSimpleTypeRestriction() {
1766 if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
&& !basefield
->outside_reference
.empty()) {
1767 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1769 printError(module
->getSchemaname(), name
.convertedValue
,
1770 "Reference for a non-defined type: " + basefield
->getReference().repr());
1771 TTCN3ModuleInventory::getInstance().incrNumErrors();
1774 basefield
->outside_reference
.set_resolved(st
);
1775 if (st
->getXsdtype() != n_NOTSET
) {
1776 ComplexType
* ct
= (ComplexType
*) st
;
1777 if (ct
->resolved
== No
) {
1778 ct
->referenceResolving();
1780 applyAttributeRestriction(ct
);
1781 basefield
->mode
= restrictionMode
;
1782 if (ct
->cmode
== CT_complextype_mode
) {
1783 applyReference(*ct
, true);
1784 type
.upload(ct
->getName().convertedValue
);
1785 basefield
->setInvisible();
1786 } else if (ct
->basefield
!= NULL
) {
1787 basefield
->applyReference(*ct
->basefield
);
1788 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1789 } else if (ct
->basefield
== NULL
) {
1790 basefield
->applyReference(*ct
);
1791 addNameSpaceAsVariant(basefield
, ct
);
1794 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1795 st
->referenceResolving();
1797 if(xsdtype
== n_simpleContent
){
1798 basefield
->applyReference(*st
, true);
1799 addNameSpaceAsVariant(basefield
, st
);
1800 basefield
->mode
= restrictionMode
;
1801 }else if(xsdtype
== n_simpleType
){
1802 basefield
->setInvisible();
1803 applyReference(*basefield
, true);
1804 applyReference(*st
, true);
1805 addNameSpaceAsVariant(this, st
);
1806 basefield
->mode
= restrictionMode
;
1809 } else if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1810 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_CT
);
1811 if (ct
== NULL
&& !isBuiltInType(basefield
->getType().convertedValue
)) {
1812 printError(module
->getSchemaname(), name
.convertedValue
,
1813 "Reference for a non-defined type: " + basefield
->getReference().repr());
1814 TTCN3ModuleInventory::getInstance().incrNumErrors();
1818 basefield
->outside_reference
.set_resolved(ct
);
1820 if (ct
->resolved
== No
) {
1821 ct
->referenceResolving();
1823 for (List
<AttributeType
*>::iterator f
= ct
->attribfields
.begin(); f
; f
= f
->Next
) {
1824 AttributeType
* attr
= new AttributeType(*f
->Data
);
1825 attribfields
.push_back(attr
);
1826 setParent(this, attr
);
1828 addNameSpaceAsVariant(this, ct
);
1830 if(!basefield
->parent
->top
){
1831 applyReference(*basefield
, true);
1832 basefield
->setInvisible();
1837 void ComplexType::resolveComplexTypeExtension() {
1838 if (mode
== extensionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1839 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1841 printError(module
->getSchemaname(), name
.convertedValue
,
1842 "Reference for a non-defined type: " + getReference().repr());
1843 TTCN3ModuleInventory::getInstance().incrNumErrors();
1846 if(ct
->getXsdtype() != n_NOTSET
){
1847 outside_reference
.set_resolved(ct
);
1848 if (ct
->resolved
== No
) {
1849 ct
->referenceResolving();
1851 List
<AttributeType
*>::iterator anyAttr
= attribfields
.begin();
1852 for (; anyAttr
; anyAttr
= anyAttr
->Next
) {
1853 if (anyAttr
->Data
->isAnyAttribute()) {
1858 if (anyAttr
!= NULL
) {
1859 applyAttributeExtension(ct
, anyAttr
->Data
);
1861 applyAttributeExtension(ct
);
1864 if (ct
->getName().convertedValue
== outside_reference
.get_val() && ct
->getModule()->getTargetNamespace() == outside_reference
.get_uri()) {
1866 outside_reference
.set_resolved(ct
);
1867 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1868 if (f
->Data
!= this) { //not a self recursive field
1869 ComplexType
* newField
= new ComplexType(*f
->Data
);
1870 complexfields
.push_front(newField
);
1871 setParent(this, newField
);
1873 //Self recursive field
1874 ComplexType
* field
= new ComplexType(this);
1875 field
->name
.upload(f
->Data
->getName().convertedValue
);
1876 field
->applyReference(*f
->Data
);
1877 field
->type
.upload(ct
->getName().convertedValue
+ Mstring(".") + f
->Data
->getName().convertedValue
);
1878 field
->type
.no_replace
= true;
1879 field
->minOccurs
= f
->Data
->minOccurs
;
1880 field
->maxOccurs
= f
->Data
->maxOccurs
;
1881 complexfields
.push_front(field
);
1882 setParent(this, field
);
1887 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1888 ComplexType
* newField
= new ComplexType(*f
->Data
);
1889 complexfields
.push_front(newField
);
1890 setParent(this, newField
);
1897 void ComplexType::resolveComplexTypeRestriction() {
1898 if (mode
== restrictionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1899 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1900 if(ct
->getXsdtype() != n_NOTSET
){
1901 if (ct
->resolved
== No
) {
1902 ct
->referenceResolving();
1904 outside_reference
.set_resolved(ct
);
1905 applyAttributeRestriction(ct
);
1907 size_t size
= complexfields
.size();
1909 List
<ComplexType
*>::iterator field
= complexfields
.begin();
1910 for (; i
< size
; field
= field
->Next
, i
= i
+ 1){
1911 List
<ComplexType
*>::iterator field2
= ct
->complexfields
.begin();
1912 for (; field2
; field2
= field2
->Next
) {
1913 if (field
->Data
->getName().convertedValue
== field2
->Data
->getName().convertedValue
&&
1914 field
->Data
->getType().convertedValue
== field2
->Data
->getType().convertedValue
) {
1915 field
->Data
->applyReference(*field2
->Data
, false);
1920 field
->Data
->setInvisible();
1927 void ComplexType::resolveUnion(SimpleType
*st
) {
1928 if (parent
!= NULL
&& parent
->with_union
&& xsdtype
== n_simpleType
&& !outside_reference
.empty()) {
1929 if (st
->getXsdtype() != n_NOTSET
) {
1930 ComplexType
* ct
= (ComplexType
*) st
;
1931 outside_reference
.set_resolved(ct
);
1932 for (List
<ComplexType
*>::iterator field
= ct
->complexfields
.begin(); field
; field
= field
->Next
) {
1933 ComplexType
* newField
= new ComplexType(*field
->Data
);
1934 parent
->complexfields
.push_back(newField
);
1935 setParent(parent
, newField
);
1942 void ComplexType::modifyAttributeParent() {
1943 if (nillable_field
!= NULL
) {
1944 ((ComplexType
*) nillable_field
)->actfield
= nillable_field
;
1950 //Element substitution
1951 void ComplexType::addSubstitution(SimpleType
* st
){
1952 ComplexType
* element
;
1953 if(st
->getXsdtype() == n_NOTSET
|| !complexfields
.empty()){
1954 element
= new ComplexType(*st
, fromTagSubstitution
);
1956 element
= new ComplexType(*(ComplexType
*)st
);
1957 element
->variant
.clear();
1959 element
->subsGroup
= this;
1960 element
->parent
= this;
1961 if(complexfields
.empty()){ //The first element(head) is the st
1962 element
->setTypeValue(st
->getType().convertedValue
);
1963 if(st
->hasVariant(Mstring("\"abstract\""))){
1964 element
->addVariant(V_abstract
);
1966 if(st
->getReference().get_ref() != NULL
){
1967 ((SimpleType
*)st
->getReference().get_ref())->addToNameDepList(element
);
1968 nameDep
= ((SimpleType
*)st
->getReference().get_ref());
1970 module
->addElementType(element
->getType().convertedValue
, element
);
1971 element
->addVariant(V_formAs
, Mstring("qualified"));
1974 if(st
->getType().convertedValue
== "anyType"){
1975 newType
= complexfields
.front()->getType().convertedValue
;
1977 newType
= st
->getName().convertedValue
;
1978 st
->addToNameDepList(element
);
1979 element
->nameDep
= st
;
1981 element
->setTypeValue(newType
);
1982 BlockValue front_block
= complexfields
.front()->getBlock();
1983 if(front_block
== all
|| front_block
== substitution
){
1984 element
->addVariant(V_block
);
1985 }else if(front_block
== restriction
|| front_block
== extension
){
1986 const Mstring
& head_type
= complexfields
.front()->getType().convertedValue
.getValueWithoutPrefix(':');
1987 //To decide if they came from a common ancestor
1988 Mstring elem_type
= findRoot(front_block
, st
, head_type
, true);
1989 if(head_type
== elem_type
){
1990 element
->addVariant(V_block
);
1995 element
->setNameValue(st
->getName().convertedValue
);
1996 element
->top
= false;
1997 complexfields
.push_back(element
);
2000 void ComplexType::addTypeSubstitution(SimpleType
* st
){
2001 ComplexType
* element
;
2002 if(st
->getXsdtype() == n_NOTSET
|| !complexfields
.empty()){
2003 element
= new ComplexType(*st
, fromTypeSubstitution
);
2005 //Only need a plain complextype
2007 element
= new ComplexType(this);
2008 //Just the block needed from st
2009 element
->block
= st
->getBlock();
2011 st
->addToNameDepList(element
);
2012 element
->nameDep
= st
;
2013 element
->typeSubsGroup
= this;
2014 element
->parent
= this;
2015 if(complexfields
.empty()){ //The first element(head) is the st
2016 if(st
->hasVariant(Mstring("\"abstract\""))){
2017 element
->addVariant(V_abstract
);
2020 BlockValue front_block
= complexfields
.front()->getBlock();
2021 if(front_block
== all
){
2022 element
->addVariant(V_block
);
2023 }else if(front_block
== restriction
|| front_block
== extension
){
2024 const Mstring
& head_type
= complexfields
.front()->getType().convertedValue
.getValueWithoutPrefix(':');
2025 //To decide if they came from a common ancestor
2026 Mstring elem_type
= findRoot(front_block
, st
, head_type
, true);
2027 if(head_type
== elem_type
){
2028 element
->addVariant(V_block
);
2032 element
->top
= false;
2033 complexfields
.push_back(element
);
2034 element
->setTypeValue(st
->getName().convertedValue
.getValueWithoutPrefix(':'));
2035 element
->setNameValue(st
->getName().convertedValue
.getValueWithoutPrefix(':'));
2038 Mstring
ComplexType::findRoot(const BlockValue block_value
, SimpleType
* elem
, const Mstring
& head_type
, const bool first
){
2039 const Mstring elemName
= elem
->getName().convertedValue
.getValueWithoutPrefix(':');
2040 const Mstring elemType
= elem
->getType().convertedValue
.getValueWithoutPrefix(':');
2042 if(!first
&& !isFromRef() && elemType
== head_type
){
2044 }else if((isFromRef() &&
2045 ((elem
->getMode() == restrictionMode
&& block_value
== restriction
) ||
2046 (elem
->getMode() == extensionMode
&& block_value
== extension
))) && elemType
== head_type
){
2048 }else if(!first
&& elemName
== head_type
){
2051 SimpleType
* st
= NULL
;
2052 if((elem
->getMode() == restrictionMode
&& block_value
== restriction
) ||
2053 (elem
->getMode() == extensionMode
&& block_value
== extension
)){
2054 if(!elem
->getReference().is_resolved()){
2055 elem
->referenceResolving();
2057 if(elem
->getXsdtype() != n_NOTSET
){
2058 ComplexType
* ct
= (ComplexType
*)elem
;
2059 if(ct
->basefield
!= NULL
&& ct
->basefield
->getType().convertedValue
.getValueWithoutPrefix(':') == head_type
){
2061 }else if(ct
->basefield
!= NULL
){
2062 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(ct
->basefield
, want_BOTH
);
2066 st
= (SimpleType
*)(elem
->getReference().get_ref());
2068 }else if(elem
->getMode() == noMode
&& (block_value
== restriction
|| block_value
== extension
)){
2069 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(this, elem
->getType().convertedValue
, want_BOTH
);
2071 if(st
!= NULL
&& elem
!= st
){
2072 return findRoot(block_value
, st
, head_type
, false);
2075 if(elem
->getMode() == noMode
&& !first
){
2078 return empty_string
;