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
)
37 , parentTypeSubsGroup(NULL
)
42 xsdtype
= n_complexType
;
45 ComplexType::ComplexType(ComplexType
& other
)
48 , nillable(other
.nillable
)
49 , enumerated(other
.enumerated
)
51 , with_union(other
.with_union
)
52 , first_child(other
.first_child
)
53 , fromAll(other
.fromAll
)
54 , max_alt(other
.max_alt
)
55 , skipback(other
.skipback
)
56 , lastType(other
.lastType
)
57 , actualPath(other
.actualPath
)
59 , nameDep(other
.nameDep
)
60 , nillable_field(NULL
)
63 , resolved(other
.resolved
)
64 , parentTypeSubsGroup(other
.parentTypeSubsGroup
) {
65 type
.originalValueWoPrefix
= other
.type
.originalValueWoPrefix
;
66 for (List
<AttributeType
*>::iterator attr
= other
.attribfields
.begin(); attr
; attr
= attr
->Next
) {
67 attribfields
.push_back(new AttributeType(*attr
->Data
));
68 attribfields
.back()->parent
= this;
71 for (List
<ComplexType
*>::iterator field
= other
.complexfields
.begin(); field
; field
= field
->Next
) {
72 complexfields
.push_back(new ComplexType(*field
->Data
));
73 complexfields
.back()->parent
= this;
74 if(field
->Data
== other
.basefield
){
75 basefield
= complexfields
.back();
76 }else if(field
->Data
== other
.nillable_field
){
77 nillable_field
= complexfields
.back();
81 if (other
.nameDep
!= NULL
) {
82 SimpleType
* dep
= other
.nameDep
;
83 if(dep
->getSubstitution() != NULL
){
84 dep
->getSubstitution()->addToNameDepList(this);
85 nameDep
= dep
->getSubstitution();
87 other
.nameDep
->addToNameDepList(this);
92 ComplexType::ComplexType(ComplexType
* other
)
93 : SimpleType(other
->getParser(), other
->getModule(), c_unknown
)
104 , actualPath(empty_string
)
107 , nillable_field(NULL
)
109 , cmode(CT_undefined_mode
)
111 , parentTypeSubsGroup(NULL
)
116 xsdtype
= n_complexType
;
118 outside_reference
= ReferenceData();
121 ComplexType::ComplexType(const SimpleType
& other
, CT_fromST c
)
133 , actualPath(empty_string
)
136 , nillable_field(NULL
)
138 , cmode(CT_simpletype_mode
)
140 , parentTypeSubsGroup(NULL
)
146 if(c
!= fromTagSubstitution
&& c
!= fromTypeSubstitution
){
147 module
->replaceLastMainType(this);
148 module
->setActualXsdConstruct(c_complexType
);
150 construct
= c_complexType
;
154 type
.upload(Mstring("union"));
158 case fromTagNillable
:
159 addVariant(V_useNil
);
160 type
.upload(Mstring("record"));
162 case fromTagComplexType
:
163 type
.upload(Mstring("record"));
164 xsdtype
= n_complexType
;
166 case fromTagSubstitution
:
167 type
.upload(Mstring("union"));
168 name
.upload(getName().originalValueWoPrefix
+ Mstring("_group"));
172 hidden_variant
.clear();
173 enumeration
.modified
= false;
174 value
.modified
= false;
175 pattern
.modified
= false;
176 length
.modified
= false;
177 whitespace
.modified
= false;
179 case fromTypeSubstitution
:
180 type
.upload(Mstring("union"));
181 name
.upload(getName().originalValueWoPrefix
+ Mstring("_derivations"));
183 substitutionGroup
= empty_string
;
184 typeSubsGroup
= this;
186 hidden_variant
.clear();
187 enumeration
.modified
= false;
188 value
.modified
= false;
189 pattern
.modified
= false;
190 length
.modified
= false;
191 whitespace
.modified
= false;
195 ComplexType::~ComplexType() {
196 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
200 complexfields
.clear();
202 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
206 attribfields
.clear();
209 void ComplexType::loadWithValues() {
210 //Find the last field where the tag is found
211 if (this != actfield
) {
212 actfield
->loadWithValues();
216 const XMLParser::TagAttributes
& atts
= parser
->getActualTagAttributes();
218 switch (parser
->getActualTagName()) {
220 if (!top
&& xsdtype
!= n_sequence
&& xsdtype
!= n_complexType
&& xsdtype
!= n_extension
&& xsdtype
!= n_restriction
&& xsdtype
!= n_element
) {
222 ComplexType
* rec
= new ComplexType(this);
223 rec
->type
.upload(Mstring("record"));
224 rec
->name
.upload(Mstring("sequence"));
225 rec
->addVariant(V_untagged
);
226 rec
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
227 rec
->setXsdtype(n_sequence
);
228 complexfields
.push_back(rec
);
231 //Do not create new record, it is an embedded sequence
232 if (xsdtype
== n_sequence
&& atts
.minOccurs
== 1 && atts
.maxOccurs
== 1) {
235 type
.upload(Mstring("record"));
236 xsdtype
= n_sequence
;
237 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
241 if (!top
|| xsdtype
!= n_group
) {
242 //Create new union field
243 ComplexType
* choice
= new ComplexType(this);
244 choice
->type
.upload(Mstring("union"));
245 choice
->name
.upload(Mstring("choice"));
246 choice
->setXsdtype(n_choice
);
247 choice
->addVariant(V_untagged
);
248 choice
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
250 complexfields
.push_back(choice
);
253 type
.upload(Mstring("union"));
258 //Create the record of enumerated field
260 ComplexType
* enumField
= new ComplexType(this);
261 enumField
->setTypeValue(Mstring("enumerated"));
262 enumField
->setNameValue(Mstring("order"));
263 enumField
->setBuiltInBase(Mstring("string"));
264 enumField
->enumerated
= true;
265 enumField
->setMinMaxOccurs(0, ULLONG_MAX
, false);
266 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
267 addVariant(V_useOrder
);
268 complexfields
.push_back(enumField
);
269 if (atts
.minOccurs
== 0) {
275 mode
= restrictionMode
;
276 //If it is an xsd:union then call SimpleType::loadWithValues
277 if (parent
!= NULL
&& parent
->with_union
) {
278 SimpleType::loadWithValues();
281 if (cmode
== CT_simpletype_mode
) {
282 //if it is from a SimpleType, then create a base field
283 ComplexType
* f
= new ComplexType(this);
284 f
->name
.upload(Mstring("base"));
285 f
->type
.upload(atts
.base
);
286 f
->setReference(atts
.base
);
287 f
->addVariant(V_untagged
);
288 complexfields
.push_back(f
);
291 } else if (cmode
== CT_complextype_mode
) {
292 setReference(atts
.base
);
293 xsdtype
= n_restriction
;
297 mode
= extensionMode
;
298 if (cmode
== CT_simpletype_mode
) {
299 //if it is from a SimpleType, then create a base field
300 ComplexType
* f
= new ComplexType(this);
301 f
->name
.upload(Mstring("base"));
302 f
->type
.upload(atts
.base
);
303 f
->setReference(atts
.base
);
304 f
->addVariant(V_untagged
);
305 complexfields
.push_back(f
);
308 } else if (cmode
== CT_complextype_mode
) {
309 setReference(atts
.base
);
310 xsdtype
= n_extension
;
316 if(cmode
== CT_simpletype_mode
){
317 //If a simple top level element is nillable
318 ComplexType
* nilrec
= new ComplexType(this);
319 if (atts
.type
.empty()) {
320 nilrec
->type
.upload(Mstring("record"));
322 nilrec
->type
.upload(atts
.type
);
324 nilrec
->name
.upload(Mstring("content"));
325 nilrec
->isOptional
= true;
326 nilrec
->nillable
= true;
327 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
328 complexfields
.push_back(nilrec
);
329 type
.upload(Mstring("record"));
330 name
.upload(atts
.name
);
332 nillable_field
= nilrec
;
334 //From a complexType element is nillable
335 ComplexType
* record
= new ComplexType(this);
336 ComplexType
* nilrec
= new ComplexType(record
);
337 if (atts
.type
.empty()) {
338 nilrec
->type
.upload(Mstring("record"));
340 nilrec
->type
.upload(atts
.type
);
342 record
->name
.upload(atts
.name
);
343 record
->type
.upload(Mstring("record"));
344 record
->complexfields
.push_back(nilrec
);
345 record
->addVariant(V_useNil
);
346 record
->nillable_field
= nilrec
;
347 record
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
349 nilrec
->name
.upload(Mstring("content"));
350 nilrec
->nillable
= true;
351 nilrec
->isOptional
= true;
352 nilrec
->tagNames
.push_back(parser
->getActualTagName());
353 complexfields
.push_back(record
);
357 //It is a simple element
358 ComplexType
* c
= new ComplexType(this);
359 c
->setXsdtype(n_element
);
360 c
->type
.upload(atts
.type
);
361 c
->name
.upload(atts
.name
);
362 c
->setReference(atts
.type
);
363 c
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
364 c
->applyDefaultAttribute(atts
.default_
);
365 c
->applyFixedAttribute(atts
.fixed
);
366 c
->setElementFormAs(atts
.form
);
367 if (atts
.ref
.empty()) {
368 c
->setReference(atts
.type
);
370 c
->applyRefAttribute(atts
.ref
);
371 c
->name
.upload(atts
.ref
.getValueWithoutPrefix(':'));
372 c
->type
.upload(atts
.ref
);
374 c
->applySubstitionGroupAttribute(atts
.substitionGroup
);
375 c
->applyBlockAttribute(atts
.block
);
378 //Inside all have some special conditions
379 if (xsdtype
== n_all
) {
380 if (atts
.minOccurs
> 1) {
381 printError(getModule()->getSchemaname(), name
.convertedValue
,
382 Mstring("Inside <all>, minOccurs must be 0 or 1"));
383 TTCN3ModuleInventory::incrNumErrors();
385 if (atts
.maxOccurs
!= 1) {
386 printError(getModule()->getSchemaname(), name
.convertedValue
,
387 Mstring("Inside <all>, maxOccurs must be 1"));
388 TTCN3ModuleInventory::incrNumErrors();
391 complexfields
.push_back(c
);
393 c
->isOptional
= true;
396 complexfields
.push_back(c
);
403 AttributeType
* attribute
= new AttributeType(this);
404 attribute
->addVariant(V_attribute
);
405 attribute
->applyMinMaxOccursAttribute(0, 1);
406 attribute
->setXsdtype(n_attribute
);
407 attribute
->applyDefaultAttribute(atts
.default_
);
408 attribute
->applyFixedAttribute(atts
.fixed
);
409 attribute
->setUseVal(atts
.use
);
410 attribute
->setAttributeFormAs(atts
.form
);
411 lastType
= n_attribute
;
412 if (atts
.ref
.empty()) {
413 attribute
->setNameOfField(atts
.name
);
414 attribute
->setTypeOfField(atts
.type
);
415 attribute
->setReference(atts
.type
, true);
417 attribute
->applyRefAttribute(atts
.ref
);
419 actfield
= attribute
;
421 //In case of nillable parent it is difficult...
422 if (nillable
&& parent
!= NULL
) {
423 parent
->attribfields
.push_back(attribute
);
424 attribute
->parent
= parent
;
425 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
426 complexfields
.back()->attribfields
.push_back(attribute
);
427 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
428 parent
->attribfields
.push_back(attribute
);
429 attribute
->parent
= parent
;
431 attribfields
.push_back(attribute
);
437 ComplexType
* any
= new ComplexType(this);
438 any
->name
.upload(Mstring("elem"));
439 any
->type
.upload(Mstring("xsd:string"));
440 any
->applyNamespaceAttribute(V_anyElement
, atts
.namespace_
);
441 any
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
442 any
->setXsdtype(n_any
);
443 complexfields
.push_back(any
);
448 AttributeType
* anyattr
= new AttributeType(this);
449 anyattr
->setXsdtype(n_anyAttribute
);
450 anyattr
->setNameOfField(Mstring("attr"));
451 anyattr
->setTypeValue(Mstring("xsd:string"));
452 anyattr
->setToAnyAttribute();
453 anyattr
->applyMinMaxOccursAttribute(0, ULLONG_MAX
);
454 anyattr
->addNameSpaceAttribute(atts
.namespace_
);
457 //In case of nillable parent it is difficult...
458 if (nillable
&& parent
!= NULL
) {
459 parent
->attribfields
.push_back(anyattr
);
460 anyattr
->parent
= parent
;
461 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
462 complexfields
.back()->attribfields
.push_back(anyattr
);
463 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
464 parent
->attribfields
.push_back(anyattr
);
465 anyattr
->parent
= parent
;
467 attribfields
.push_back(anyattr
);
471 case n_attributeGroup
:
472 if (!atts
.ref
.empty()) {
473 ComplexType
* g
= new ComplexType(this);
474 g
->setXsdtype(n_attributeGroup
);
475 g
->setReference(atts
.ref
);
476 complexfields
.push_back(g
);
479 xsdtype
= n_attributeGroup
;
480 name
.upload(Mstring(atts
.name
));
485 if (atts
.ref
.empty()) {
488 name
.upload(atts
.name
);
491 ComplexType
* group
= new ComplexType(this);
492 group
->setXsdtype(n_group
);
493 group
->name
.upload(atts
.name
);
494 group
->setReference(Mstring(atts
.ref
));
495 group
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
496 complexfields
.push_back(group
);
504 type
.upload(Mstring("union"));
505 addVariant(V_useUnion
);
506 if (!atts
.memberTypes
.empty()) {
508 //Get the union values
509 expstring_t valueToSplitIntoTokens
= mcopystr(atts
.memberTypes
.c_str());
511 token
= strtok(valueToSplitIntoTokens
, " ");
512 while (token
!= NULL
) {
513 types
.push_back(Mstring(token
));
514 token
= strtok(NULL
, " ");
516 Free(valueToSplitIntoTokens
);
518 //Create the union elements and push into the container
519 for (List
<Mstring
>::iterator memberType
= types
.begin(); memberType
; memberType
= memberType
->Next
) {
520 Mstring tmp_name
= memberType
->Data
.getValueWithoutPrefix(':');
521 ComplexType
* f
= new ComplexType(this);
522 f
->name
.upload(tmp_name
);
523 f
->type
.upload(memberType
->Data
);
524 f
->setXsdtype(n_simpleType
);
525 f
->setReference(memberType
->Data
);
526 complexfields
.push_back(f
);
532 case n_simpleContent
:
534 xsdtype
= parser
->getActualTagName();
535 cmode
= CT_simpletype_mode
;
539 fieldname
= Mstring("alt_");
541 fieldname
= mprintf("alt_%d", max_alt
);
544 ComplexType
* field
= new ComplexType(this);
545 field
->name
.upload(fieldname
);
546 field
->setXsdtype(n_simpleType
);
547 field
->addVariant(V_nameAs
, empty_string
, true);
548 complexfields
.push_back(field
);
554 name
.upload(atts
.name
);
555 type
.upload(Mstring("record"));
556 applyAbstractAttribute(atts
.abstract
);
557 applySubstitionGroupAttribute(atts
.substitionGroup
);
558 applyBlockAttribute(atts
.block
);
560 case n_complexContent
:
561 tagNames
.push_back(parser
->getActualTagName());
562 cmode
= CT_complextype_mode
;
564 ComplexType
* mixed
= new ComplexType(this);
565 mixed
->name
.upload(Mstring("embed_values"));
566 mixed
->type
.upload(Mstring("xsd:string"));
567 mixed
->setMinMaxOccurs(0, ULLONG_MAX
, false);
569 complexfields
.push_back(mixed
);
570 addVariant(V_embedValues
);
585 case n_fractionDigits
:
586 SimpleType::loadWithValues();
589 addComment(Mstring("LABEL:"));
592 addComment(Mstring("DEFINITION:"));
599 // called from endelementHandler
600 void ComplexType::modifyValues() {
601 if (this != actfield
) {
602 actfield
->modifyValues();
605 if (xsdtype
== n_sequence
) {
606 skipback
= skipback
- 1;
609 if ((xsdtype
== n_element
||
610 xsdtype
== n_complexType
||
611 xsdtype
== n_complexContent
||
613 xsdtype
== n_attribute
||
614 xsdtype
== n_anyAttribute
||
615 xsdtype
== n_choice
||
616 xsdtype
== n_group
||
617 xsdtype
== n_attributeGroup
||
618 xsdtype
== n_extension
||
619 xsdtype
== n_restriction
||
620 xsdtype
== n_simpleType
||
621 xsdtype
== n_simpleContent
||
622 (xsdtype
== n_sequence
&& skipback
< 0)
625 if (!tagNames
.empty() && tagNames
.back() == parser
->getParentTagName()) {
626 if (nillable
&& tagNames
.back() == n_element
) {
627 parent
->modifyValues();
630 } else if (tagNames
.empty()) {
631 parent
->actfield
= parent
;
632 parent
->lastType
= xsdtype
;
637 void ComplexType::referenceResolving() {
638 if (resolved
!= No
) return; // nothing to do
639 if(this == subsGroup
){
643 resolved
= InProgress
;
644 for (List
<ComplexType
*>::iterator ct
= complexfields
.begin(); ct
; ct
= ct
->Next
) {
645 // Referenece resolving of ComplexTypes
646 ct
->Data
->referenceResolving();
648 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
649 //Reference resolving for Attributes
650 resolveAttribute(attr
->Data
);
653 reference_resolving_funtion();
655 if(!substitutionGroup
.empty()){
656 addToSubstitutions();
661 void ComplexType::reference_resolving_funtion() {
662 //Every child element references are resolved here.
663 if (outside_reference
.empty() && basefield
== NULL
) {
664 //Its not in the resolveElement function because we need the built in type
665 //reference too, and then the outside_reference is empty.
666 if(xsdtype
== n_element
){
667 collectElementTypes(NULL
, NULL
);
672 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_BOTH
);
673 if (st
== NULL
&& basefield
== NULL
) {
674 printError(module
->getSchemaname(), name
.convertedValue
,
675 "Reference for a non-defined type: " + getReference().repr());
676 TTCN3ModuleInventory::getInstance().incrNumErrors();
677 outside_reference
.set_resolved(NULL
);
681 resolveAttributeGroup(st
);
687 resolveSimpleTypeExtension();
689 resolveSimpleTypeRestriction();
691 resolveComplexTypeExtension();
693 resolveComplexTypeRestriction();
697 addToTypeSubstitutions();
701 void ComplexType::setParent(ComplexType
* par
, SimpleType
* child
) {
705 void ComplexType::applyReference(const SimpleType
& other
, const bool on_attributes
) {
706 type
.convertedValue
= other
.getType().convertedValue
;
707 type
.originalValueWoPrefix
= other
.getType().convertedValue
.getValueWithoutPrefix(':');
709 if (other
.getMinOccurs() > minOccurs
|| other
.getMaxOccurs() < maxOccurs
) {
710 if (!on_attributes
) {
711 expstring_t temp
= memptystr();
714 "The occurrence range (%llu .. %llu) of the element (%s) is not compatible "
715 "with the occurrence range (%llu .. %llu) of the referenced element.",
718 name
.originalValueWoPrefix
.c_str(),
719 other
.getMinOccurs(),
720 other
.getMaxOccurs());
721 printError(module
->getSchemaname(), parent
->getName().originalValueWoPrefix
,
724 TTCN3ModuleInventory::getInstance().incrNumErrors();
727 minOccurs
= llmax(minOccurs
, other
.getMinOccurs());
728 maxOccurs
= llmin(maxOccurs
, other
.getMaxOccurs());
731 for (List
<Mstring
>::iterator var
= other
.getVariantRef().begin(); var
; var
= var
->Next
) {
733 for (List
<Mstring
>::iterator var1
= variant
.begin(); var1
; var1
= var1
->Next
) {
734 if (var
->Data
== var1
->Data
) {
740 variant
.push_back(var
->Data
);
741 variant_ref
.push_back(var
->Data
);
745 builtInBase
= other
.getBuiltInBase();
747 length
.applyReference(other
.getLength());
748 pattern
.applyReference(other
.getPattern());
749 enumeration
.applyReference(other
.getEnumeration());
750 whitespace
.applyReference(other
.getWhitespace());
751 value
.applyReference(other
.getValue());
754 void ComplexType::nameConversion(NameConversionMode conversion_mode
, const List
<NamespaceType
> & ns
) {
756 switch (conversion_mode
) {
758 nameConversion_names(ns
);
761 nameConversion_types(ns
);
764 nameConversion_fields(ns
);
769 void ComplexType::nameConversion_names(const List
<NamespaceType
> &) {
770 Mstring res
, var(module
->getTargetNamespace());
771 XSDName2TTCN3Name(name
.convertedValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_name
, res
, var
);
772 name
.convertedValue
= res
;
774 for (List
<Mstring
>::iterator vari
= variant
.begin(); vari
; vari
= vari
->Next
) {
775 if (vari
->Data
== "\"untagged\"") {
781 addVariant(V_onlyValue
, var
);
783 for (List
<SimpleType
*>::iterator dep
= nameDepList
.begin(); dep
; dep
= dep
->Next
) {
784 dep
->Data
->setTypeValue(res
);
788 void ComplexType::nameConversion_types(const List
<NamespaceType
> & ns
) {
789 attribfields
.sort(compareAttributeNameSpaces
);
790 attribfields
.sort(compareAttributeTypes
);
791 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
792 field
->Data
->nameConversion(typeMode
, ns
);
795 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
796 field
->Data
->nameConversion_types(ns
);
799 Mstring prefix
, uri
, typeValue
;
801 if (type
.convertedValue
== "record" ||
802 type
.convertedValue
== "set" ||
803 type
.convertedValue
== "union" ||
804 type
.convertedValue
== "enumerated") {
808 prefix
= type
.convertedValue
.getPrefix(':');
809 typeValue
= type
.convertedValue
.getValueWithoutPrefix(':');
811 for (List
<NamespaceType
>::iterator namesp
= ns
.begin(); namesp
; namesp
= namesp
->Next
) {
812 if (prefix
== namesp
->Data
.prefix
) {
813 uri
= namesp
->Data
.uri
;
818 QualifiedName
in(uri
, typeValue
); // ns uri + original name
820 // Check all known types
821 QualifiedNames::iterator origTN
= TTCN3ModuleInventory::getInstance().getTypenames().begin();
822 for (; origTN
; origTN
= origTN
->Next
) {
823 if (origTN
->Data
== in
) {
824 QualifiedName
tmp_name(module
->getTargetNamespace(), name
.convertedValue
);
825 if (origTN
->Data
!= tmp_name
){
831 if (origTN
!= NULL
) {
832 setTypeValue(origTN
->Data
.name
);
835 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
, type
.no_replace
);
840 void ComplexType::nameConversion_fields(const List
<NamespaceType
> & ns
) {
841 QualifiedNames used_field_names
;
843 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
844 field
->Data
->nameConversion_names(used_field_names
);
847 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
848 if (field
->Data
->getMinOccurs() == 0 && field
->Data
->getMaxOccurs() == 0) {
851 if (!field
->Data
->isVisible()) {
855 field
->Data
->nameConversion_fields(ns
);
857 Mstring prefix
= field
->Data
->getType().convertedValue
.getPrefix(':');
858 Mstring typeValue
= field
->Data
->getType().convertedValue
.getValueWithoutPrefix(':');
861 var
= getModule()->getTargetNamespace();
862 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
);
864 field
->Data
->addVariant(V_onlyValue
, var
);
865 var
= getModule()->getTargetNamespace();
867 if (field
->Data
->getName().list_extension
) {
868 field
->Data
->useNameListProperty();
869 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
870 used_field_names
, field_name
, res
, var
);
871 field
->Data
->setNameValue(res
);
872 bool found_in_variant
= false;
873 for (List
<Mstring
>::iterator vari
= field
->Data
->getVariant().begin(); vari
; vari
= vari
->Next
) {
874 if (vari
->Data
== Mstring("\"untagged\"")) {
875 found_in_variant
= true;
879 if (!field
->Data
->getName().originalValueWoPrefix
.empty() &&
880 field
->Data
->getName().originalValueWoPrefix
!= "sequence" &&
881 field
->Data
->getName().originalValueWoPrefix
!= "choice" &&
882 field
->Data
->getName().originalValueWoPrefix
!= "elem" &&
884 field
->Data
->addVariant(V_nameAs
, field
->Data
->getName().originalValueWoPrefix
);
888 if (!found_in_variant
) {
889 field
->Data
->addVariant(V_untagged
, empty_string
, true);
892 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
893 used_field_names
, field_name
, res
, var
);
894 field
->Data
->setNameValue(res
);
895 field
->Data
->addVariant(V_onlyValue
, var
);
901 void ComplexType::setFieldPaths(Mstring path
) {
904 Mstring field_prefix
= empty_string
;
905 if(parent
->minOccurs
== 0 && parent
->maxOccurs
== ULLONG_MAX
){
906 field_prefix
= "[-].";
908 path
= field_prefix
+ getName().convertedValue
;
909 actualPath
= field_prefix
+ getName().convertedValue
;
911 actualPath
= getName().convertedValue
;
913 } else if (parent
!= NULL
&& (parent
->getMinOccurs() != 1 || parent
->getMaxOccurs() != 1) &&
914 (parent
->getName().list_extension
|| parent
->mode
== listMode
)) {
915 path
= path
+ Mstring("[-].") + getName().convertedValue
;
918 path
= path
+ Mstring(".") + getName().convertedValue
;
922 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
923 field
->Data
->setFieldPaths(path
);
925 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
926 attr
->Data
->setFieldPath(path
);
930 void ComplexType::finalModification2() {
931 //Call SimpleType finalModification
932 SimpleType::finalModification();
934 //Set isOptional field
935 isOptional
= isOptional
|| (minOccurs
== 0 && maxOccurs
== 1);
938 List
<Mstring
> enumNames
;
939 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
940 nextField
= field
->Next
;
941 //Remove invisible fields
942 if ((field
->Data
->minOccurs
== 0 && field
->Data
->maxOccurs
== 0) || !field
->Data
->isVisible()) {
945 complexfields
.remove(field
);
948 field
->Data
->finalModification2();
949 //collect <xsd:all> elements
950 if (field
->Data
->fromAll
) {
951 enumNames
.push_back(field
->Data
->getName().convertedValue
);
956 ComplexType
* embedField
= NULL
;
957 ComplexType
* enumField
= NULL
;
959 //Find the embed and order fields, and remove them
960 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
961 nextField
= field
->Next
;
962 if (field
->Data
->embed
) {
963 embedField
= new ComplexType(*field
->Data
);
964 embedField
->parent
= this;
967 complexfields
.remove(field
);
968 } else if (field
->Data
->enumerated
) {
969 enumField
= new ComplexType(*field
->Data
);
970 enumField
->parent
= this;
973 complexfields
.remove(field
);
977 if (enumField
!= NULL
) {
978 //Insert the order field in the front
979 complexfields
.push_front(enumField
);
980 //Push the field names into the order field
981 for (List
<Mstring
>::iterator field
= enumNames
.begin(); field
; field
= field
->Next
) {
982 enumField
->enumfields
.push_back(field
->Data
);
986 if (embedField
!= NULL
) {
987 //Insert the embed field to the front
988 complexfields
.push_front(embedField
);
993 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
994 if (field
->Data
->name
.convertedValue
.foundAt("alt_") == field
->Data
->name
.convertedValue
.c_str()) {
996 field
->Data
->name
.upload(Mstring("alt_"));
998 field
->Data
->name
.upload(Mstring(mprintf("alt_%d", number
)));
1005 AttributeType
* anyAttr
= NULL
;
1006 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(), nextField
; field
; field
= nextField
) {
1007 nextField
= field
->Next
;
1008 field
->Data
->applyUseAttribute();
1009 //Find anyattribute, and remove it
1010 if (field
->Data
->isAnyAttribute()) {
1011 anyAttr
= new AttributeType(*field
->Data
);
1012 setParent(this, anyAttr
);
1015 attribfields
.remove(field
);
1016 } else if (field
->Data
->getUseVal() == prohibited
|| !field
->Data
->isVisible()) {
1017 //Not visible attribute removed
1020 attribfields
.remove(field
);
1022 field
->Data
->SimpleType::finalModification();
1026 //Push anyattribute to the front
1027 if (anyAttr
!= NULL
) {
1028 anyAttr
->applyNamespaceAttribute(V_anyAttributes
);
1029 attribfields
.push_back(anyAttr
);
1032 //Substitution group ordering
1033 if(subsGroup
== this || typeSubsGroup
== this){ //We are a generated substitution group
1034 //Substitution group never empty
1035 ComplexType
* front
= complexfields
.front();
1036 List
<ComplexType
*>::iterator it
= complexfields
.begin();
1037 complexfields
.remove(it
);
1038 complexfields
.sort(compareComplexTypeNameSpaces
);
1039 complexfields
.sort(compareTypes
);
1040 complexfields
.push_front(front
);
1044 void ComplexType::finalModification() {
1045 finalModification2();
1046 setFieldPaths(empty_string
);
1047 List
<Mstring
> container
;
1048 collectVariants(container
);
1050 variant
= container
;
1053 void ComplexType::printToFile(FILE * file
) {
1054 printToFile(file
, 0, false);
1057 void ComplexType::printToFile(FILE * file
, const unsigned level
, const bool is_union
) {
1061 printComment(file
, level
);
1063 fprintf(file
, "type ");
1064 if(mode
== listMode
){
1065 printMinOccursMaxOccurs(file
, is_union
);
1066 fprintf(file
, "%s", type
.convertedValue
.c_str());
1068 fprintf(file
, "%s %s", type
.convertedValue
.c_str(), name
.convertedValue
.c_str());
1070 fprintf(file
, "\n{\n");
1072 if (attribfields
.empty() && complexfields
.empty()) {
1073 fprintf(file
, "\n");
1076 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(), nextField
; c
; c
= nextField
) {
1077 nextField
= c
->Next
;
1078 if (c
->Data
->embed
|| c
->Data
->enumerated
) {
1079 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1080 if (c
->Next
!= NULL
|| !attribfields
.empty()) {
1081 fprintf(file
, ",\n");
1083 fprintf(file
, "\n");
1087 complexfields
.remove(c
);
1091 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1092 f
->Data
->printToFile(file
, level
+ 1);
1093 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1094 fprintf(file
, ",\n");
1096 fprintf(file
, "\n");
1100 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1101 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1102 if (c
->Next
!= NULL
) {
1103 fprintf(file
, ",\n");
1105 fprintf(file
, "\n");
1109 const bool field_is_record
= getType().convertedValue
== Mstring("record");
1110 const bool field_is_union
= getType().convertedValue
== "union";
1111 if (complexfields
.empty() && attribfields
.empty() && (field_is_record
|| field_is_union
)) {
1112 if (field_is_record
) {
1113 indent(file
, level
);
1114 printMinOccursMaxOccurs(file
, is_union
);
1115 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1116 indent(file
, level
);
1117 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1119 fprintf(file
, " optional");
1121 } else if (field_is_union
) {
1122 indent(file
, level
);
1123 printMinOccursMaxOccurs(file
, is_union
);
1124 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1125 indent(file
, level
+ 1);
1126 fprintf(file
, "record length(0 .. 1) of enumerated { NULL_ } choice\n");
1127 indent(file
, level
);
1128 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1130 fprintf(file
, " optional");
1134 indent(file
, level
);
1135 if (getEnumeration().modified
) {
1136 if (isFloatType(getBuiltInBase())) {
1137 fprintf(file
, "%s (", type
.convertedValue
.c_str());
1138 getEnumeration().sortFacets();
1139 getEnumeration().printToFile(file
);
1142 printMinOccursMaxOccurs(file
, with_union
);
1143 fprintf(file
, "enumerated {\n");
1144 //getEnumeration().sortFacets();
1145 getEnumeration().printToFile(file
, level
);
1146 fprintf(file
, "\n");
1147 indent(file
, level
);
1148 fprintf(file
, "} ");
1151 int multiplicity
= multi(module
, getReference(), this);
1152 if ((multiplicity
> 1) && getReference().get_ref()) {
1153 fprintf(file
, "%s.", getReference().get_ref()->getModule()->getModulename().c_str());
1155 if (field_is_record
|| field_is_union
) {
1156 printMinOccursMaxOccurs(file
, with_union
, !first_child
|| parent
->getXsdtype() != n_choice
);
1157 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1158 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1159 f
->Data
->printToFile(file
, level
+ 1);
1160 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1161 fprintf(file
, ",\n");
1163 fprintf(file
, "\n");
1167 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1168 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1169 if (c
->Next
!= NULL
) {
1170 fprintf(file
, ",\n");
1172 fprintf(file
, "\n");
1176 printMinOccursMaxOccurs(file
, with_union
, !first_child
);
1177 fprintf(file
, "%s ", getType().convertedValue
.c_str());
1178 if (getName().convertedValue
== Mstring("order") && getType().convertedValue
== Mstring("enumerated")) {
1179 fprintf(file
, "{\n");
1180 for (List
<Mstring
>::iterator e
= enumfields
.begin(); e
; e
= e
->Next
) {
1181 indent(file
, level
+ 1);
1182 fprintf(file
, "%s", e
->Data
.c_str());
1183 if (e
->Next
!= NULL
) {
1184 fprintf(file
, ",\n");
1186 fprintf(file
, "\n");
1189 indent(file
, level
);
1190 fprintf(file
, "} ");
1194 if (field_is_record
|| field_is_union
) {
1195 indent(file
, level
);
1196 fprintf(file
, "} ");
1199 fprintf(file
, "%s", getName().convertedValue
.c_str());
1200 getPattern().printToFile(file
);
1201 getValue().printToFile(file
);
1202 getLength().printToFile(file
);
1203 if (!with_union
&& isOptional
) {
1204 fprintf(file
, " optional");
1211 if(mode
== listMode
){
1212 fprintf(file
, " %s", name
.convertedValue
.c_str());
1215 fprintf(file
, ";\n\n\n");
1219 void ComplexType::collectVariants(List
<Mstring
>& container
) {
1221 if (e_flag_used
|| !isVisible()) {
1226 bool useUnionVariantWhenMainTypeIsRecordOf
= false;
1227 for (List
<Mstring
>::iterator var
= variant
.end(); var
; var
= var
->Prev
) {
1228 if ((minOccurs
!= 1 || maxOccurs
!= 1) && (var
->Data
== "\"useUnion\"")) { // main type is a record of
1229 useUnionVariantWhenMainTypeIsRecordOf
= true; // TR HL15893
1231 container
.push_back(Mstring("variant ") + Mstring(var
->Data
.c_str()) + Mstring(";\n"));
1234 if (useUnionVariantWhenMainTypeIsRecordOf
) {
1235 container
.push_back(Mstring("variant ([-]) \"useUnion\";\n"));
1237 for (List
<Mstring
>::iterator var
= hidden_variant
.end(); var
; var
= var
->Prev
) {
1238 container
.push_back(Mstring("//variant ") + Mstring(var
->Data
.c_str()) + Mstring(";\n"));
1242 //Collect variants of attributes
1243 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1244 field
->Data
->collectVariants(container
);
1247 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1249 if (!field
->Data
->isVisible()) {
1253 if (field
->Data
->getVariant().empty() && field
->Data
->getHiddenVariant().empty() &&
1254 field
->Data
->complexfields
.empty() && field
->Data
->attribfields
.empty() &&
1255 field
->Data
->enumeration
.variants
.empty()) {
1259 bool already_used
= false;
1261 for (List
<Mstring
>::iterator var2
= field
->Data
->getVariant().end(); var2
; var2
= var2
->Prev
) {
1262 if (var2
->Data
== "\"untagged\"" && !already_used
) {
1263 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1264 already_used
= true;
1266 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1267 (field
->Data
->getName().list_extension
|| var2
->Data
== "\"useUnion\"")) {
1268 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1269 } else if (var2
->Data
!= "\"untagged\"") {
1270 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1274 for (List
<Mstring
>::iterator hidden_var
= field
->Data
->getHiddenVariant().end();
1275 hidden_var
; hidden_var
= hidden_var
->Prev
) {
1276 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1277 field
->Data
->getName().list_extension
) {
1278 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1280 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1284 if(field
->Data
->enumeration
.modified
){
1285 Mstring path
= empty_string
;
1286 if(field
->Data
->getMinOccurs() != 1 && field
->Data
->getMaxOccurs() != 1){
1287 path
= field
->Data
->actualPath
+ Mstring("[-]");
1289 path
= field
->Data
->actualPath
;
1291 for(List
<Mstring
>::iterator var
= field
->Data
->enumeration
.variants
.end(); var
; var
= var
->Prev
){
1292 if(var
->Data
.empty()) continue;
1293 container
.push_back("variant (" + path
+ ") " + var
->Data
+ ";\n");
1297 field
->Data
->collectVariants(container
);
1301 void ComplexType::printVariant(FILE * file
) {
1306 bool foundAtLeastOneVariant
= false;
1307 bool foundAtLeastOneHiddenVariant
= false;
1309 if (!variant
.empty()) {
1310 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1311 if (foundAtLeastOneVariant
&& foundAtLeastOneHiddenVariant
) {
1314 if (var
->Data
[0] != '/') {
1315 foundAtLeastOneVariant
= true;
1317 foundAtLeastOneHiddenVariant
= true;
1322 if (!foundAtLeastOneVariant
&& !foundAtLeastOneHiddenVariant
) {
1326 if (!foundAtLeastOneVariant
) {
1327 //No other variants, only commented, so the 'with' must be commented also.
1328 fprintf(file
, ";\n//with {\n");
1330 fprintf(file
, "\nwith {\n");
1333 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1334 fprintf(file
, " %s", var
->Data
.c_str());
1337 if (!foundAtLeastOneVariant
) {
1338 fprintf(file
, "//");
1343 void ComplexType::dump(unsigned int depth
) const {
1344 fprintf(stderr
, "%*s %sComplexType at %p | Top:%s\n", depth
* 2, "", isVisible() ? "" : "(hidden)", (const void*) this, top
? "true" : "false");
1345 if (parent
!= NULL
) {
1346 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %i | my xsdtype: %i\n", depth
* 2, "", (const void*) parent
, parent
->getXsdtype(), xsdtype
);
1348 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %s | my xsdtype: %i\n", depth
* 2, "", "NULL", "NULL", xsdtype
);
1350 fprintf(stderr
, "%*s name='%s' -> '%s', type='%s' %d complexfields | %s | %s | %s\n", depth
* 2, "",
1351 name
.originalValueWoPrefix
.c_str(), name
.convertedValue
.c_str(), type
.convertedValue
.c_str(), (int) complexfields
.size(),
1352 outside_reference
.empty() ? "" : outside_reference
.get_val().c_str(), mode
== restrictionMode
? "restriction" : "",
1353 mode
== extensionMode
? "extension" : "");
1354 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1355 field
->Data
->dump(depth
+ 1);
1357 fprintf(stderr
, "%*s %d attribields\n", depth
* 2, "", (int) attribfields
.size());
1358 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1359 field
->Data
->dump(depth
+ 1);
1361 fprintf(stderr
, "%*s %d enumfields\n", depth
* 2, "", (int) enumfields
.size());
1362 for (List
<Mstring
>::iterator field
= enumfields
.begin(); field
; field
= field
->Next
) {
1363 fprintf(stderr
, "%*s enum: %s\n", depth
* 2 + depth
, "", field
->Data
.c_str());
1365 fprintf(stderr
, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth
+ 1) * 2, "", minOccurs
, maxOccurs
, isOptional
? "true" : "false", name
.list_extension
? "true" : "false");
1366 fprintf(stderr
, "%*s %d variants: ", (depth
+ 1) * 2, "", (int) variant
.size());
1367 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1368 fprintf(stderr
, "%s, ", var
->Data
.c_str());
1370 fprintf(stderr
, "%*s pattern:%s | length:%i \n ", (depth
+ 1) * 2, "", this->pattern
.facet
.c_str(), (int) (this->length
.facet_maxLength
));
1371 fprintf(stderr
, "%*s enum: %i \n", (depth
+ 1)*2, "", (int) this->enumeration
.facets
.size());
1372 fprintf(stderr
, "\n");
1375 void ComplexType::setMinMaxOccurs(const unsigned long long min
, const unsigned long long max
, const bool generate_list_postfix
) {
1377 if (min
!= 1 || max
!= 1) {
1378 if (xsdtype
== n_choice
) {
1381 addVariant(V_untagged
);
1382 first_child
= false;
1383 } else if (xsdtype
== n_sequence
) {
1384 ComplexType
* rec
= new ComplexType(this);
1385 rec
->type
.upload(Mstring("record"));
1386 rec
->name
.upload(Mstring("sequence"));
1387 rec
->setXsdtype(n_sequence
);
1388 rec
->addVariant(V_untagged
);
1389 rec
->addVariant(V_untagged
);
1390 rec
->minOccurs
= min
;
1391 rec
->maxOccurs
= max
;
1392 complexfields
.push_back(rec
);
1394 if ((rec
->minOccurs
== 0 && rec
->maxOccurs
> 1) || rec
->minOccurs
> 0) {
1395 rec
->name
.list_extension
= true;
1400 if ((minOccurs
== 0 && maxOccurs
> 1) || minOccurs
> 0) {
1401 if (generate_list_postfix
) {
1402 name
.list_extension
= true;
1405 if (parent
!= NULL
&& parent
->getXsdtype() == n_choice
) {
1406 name
.list_extension
= true;
1407 if ((parent
!= NULL
&& parent
->getXsdtype() == n_choice
)) {
1408 if (parent
->first_child
== false && minOccurs
== 0) {
1409 parent
->first_child
= true;
1411 first_child
= false;
1421 if (maxOccurs
> 1 && generate_list_postfix
) {
1422 name
.list_extension
= true;
1426 void ComplexType::applyNamespaceAttribute(VariantMode varLabel
, const Mstring
& ns_list
) {
1427 List
<Mstring
> namespaces
;
1428 if (!ns_list
.empty()) {
1429 expstring_t valueToSplitIntoTokens
= mcopystr(ns_list
.c_str());
1431 token
= strtok(valueToSplitIntoTokens
, " ");
1432 while (token
!= NULL
) {
1433 namespaces
.push_back(Mstring(token
));
1434 token
= strtok(NULL
, " ");
1436 Free(valueToSplitIntoTokens
);
1441 // Note: libxml2 will verify the namespace list according to the schema
1442 // of XML Schema. It is either ##any, ##other, ##local, ##targetNamespace,
1443 // or a list of (namespace reference | ##local | ##targetNamespace).
1444 for (List
<Mstring
>::iterator ns
= namespaces
.begin(); ns
; ns
= ns
->Next
) {
1445 static const Mstring
xxany("##any"), xxother("##other"), xxlocal("##local"),
1446 xxtargetNamespace("##targetNamespace");
1447 if (!first
) any_ns
+= ',';
1449 if (ns
->Data
== xxany
) {
1450 }// this must be the only element, nothing to add
1451 else if (ns
->Data
== xxother
) { // this must be the only element
1452 any_ns
+= " except unqualified";
1453 if (module
->getTargetNamespace() != "NoTargetNamespace") {
1455 any_ns
+= parent
->getModule()->getTargetNamespace();
1458 }// The three cases below can happen multiple times
1460 if (first
) any_ns
+= " from ";
1461 // else a comma was already added
1462 if (ns
->Data
== xxtargetNamespace
) {
1464 any_ns
+= parent
->getModule()->getTargetNamespace();
1466 } else if (ns
->Data
== xxlocal
) {
1467 any_ns
+= "unqualified";
1478 addVariant(varLabel
, any_ns
, true);
1481 void ComplexType::addComment(const Mstring
& text
) {
1482 if (this == actfield
) {
1483 if (lastType
== n_attribute
) { // ez nem teljesen jo, stb, tobb lehetoseg, es rossy sorrend
1484 if (!attribfields
.empty()) {
1485 attribfields
.back()->addComment(text
);
1488 if (actfield
->getName().convertedValue
== Mstring("base") && parent
!= NULL
) {
1489 parent
->getComment().push_back(Mstring("/* " + text
+ " */\n"));
1491 comment
.push_back(Mstring("/* " + text
+ " */\n"));
1495 actfield
->addComment(text
);
1500 //Attribute extension logic when extending complextypes
1501 void ComplexType::applyAttributeExtension(ComplexType
* found_CT
, AttributeType
* anyAttrib
/* = NULL */) {
1502 for (List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1504 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1505 anyAttrib
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1508 for (List
<AttributeType
*>::iterator attr2
= attribfields
.begin(); attr2
; attr2
= attr2
->Next
) {
1509 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1510 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
) {
1511 if (attr
->Data
->getUseVal() == optional
) {
1512 attr2
->Data
->setUseVal(optional
);
1520 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1521 attribfields
.push_back(newAttrib
);
1522 setParent(this, newAttrib
);
1527 //Attribute restriction logic when restricting complextypes
1528 void ComplexType::applyAttributeRestriction(ComplexType
* found_CT
) {
1529 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(), nextAttr
; attr
; attr
= nextAttr
) {
1530 nextAttr
= attr
->Next
;
1532 for (List
<AttributeType
*>::iterator attr2
= found_CT
->attribfields
.begin(); attr2
; attr2
= attr2
->Next
) {
1533 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1534 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
) {
1542 attribfields
.remove(attr
);
1545 size_t size
= found_CT
->attribfields
.size();
1546 size_t size2
= attribfields
.size();
1548 List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin();
1549 for (; i
< size
; attr
= attr
->Next
, i
= i
+ 1) {
1552 List
<AttributeType
*>::iterator attr2
= attribfields
.begin();
1553 for (; j
< size2
; attr2
= attr2
->Next
, j
= j
+ 1) {
1554 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1555 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
&& !attr2
->Data
->getUsed()) {
1557 attr2
->Data
->setUsed(true);
1562 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1563 attribfields
.push_back(newAttrib
);
1564 setParent(this, newAttrib
);
1569 void ComplexType::addNameSpaceAsVariant(RootType
* root
, RootType
* other
) {
1570 if (other
->getModule()->getTargetNamespace() != root
->getModule()->getTargetNamespace() &&
1571 other
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1572 root
->addVariant(V_namespaceAs
, other
->getModule()->getTargetNamespace());
1576 void ComplexType::resolveAttribute(AttributeType
* attr
) {
1577 if (attr
->getXsdtype() == n_attribute
&& !attr
->getReference().empty()) {
1578 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(attr
, want_BOTH
);
1580 if (attr
->isFromRef()) {
1581 addNameSpaceAsVariant(attr
, st
);
1582 attr
->setTypeOfField(st
->getName().convertedValue
);
1583 attr
->setNameOfField(st
->getName().originalValueWoPrefix
);
1584 attr
->setOrigModule(st
->getModule());
1586 attr
->setTypeOfField(st
->getName().convertedValue
);
1587 if (st
->getType().convertedValue
== "record" || st
->getType().convertedValue
== "union") {
1588 st
->addToNameDepList(attr
);
1592 printError(module
->getSchemaname(), name
.convertedValue
,
1593 "Reference for a non-defined type: " + attr
->getReference().repr());
1594 TTCN3ModuleInventory::getInstance().incrNumErrors();
1599 void ComplexType::resolveAttributeGroup(SimpleType
* st
) {
1600 if (xsdtype
== n_attributeGroup
&& !outside_reference
.empty()) {
1601 ComplexType
* ct
= (ComplexType
*) st
;
1602 if(ct
->resolved
== No
){
1603 ct
->referenceResolving();
1605 outside_reference
.set_resolved(ct
);
1607 bool addNameSpaceas
= false;
1608 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1609 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1610 addNameSpaceas
= true;
1613 if(parent
->nillable
&& parent
->parent
!= NULL
){
1614 par
= parent
->parent
;
1618 List
<AttributeType
*>::iterator anyAttrib
= par
->attribfields
.begin();
1619 for (; anyAttrib
; anyAttrib
= anyAttrib
->Next
) {
1620 if (anyAttrib
->Data
->isAnyAttribute()) {
1624 for (List
<AttributeType
*>::iterator attr
= ct
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1625 AttributeType
* attrib
= new AttributeType(*attr
->Data
);
1626 attr
->Data
->setOrigModule(ct
->getModule());
1627 if (addNameSpaceas
) {
1628 attrib
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1630 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1631 anyAttrib
->Data
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1633 //Nillable attribute placement is hard...
1634 if (parent
->nillable
&& parent
->parent
!= NULL
) {
1635 parent
->parent
->attribfields
.push_back(attrib
);
1636 attrib
->parent
= parent
->parent
;
1637 setParent(parent
->parent
, attrib
);
1638 } else if (parent
->nillable
&& !parent
->complexfields
.empty()) {
1639 parent
->complexfields
.back()->attribfields
.push_back(attrib
);
1640 attrib
->parent
= parent
->complexfields
.back();
1641 } else if (parent
->parent
!= NULL
&& (parent
->parent
->mode
== extensionMode
|| parent
->parent
->mode
== restrictionMode
)) {
1642 parent
->parent
->attribfields
.push_back(attrib
);
1643 setParent(parent
->parent
, attrib
);
1645 parent
->attribfields
.push_back(attrib
);
1646 setParent(parent
, attrib
);
1653 void ComplexType::resolveGroup(SimpleType
*st
) {
1654 if (xsdtype
== n_group
&& !outside_reference
.empty()) {
1655 ComplexType
* ct
= (ComplexType
*) st
;
1656 outside_reference
.set_resolved(ct
);
1658 if(ct
->resolved
== No
){
1659 ct
->referenceResolving();
1661 //Decide if namespaceas variant needs to be added
1662 bool addNameSpaceas
= false;
1663 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1664 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1665 addNameSpaceas
= true;
1667 if (ct
->getXsdtype() == n_sequence
&& minOccurs
== 1 && maxOccurs
== 1 && (parent
->getXsdtype() == n_complexType
|| parent
->getXsdtype() == n_sequence
)) {
1668 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1669 ComplexType
* newField
= new ComplexType(*c
->Data
);
1670 parent
->complexfields
.push_back(newField
);
1671 setParent(parent
, newField
);
1672 parent
->complexfields
.back()->setModule(getModule());
1673 if (addNameSpaceas
) {
1674 parent
->complexfields
.back()->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1677 } else if (ct
->getXsdtype() == n_all
) {
1678 //If the parent optional, then every field is optional
1679 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1680 ComplexType
* f
= new ComplexType(*c
->Data
);
1681 if (minOccurs
== 0 && !f
->enumerated
) {
1682 f
->isOptional
= true;
1684 ((ComplexType
*) parent
)->complexfields
.push_back(f
);
1685 setParent(parent
, f
);
1686 f
->setModule(getModule());
1687 if (addNameSpaceas
) {
1688 f
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1691 parent
->addVariant(V_useOrder
);
1693 if (name
.list_extension
) {
1694 addVariant(V_untagged
);
1696 type
.upload(ct
->getName().convertedValue
);
1697 name
.upload(ct
->getName().convertedValue
);
1698 ct
->addToNameDepList(this);
1701 if (addNameSpaceas
) {
1702 addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1708 void ComplexType::resolveElement(SimpleType
*st
) {
1709 if (xsdtype
== n_element
&& !outside_reference
.empty()) {
1710 outside_reference
.set_resolved(st
);
1711 type
.upload(st
->getModule()->getTargetNamespaceConnector() + Mstring(":") + st
->getName().convertedValue
);
1712 if (name
.originalValueWoPrefix
.empty()) {
1713 name
.upload(st
->getName().convertedValue
);
1716 addNameSpaceAsVariant(this, st
);
1719 collectElementTypes(st
, NULL
);
1721 //Namedep is added to the substitutions, if any
1722 if(st
->getSubstitution() != NULL
){
1723 st
->getSubstitution()->addToNameDepList(this);
1724 nameDep
= st
->getSubstitution();
1725 }if(st
->getTypeSubstitution() != NULL
){
1726 st
->getTypeSubstitution()->addToNameDepList(this);
1727 nameDep
= st
->getTypeSubstitution();
1729 st
->addToNameDepList(this);
1735 void ComplexType::resolveSimpleTypeExtension() {
1736 if (mode
== extensionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1737 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1739 if (st
->getXsdtype() != n_NOTSET
&& ((ComplexType
*) st
)->basefield
!= NULL
) { // if the xsdtype != simpletype
1740 ComplexType
* ct
= (ComplexType
*) st
;
1741 if (ct
->resolved
== No
) {
1742 ct
->referenceResolving();
1744 basefield
->outside_reference
.set_resolved(ct
);
1745 ct
->basefield
->addToNameDepList(basefield
);
1746 basefield
->nameDep
= ct
->basefield
;
1747 basefield
->mode
= extensionMode
;
1748 basefield
->applyReference(*ct
->basefield
, true);
1749 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1750 applyAttributeExtension(ct
);
1752 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1753 st
->referenceResolving();
1755 st
->addToNameDepList(basefield
);
1756 basefield
->nameDep
= st
;
1757 addNameSpaceAsVariant(basefield
, st
);
1759 } else if(!isBuiltInType(basefield
->getType().convertedValue
)){
1760 printError(module
->getSchemaname(), name
.convertedValue
,
1761 "Reference for a non-defined type: " + basefield
->getReference().repr());
1762 TTCN3ModuleInventory::getInstance().incrNumErrors();
1769 void ComplexType::resolveSimpleTypeRestriction() {
1770 if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
&& !basefield
->outside_reference
.empty()) {
1771 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1773 printError(module
->getSchemaname(), name
.convertedValue
,
1774 "Reference for a non-defined type: " + basefield
->getReference().repr());
1775 TTCN3ModuleInventory::getInstance().incrNumErrors();
1778 basefield
->outside_reference
.set_resolved(st
);
1779 if (st
->getXsdtype() != n_NOTSET
) {
1780 ComplexType
* ct
= (ComplexType
*) st
;
1781 if (ct
->resolved
== No
) {
1782 ct
->referenceResolving();
1784 applyAttributeRestriction(ct
);
1785 basefield
->mode
= restrictionMode
;
1786 if (ct
->cmode
== CT_complextype_mode
) {
1787 applyReference(*ct
, true);
1788 type
.upload(ct
->getName().convertedValue
);
1789 basefield
->setInvisible();
1790 } else if (ct
->basefield
!= NULL
) {
1791 basefield
->applyReference(*ct
->basefield
);
1792 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1793 } else if (ct
->basefield
== NULL
) {
1794 basefield
->applyReference(*ct
);
1795 addNameSpaceAsVariant(basefield
, ct
);
1798 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1799 st
->referenceResolving();
1801 if(xsdtype
== n_simpleContent
){
1802 basefield
->applyReference(*st
, true);
1803 addNameSpaceAsVariant(basefield
, st
);
1804 basefield
->mode
= restrictionMode
;
1805 }else if(xsdtype
== n_simpleType
){
1806 basefield
->setInvisible();
1807 applyReference(*basefield
, true);
1808 applyReference(*st
, true);
1809 addNameSpaceAsVariant(this, st
);
1810 basefield
->mode
= restrictionMode
;
1813 } else if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1814 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_CT
);
1815 if (ct
== NULL
&& !isBuiltInType(basefield
->getType().convertedValue
)) {
1816 printError(module
->getSchemaname(), name
.convertedValue
,
1817 "Reference for a non-defined type: " + basefield
->getReference().repr());
1818 TTCN3ModuleInventory::getInstance().incrNumErrors();
1822 basefield
->outside_reference
.set_resolved(ct
);
1824 if (ct
->resolved
== No
) {
1825 ct
->referenceResolving();
1827 for (List
<AttributeType
*>::iterator f
= ct
->attribfields
.begin(); f
; f
= f
->Next
) {
1828 AttributeType
* attr
= new AttributeType(*f
->Data
);
1829 attribfields
.push_back(attr
);
1830 setParent(this, attr
);
1832 addNameSpaceAsVariant(this, ct
);
1834 if(!basefield
->parent
->top
){
1835 applyReference(*basefield
, true);
1836 basefield
->setInvisible();
1841 void ComplexType::resolveComplexTypeExtension() {
1842 if (mode
== extensionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1843 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1845 printError(module
->getSchemaname(), name
.convertedValue
,
1846 "Reference for a non-defined type: " + getReference().repr());
1847 TTCN3ModuleInventory::getInstance().incrNumErrors();
1850 if(ct
->getXsdtype() != n_NOTSET
){
1851 outside_reference
.set_resolved(ct
);
1852 if (ct
->resolved
== No
) {
1853 ct
->referenceResolving();
1855 List
<AttributeType
*>::iterator anyAttr
= attribfields
.begin();
1856 for (; anyAttr
; anyAttr
= anyAttr
->Next
) {
1857 if (anyAttr
->Data
->isAnyAttribute()) {
1862 if (anyAttr
!= NULL
) {
1863 applyAttributeExtension(ct
, anyAttr
->Data
);
1865 applyAttributeExtension(ct
);
1868 if (ct
->getName().convertedValue
== outside_reference
.get_val() && ct
->getModule()->getTargetNamespace() == outside_reference
.get_uri()) {
1870 outside_reference
.set_resolved(ct
);
1871 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1872 if (f
->Data
!= this) { //not a self recursive field
1873 ComplexType
* newField
= new ComplexType(*f
->Data
);
1874 complexfields
.push_front(newField
);
1875 setParent(this, newField
);
1877 //Self recursive field
1878 ComplexType
* field
= new ComplexType(this);
1879 field
->name
.upload(f
->Data
->getName().convertedValue
);
1880 field
->applyReference(*f
->Data
);
1881 field
->type
.upload(ct
->getName().convertedValue
+ Mstring(".") + f
->Data
->getName().convertedValue
);
1882 field
->type
.no_replace
= true;
1883 field
->minOccurs
= f
->Data
->minOccurs
;
1884 field
->maxOccurs
= f
->Data
->maxOccurs
;
1885 complexfields
.push_front(field
);
1886 setParent(this, field
);
1891 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1892 ComplexType
* newField
= new ComplexType(*f
->Data
);
1893 complexfields
.push_front(newField
);
1894 setParent(this, newField
);
1901 void ComplexType::resolveComplexTypeRestriction() {
1902 if (mode
== restrictionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1903 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1904 if(ct
->getXsdtype() != n_NOTSET
){
1905 if (ct
->resolved
== No
) {
1906 ct
->referenceResolving();
1908 outside_reference
.set_resolved(ct
);
1909 applyAttributeRestriction(ct
);
1911 size_t size
= complexfields
.size();
1913 List
<ComplexType
*>::iterator field
= complexfields
.begin();
1914 for (; i
< size
; field
= field
->Next
, i
= i
+ 1){
1915 List
<ComplexType
*>::iterator field2
= ct
->complexfields
.begin();
1916 for (; field2
; field2
= field2
->Next
) {
1917 if (field
->Data
->getName().convertedValue
== field2
->Data
->getName().convertedValue
&&
1918 field
->Data
->getType().convertedValue
== field2
->Data
->getType().convertedValue
) {
1919 field
->Data
->applyReference(*field2
->Data
, false);
1924 field
->Data
->setInvisible();
1931 void ComplexType::resolveUnion(SimpleType
*st
) {
1932 if (parent
!= NULL
&& parent
->with_union
&& xsdtype
== n_simpleType
&& !outside_reference
.empty()) {
1933 if (st
->getXsdtype() != n_NOTSET
) {
1934 ComplexType
* ct
= (ComplexType
*) st
;
1935 outside_reference
.set_resolved(ct
);
1936 for (List
<ComplexType
*>::iterator field
= ct
->complexfields
.begin(); field
; field
= field
->Next
) {
1937 ComplexType
* newField
= new ComplexType(*field
->Data
);
1938 parent
->complexfields
.push_back(newField
);
1939 setParent(parent
, newField
);
1946 void ComplexType::modifyAttributeParent() {
1947 if (nillable_field
!= NULL
) {
1948 ((ComplexType
*) nillable_field
)->actfield
= nillable_field
;
1954 //Element substitution
1955 void ComplexType::addSubstitution(SimpleType
* st
){
1956 ComplexType
* element
;
1957 if(st
->getXsdtype() == n_NOTSET
|| !complexfields
.empty()){
1958 element
= new ComplexType(*st
, fromTagSubstitution
);
1960 element
= new ComplexType(*(ComplexType
*)st
);
1961 element
->variant
.clear();
1963 element
->subsGroup
= this;
1964 element
->parent
= this;
1965 if(complexfields
.empty()){ //The first element(head) is the st
1966 element
->setTypeValue(st
->getType().convertedValue
);
1967 if(st
->hasVariant(Mstring("\"abstract\""))){
1968 element
->addVariant(V_abstract
);
1970 if(st
->getReference().get_ref() != NULL
){
1971 ((SimpleType
*)st
->getReference().get_ref())->addToNameDepList(element
);
1972 nameDep
= ((SimpleType
*)st
->getReference().get_ref());
1974 module
->addElementType(element
->getType().convertedValue
, element
);
1975 element
->addVariant(V_formAs
, Mstring("qualified"));
1978 if(st
->getType().convertedValue
== "anyType"){
1979 newType
= complexfields
.front()->getType().convertedValue
;
1981 newType
= st
->getName().convertedValue
;
1982 st
->addToNameDepList(element
);
1983 element
->nameDep
= st
;
1985 element
->setTypeValue(newType
);
1986 BlockValue front_block
= complexfields
.front()->getBlock();
1987 if(front_block
== all
|| front_block
== substitution
){
1988 element
->addVariant(V_block
);
1989 }else if(front_block
== restriction
|| front_block
== extension
){
1990 const Mstring
& head_type
= complexfields
.front()->getType().convertedValue
.getValueWithoutPrefix(':');
1991 //To decide if they came from a common ancestor
1992 Mstring elem_type
= findRoot(front_block
, st
, head_type
, true);
1993 if(head_type
== elem_type
){
1994 element
->addVariant(V_block
);
1999 element
->setNameValue(st
->getName().convertedValue
);
2000 element
->top
= false;
2001 complexfields
.push_back(element
);
2004 void ComplexType::addTypeSubstitution(SimpleType
* st
){
2005 ComplexType
* element
;
2006 if(st
->getXsdtype() == n_NOTSET
|| !complexfields
.empty()){
2007 element
= new ComplexType(*st
, fromTypeSubstitution
);
2009 //Only need a plain complextype
2011 element
= new ComplexType(this);
2012 //Just the block needed from st
2013 element
->block
= st
->getBlock();
2015 st
->addToNameDepList(element
);
2016 element
->nameDep
= st
;
2017 element
->typeSubsGroup
= this;
2018 element
->parent
= this;
2019 if(complexfields
.empty()){ //The first element(head) is the st
2020 if(st
->hasVariant(Mstring("\"abstract\""))){
2021 element
->addVariant(V_abstract
);
2024 BlockValue front_block
= complexfields
.front()->getBlock();
2025 if(front_block
== all
){
2026 element
->addVariant(V_block
);
2027 }else if(front_block
== restriction
|| front_block
== extension
){
2028 const Mstring
& head_type
= complexfields
.front()->getType().convertedValue
.getValueWithoutPrefix(':');
2029 //To decide if they came from a common ancestor
2030 Mstring elem_type
= findRoot(front_block
, st
, head_type
, true);
2031 if(head_type
== elem_type
){
2032 element
->addVariant(V_block
);
2036 //Cascading to parent type substitution
2037 if(parentTypeSubsGroup
!= NULL
&& !complexfields
.empty()){
2038 parentTypeSubsGroup
->addTypeSubstitution(st
);
2040 element
->top
= false;
2041 complexfields
.push_back(element
);
2042 element
->setTypeValue(st
->getName().convertedValue
.getValueWithoutPrefix(':'));
2043 element
->setNameValue(st
->getName().convertedValue
.getValueWithoutPrefix(':'));
2046 Mstring
ComplexType::findRoot(const BlockValue block_value
, SimpleType
* elem
, const Mstring
& head_type
, const bool first
){
2047 const Mstring elemName
= elem
->getName().convertedValue
.getValueWithoutPrefix(':');
2048 const Mstring elemType
= elem
->getType().convertedValue
.getValueWithoutPrefix(':');
2050 if(!first
&& !isFromRef() && elemType
== head_type
){
2052 }else if((isFromRef() &&
2053 ((elem
->getMode() == restrictionMode
&& block_value
== restriction
) ||
2054 (elem
->getMode() == extensionMode
&& block_value
== extension
))) && elemType
== head_type
){
2056 }else if(!first
&& elemName
== head_type
){
2059 SimpleType
* st
= NULL
;
2060 if((elem
->getMode() == restrictionMode
&& block_value
== restriction
) ||
2061 (elem
->getMode() == extensionMode
&& block_value
== extension
)){
2062 if(!elem
->getReference().is_resolved()){
2063 elem
->referenceResolving();
2065 if(elem
->getXsdtype() != n_NOTSET
){
2066 ComplexType
* ct
= (ComplexType
*)elem
;
2067 if(ct
->basefield
!= NULL
&& ct
->basefield
->getType().convertedValue
.getValueWithoutPrefix(':') == head_type
){
2069 }else if(ct
->basefield
!= NULL
){
2070 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(ct
->basefield
, want_BOTH
);
2074 st
= (SimpleType
*)(elem
->getReference().get_ref());
2076 }else if(elem
->getMode() == noMode
&& (block_value
== restriction
|| block_value
== extension
)){
2077 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(this, elem
->getType().convertedValue
, want_BOTH
);
2079 if(st
!= NULL
&& elem
!= st
){
2080 return findRoot(block_value
, st
, head_type
, false);
2083 if(elem
->getMode() == noMode
&& !first
){
2086 return empty_string
;