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
!= fromTagSubstition
){
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 fromTagSubstition
:
163 type
.upload(Mstring("union"));
164 name
.upload(getName().originalValueWoPrefix
+ Mstring("_group"));
168 enumeration
.modified
= false;
169 value
.modified
= false;
170 pattern
.modified
= false;
171 length
.modified
= false;
172 whitespace
.modified
= false;
177 ComplexType::~ComplexType() {
178 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
182 complexfields
.clear();
184 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
188 attribfields
.clear();
191 void ComplexType::loadWithValues() {
192 //Find the last field where the tag is found
193 if (this != actfield
) {
194 actfield
->loadWithValues();
198 const XMLParser::TagAttributes
& atts
= parser
->getActualTagAttributes();
200 switch (parser
->getActualTagName()) {
202 if (!top
&& xsdtype
!= n_sequence
&& xsdtype
!= n_complexType
&& xsdtype
!= n_extension
&& xsdtype
!= n_restriction
&& xsdtype
!= n_element
) {
204 ComplexType
* rec
= new ComplexType(this);
205 rec
->type
.upload(Mstring("record"));
206 rec
->name
.upload(Mstring("sequence"));
207 rec
->addVariant(V_untagged
);
208 rec
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
209 rec
->setXsdtype(n_sequence
);
210 complexfields
.push_back(rec
);
213 //Do not create new record, it is an embedded sequence
214 if (xsdtype
== n_sequence
&& atts
.minOccurs
== 1 && atts
.maxOccurs
== 1) {
217 type
.upload(Mstring("record"));
218 xsdtype
= n_sequence
;
219 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
223 if (!top
|| xsdtype
!= n_group
) {
224 //Create new union field
225 ComplexType
* choice
= new ComplexType(this);
226 choice
->type
.upload(Mstring("union"));
227 choice
->name
.upload(Mstring("choice"));
228 choice
->setXsdtype(n_choice
);
229 choice
->addVariant(V_untagged
);
230 choice
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
232 complexfields
.push_back(choice
);
235 type
.upload(Mstring("union"));
240 //Create the record of enumerated field
242 ComplexType
* enumField
= new ComplexType(this);
243 enumField
->setTypeValue(Mstring("enumerated"));
244 enumField
->setNameValue(Mstring("order"));
245 enumField
->setBuiltInBase(Mstring("string"));
246 enumField
->enumerated
= true;
247 enumField
->setMinMaxOccurs(0, ULLONG_MAX
, false);
248 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
249 addVariant(V_useOrder
);
250 complexfields
.push_back(enumField
);
251 if (atts
.minOccurs
== 0) {
257 mode
= restrictionMode
;
258 //If it is an xsd:union then call SimpleType::loadWithValues
259 if (parent
!= NULL
&& parent
->with_union
) {
260 SimpleType::loadWithValues();
263 if (cmode
== CT_simpletype_mode
) {
264 //if it is from a SimpleType, then create a base field
265 ComplexType
* f
= new ComplexType(this);
266 f
->name
.upload(Mstring("base"));
267 f
->type
.upload(atts
.base
);
268 f
->setReference(atts
.base
);
269 f
->addVariant(V_untagged
);
270 complexfields
.push_back(f
);
273 } else if (cmode
== CT_complextype_mode
) {
274 setReference(atts
.base
);
275 xsdtype
= n_restriction
;
279 mode
= extensionMode
;
280 if (cmode
== CT_simpletype_mode
) {
281 //if it is from a SimpleType, then create a base field
282 ComplexType
* f
= new ComplexType(this);
283 f
->name
.upload(Mstring("base"));
284 f
->type
.upload(atts
.base
);
285 f
->setReference(atts
.base
);
286 f
->addVariant(V_untagged
);
287 complexfields
.push_back(f
);
290 } else if (cmode
== CT_complextype_mode
) {
291 setReference(atts
.base
);
292 xsdtype
= n_extension
;
298 if(cmode
== CT_simpletype_mode
){
299 //If a simple top level element is nillable
300 ComplexType
* nilrec
= new ComplexType(this);
301 if (atts
.type
.empty()) {
302 nilrec
->type
.upload(Mstring("record"));
304 nilrec
->type
.upload(atts
.type
);
306 nilrec
->name
.upload(Mstring("content"));
307 nilrec
->isOptional
= true;
308 nilrec
->nillable
= true;
309 setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
310 complexfields
.push_back(nilrec
);
311 type
.upload(Mstring("record"));
312 name
.upload(atts
.name
);
314 nillable_field
= nilrec
;
316 //From a complexType element is nillable
317 ComplexType
* record
= new ComplexType(this);
318 ComplexType
* nilrec
= new ComplexType(record
);
319 if (atts
.type
.empty()) {
320 nilrec
->type
.upload(Mstring("record"));
322 nilrec
->type
.upload(atts
.type
);
324 record
->name
.upload(atts
.name
);
325 record
->type
.upload(Mstring("record"));
326 record
->complexfields
.push_back(nilrec
);
327 record
->addVariant(V_useNil
);
328 record
->nillable_field
= nilrec
;
329 record
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
331 nilrec
->name
.upload(Mstring("content"));
332 nilrec
->nillable
= true;
333 nilrec
->isOptional
= true;
334 nilrec
->tagNames
.push_back(parser
->getActualTagName());
335 complexfields
.push_back(record
);
339 //It is a simple element
340 ComplexType
* c
= new ComplexType(this);
341 c
->setXsdtype(n_element
);
342 c
->type
.upload(atts
.type
);
343 c
->name
.upload(atts
.name
);
344 c
->setReference(atts
.type
);
345 c
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
346 c
->applyDefaultAttribute(atts
.default_
);
347 c
->applyFixedAttribute(atts
.fixed
);
348 c
->setElementFormAs(atts
.form
);
349 if (atts
.ref
.empty()) {
350 c
->setReference(atts
.type
);
352 c
->applyRefAttribute(atts
.ref
);
353 c
->name
.upload(atts
.ref
.getValueWithoutPrefix(':'));
354 c
->type
.upload(atts
.ref
);
356 c
->applySubstitionGroupAttribute(atts
.substitionGroup
);
357 c
->applyBlockAttribute(atts
.block
);
360 //Inside all have some special conditions
361 if (xsdtype
== n_all
) {
362 if (atts
.minOccurs
> 1) {
363 printError(getModule()->getSchemaname(), name
.convertedValue
,
364 Mstring("Inside <all>, minOccurs must be 0 or 1"));
365 TTCN3ModuleInventory::incrNumErrors();
367 if (atts
.maxOccurs
!= 1) {
368 printError(getModule()->getSchemaname(), name
.convertedValue
,
369 Mstring("Inside <all>, maxOccurs must be 1"));
370 TTCN3ModuleInventory::incrNumErrors();
373 complexfields
.push_back(c
);
375 c
->isOptional
= true;
378 complexfields
.push_back(c
);
385 AttributeType
* attribute
= new AttributeType(this);
386 attribute
->addVariant(V_attribute
);
387 attribute
->applyMinMaxOccursAttribute(0, 1);
388 attribute
->setXsdtype(n_attribute
);
389 attribute
->applyDefaultAttribute(atts
.default_
);
390 attribute
->applyFixedAttribute(atts
.fixed
);
391 attribute
->setUseVal(atts
.use
);
392 attribute
->setAttributeFormAs(atts
.form
);
393 lastType
= n_attribute
;
394 if (atts
.ref
.empty()) {
395 attribute
->setNameOfField(atts
.name
);
396 attribute
->setTypeOfField(atts
.type
);
397 attribute
->setReference(atts
.type
, true);
399 attribute
->applyRefAttribute(atts
.ref
);
401 actfield
= attribute
;
403 //In case of nillable parent it is difficult...
404 if (nillable
&& parent
!= NULL
) {
405 parent
->attribfields
.push_back(attribute
);
406 attribute
->parent
= parent
;
407 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
408 complexfields
.back()->attribfields
.push_back(attribute
);
409 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
410 parent
->attribfields
.push_back(attribute
);
411 attribute
->parent
= parent
;
413 attribfields
.push_back(attribute
);
419 ComplexType
* any
= new ComplexType(this);
420 any
->name
.upload(Mstring("elem"));
421 any
->type
.upload(Mstring("xsd:string"));
422 any
->applyNamespaceAttribute(V_anyElement
, atts
.namespace_
);
423 any
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
424 any
->setXsdtype(n_any
);
425 complexfields
.push_back(any
);
430 AttributeType
* anyattr
= new AttributeType(this);
431 anyattr
->setXsdtype(n_anyAttribute
);
432 anyattr
->setNameOfField(Mstring("attr"));
433 anyattr
->setTypeValue(Mstring("xsd:string"));
434 anyattr
->setToAnyAttribute();
435 anyattr
->applyMinMaxOccursAttribute(0, ULLONG_MAX
);
436 anyattr
->addNameSpaceAttribute(atts
.namespace_
);
439 //In case of nillable parent it is difficult...
440 if (nillable
&& parent
!= NULL
) {
441 parent
->attribfields
.push_back(anyattr
);
442 anyattr
->parent
= parent
;
443 } else if (nillable
&& !complexfields
.empty() && parent
== NULL
) {
444 complexfields
.back()->attribfields
.push_back(anyattr
);
445 } else if (parent
!= NULL
&& (parent
->mode
== extensionMode
|| parent
->mode
== restrictionMode
) && name
.convertedValue
== Mstring("base")) {
446 parent
->attribfields
.push_back(anyattr
);
447 anyattr
->parent
= parent
;
449 attribfields
.push_back(anyattr
);
453 case n_attributeGroup
:
454 if (!atts
.ref
.empty()) {
455 ComplexType
* g
= new ComplexType(this);
456 g
->setXsdtype(n_attributeGroup
);
457 g
->setReference(atts
.ref
);
458 complexfields
.push_back(g
);
461 xsdtype
= n_attributeGroup
;
462 name
.upload(Mstring(atts
.name
));
467 if (atts
.ref
.empty()) {
470 name
.upload(atts
.name
);
473 ComplexType
* group
= new ComplexType(this);
474 group
->setXsdtype(n_group
);
475 group
->name
.upload(atts
.name
);
476 group
->setReference(Mstring(atts
.ref
));
477 group
->setMinMaxOccurs(atts
.minOccurs
, atts
.maxOccurs
);
478 complexfields
.push_back(group
);
486 type
.upload(Mstring("union"));
487 addVariant(V_useUnion
);
488 if (!atts
.memberTypes
.empty()) {
490 //Get the union values
491 expstring_t valueToSplitIntoTokens
= mcopystr(atts
.memberTypes
.c_str());
493 token
= strtok(valueToSplitIntoTokens
, " ");
494 while (token
!= NULL
) {
495 types
.push_back(Mstring(token
));
496 token
= strtok(NULL
, " ");
498 Free(valueToSplitIntoTokens
);
500 //Create the union elements and push into the container
501 for (List
<Mstring
>::iterator memberType
= types
.begin(); memberType
; memberType
= memberType
->Next
) {
502 Mstring tmp_name
= memberType
->Data
.getValueWithoutPrefix(':');
503 ComplexType
* f
= new ComplexType(this);
504 f
->name
.upload(tmp_name
);
505 f
->type
.upload(memberType
->Data
);
506 f
->setXsdtype(n_simpleType
);
507 f
->setReference(memberType
->Data
);
508 complexfields
.push_back(f
);
514 case n_simpleContent
:
516 xsdtype
= parser
->getActualTagName();
517 cmode
= CT_simpletype_mode
;
521 fieldname
= Mstring("alt_");
523 fieldname
= mprintf("alt_%d", max_alt
);
526 ComplexType
* field
= new ComplexType(this);
527 field
->name
.upload(fieldname
);
528 field
->setXsdtype(n_simpleType
);
529 field
->addVariant(V_nameAs
, empty_string
, true);
530 complexfields
.push_back(field
);
536 name
.upload(atts
.name
);
537 type
.upload(Mstring("record"));
538 applyAbstractAttribute(atts
.abstract
);
539 applySubstitionGroupAttribute(atts
.substitionGroup
);
540 applyBlockAttribute(atts
.block
);
542 case n_complexContent
:
543 tagNames
.push_back(parser
->getActualTagName());
544 cmode
= CT_complextype_mode
;
546 ComplexType
* mixed
= new ComplexType(this);
547 mixed
->name
.upload(Mstring("embed_values"));
548 mixed
->type
.upload(Mstring("xsd:string"));
549 mixed
->setMinMaxOccurs(0, ULLONG_MAX
, false);
551 complexfields
.push_back(mixed
);
552 addVariant(V_embedValues
);
567 case n_fractionDigits
:
568 SimpleType::loadWithValues();
571 addComment(Mstring("LABEL:"));
574 addComment(Mstring("DEFINITION:"));
581 // called from endelementHandler
582 void ComplexType::modifyValues() {
583 if (this != actfield
) {
584 actfield
->modifyValues();
587 if (xsdtype
== n_sequence
) {
588 skipback
= skipback
- 1;
591 if ((xsdtype
== n_element
||
592 xsdtype
== n_complexType
||
593 xsdtype
== n_complexContent
||
595 xsdtype
== n_attribute
||
596 xsdtype
== n_anyAttribute
||
597 xsdtype
== n_choice
||
598 xsdtype
== n_group
||
599 xsdtype
== n_attributeGroup
||
600 xsdtype
== n_extension
||
601 xsdtype
== n_restriction
||
602 xsdtype
== n_simpleType
||
603 xsdtype
== n_simpleContent
||
604 (xsdtype
== n_sequence
&& skipback
< 0)
607 if (!tagNames
.empty() && tagNames
.back() == parser
->getParentTagName()) {
608 if (nillable
&& tagNames
.back() == n_element
) {
609 parent
->modifyValues();
612 } else if (tagNames
.empty()) {
613 parent
->actfield
= parent
;
614 parent
->lastType
= xsdtype
;
619 void ComplexType::referenceResolving() {
620 if (resolved
!= No
) return; // nothing to do
621 if(this == subsGroup
){
625 resolved
= InProgress
;
626 for (List
<ComplexType
*>::iterator ct
= complexfields
.begin(); ct
; ct
= ct
->Next
) {
627 // Referenece resolving of ComplexTypes
628 ct
->Data
->referenceResolving();
630 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
631 //Reference resolving for Attributes
632 resolveAttribute(attr
->Data
);
635 reference_resolving_funtion();
637 if(!substitionGroup
.empty()){
638 addToSubstitutions();
643 void ComplexType::reference_resolving_funtion() {
644 //Every child element references are resolved here.
645 if (outside_reference
.empty() && basefield
== NULL
) {
649 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_BOTH
);
650 if (st
== NULL
&& basefield
== NULL
) {
651 printError(module
->getSchemaname(), name
.convertedValue
,
652 "Reference for a non-defined type: " + getReference().repr());
653 TTCN3ModuleInventory::getInstance().incrNumErrors();
654 outside_reference
.set_resolved(NULL
);
658 resolveAttributeGroup(st
);
664 resolveSimpleTypeExtension();
666 resolveSimpleTypeRestriction();
668 resolveComplexTypeExtension();
670 resolveComplexTypeRestriction();
676 void ComplexType::setParent(ComplexType
* par
, SimpleType
* child
) {
680 void ComplexType::applyReference(const SimpleType
& other
, const bool on_attributes
) {
681 type
.convertedValue
= other
.getType().convertedValue
;
682 type
.originalValueWoPrefix
= other
.getType().convertedValue
;
684 if (other
.getMinOccurs() > minOccurs
|| other
.getMaxOccurs() < maxOccurs
) {
685 if (!on_attributes
) {
686 expstring_t temp
= memptystr();
689 "The occurrence range (%llu .. %llu) of the element (%s) is not compatible "
690 "with the occurrence range (%llu .. %llu) of the referenced element.",
693 name
.originalValueWoPrefix
.c_str(),
694 other
.getMinOccurs(),
695 other
.getMaxOccurs());
696 printError(module
->getSchemaname(), parent
->getName().originalValueWoPrefix
,
699 TTCN3ModuleInventory::getInstance().incrNumErrors();
702 minOccurs
= llmax(minOccurs
, other
.getMinOccurs());
703 maxOccurs
= llmin(maxOccurs
, other
.getMaxOccurs());
706 for (List
<Mstring
>::iterator var
= other
.getVariantRef().begin(); var
; var
= var
->Next
) {
708 for (List
<Mstring
>::iterator var1
= variant
.begin(); var1
; var1
= var1
->Next
) {
709 if (var
->Data
== var1
->Data
) {
715 variant
.push_back(var
->Data
);
716 variant_ref
.push_back(var
->Data
);
720 builtInBase
= other
.getBuiltInBase();
722 length
.applyReference(other
.getLength());
723 pattern
.applyReference(other
.getPattern());
724 enumeration
.applyReference(other
.getEnumeration());
725 whitespace
.applyReference(other
.getWhitespace());
726 value
.applyReference(other
.getValue());
729 void ComplexType::nameConversion(NameConversionMode conversion_mode
, const List
<NamespaceType
> & ns
) {
731 switch (conversion_mode
) {
733 nameConversion_names(ns
);
736 nameConversion_types(ns
);
739 nameConversion_fields(ns
);
744 void ComplexType::nameConversion_names(const List
<NamespaceType
> &) {
745 Mstring res
, var(module
->getTargetNamespace());
746 XSDName2TTCN3Name(name
.convertedValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_name
, res
, var
);
747 name
.convertedValue
= res
;
749 for (List
<Mstring
>::iterator vari
= variant
.begin(); vari
; vari
= vari
->Next
) {
750 if (vari
->Data
== "\"untagged\"") {
756 addVariant(V_onlyValue
, var
);
758 for (List
<SimpleType
*>::iterator dep
= nameDepList
.begin(); dep
; dep
= dep
->Next
) {
759 dep
->Data
->setTypeValue(res
);
763 void ComplexType::nameConversion_types(const List
<NamespaceType
> & ns
) {
764 attribfields
.sort(compareAttributeNameSpaces
);
765 attribfields
.sort(compareAttributeTypes
);
766 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
767 field
->Data
->nameConversion(typeMode
, ns
);
770 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
771 field
->Data
->nameConversion_types(ns
);
774 Mstring prefix
, uri
, typeValue
;
776 if (type
.convertedValue
== "record" ||
777 type
.convertedValue
== "set" ||
778 type
.convertedValue
== "union" ||
779 type
.convertedValue
== "enumerated") {
783 prefix
= type
.convertedValue
.getPrefix(':');
784 typeValue
= type
.convertedValue
.getValueWithoutPrefix(':');
786 for (List
<NamespaceType
>::iterator namesp
= ns
.begin(); namesp
; namesp
= namesp
->Next
) {
787 if (prefix
== namesp
->Data
.prefix
) {
788 uri
= namesp
->Data
.uri
;
793 QualifiedName
in(uri
, typeValue
); // ns uri + original name
795 // Check all known types
796 QualifiedNames::iterator origTN
= TTCN3ModuleInventory::getInstance().getTypenames().begin();
797 for (; origTN
; origTN
= origTN
->Next
) {
798 if (origTN
->Data
== in
) {
799 QualifiedName
tmp_name(module
->getTargetNamespace(), name
.convertedValue
);
800 if (origTN
->Data
!= tmp_name
){
806 if (origTN
!= NULL
) {
807 setTypeValue(origTN
->Data
.name
);
810 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
, type
.no_replace
);
815 void ComplexType::nameConversion_fields(const List
<NamespaceType
> & ns
) {
816 QualifiedNames used_field_names
;
818 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
819 field
->Data
->nameConversion_names(used_field_names
);
822 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
823 if (field
->Data
->getMinOccurs() == 0 && field
->Data
->getMaxOccurs() == 0) {
826 if (!field
->Data
->isVisible()) {
830 field
->Data
->nameConversion_fields(ns
);
832 Mstring prefix
= field
->Data
->getType().convertedValue
.getPrefix(':');
833 Mstring typeValue
= field
->Data
->getType().convertedValue
.getValueWithoutPrefix(':');
836 var
= getModule()->getTargetNamespace();
837 XSDName2TTCN3Name(typeValue
, TTCN3ModuleInventory::getInstance().getTypenames(), type_reference_name
, res
, var
);
839 field
->Data
->addVariant(V_onlyValue
, var
);
840 var
= getModule()->getTargetNamespace();
842 if (field
->Data
->getName().list_extension
) {
843 field
->Data
->useNameListProperty();
844 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
845 used_field_names
, field_name
, res
, var
);
846 field
->Data
->setNameValue(res
);
847 bool found_in_variant
= false;
848 for (List
<Mstring
>::iterator vari
= field
->Data
->getVariant().begin(); vari
; vari
= vari
->Next
) {
849 if (vari
->Data
== Mstring("\"untagged\"")) {
850 found_in_variant
= true;
854 if (!field
->Data
->getName().originalValueWoPrefix
.empty() &&
855 field
->Data
->getName().originalValueWoPrefix
!= "sequence" &&
856 field
->Data
->getName().originalValueWoPrefix
!= "choice" &&
857 field
->Data
->getName().originalValueWoPrefix
!= "elem" &&
859 field
->Data
->addVariant(V_nameAs
, field
->Data
->getName().originalValueWoPrefix
);
863 if (!found_in_variant
) {
864 field
->Data
->addVariant(V_untagged
, empty_string
, true);
867 XSDName2TTCN3Name(field
->Data
->getName().convertedValue
,
868 used_field_names
, field_name
, res
, var
);
869 field
->Data
->setNameValue(res
);
870 field
->Data
->addVariant(V_onlyValue
, var
);
876 void ComplexType::setFieldPaths(Mstring path
) {
879 Mstring field_prefix
= empty_string
;
880 if(parent
->minOccurs
== 0 && parent
->maxOccurs
== ULLONG_MAX
){
881 field_prefix
= "[-].";
883 path
= field_prefix
+ getName().convertedValue
;
884 actualPath
= field_prefix
+ getName().convertedValue
;
886 actualPath
= getName().convertedValue
;
888 } else if (parent
!= NULL
&& (parent
->getMinOccurs() != 1 || parent
->getMaxOccurs() != 1) &&
889 (parent
->getName().list_extension
|| parent
->mode
== listMode
)) {
890 path
= path
+ Mstring("[-].") + getName().convertedValue
;
893 path
= path
+ Mstring(".") + getName().convertedValue
;
897 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
898 field
->Data
->setFieldPaths(path
);
900 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(); attr
; attr
= attr
->Next
) {
901 attr
->Data
->setFieldPath(path
);
905 void ComplexType::finalModification2() {
906 //Call SimpleType finalModification
907 SimpleType::finalModification();
909 //Set isOptional field
910 isOptional
= isOptional
|| (minOccurs
== 0 && maxOccurs
== 1);
913 List
<Mstring
> enumNames
;
914 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
915 nextField
= field
->Next
;
916 //Remove invisible fields
917 if ((field
->Data
->minOccurs
== 0 && field
->Data
->maxOccurs
== 0) || !field
->Data
->isVisible()) {
920 complexfields
.remove(field
);
923 field
->Data
->finalModification2();
924 //collect <xsd:all> elements
925 if (field
->Data
->fromAll
) {
926 enumNames
.push_back(field
->Data
->getName().convertedValue
);
931 ComplexType
* embedField
= NULL
;
932 ComplexType
* enumField
= NULL
;
934 //Find the embed and order fields, and remove them
935 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(), nextField
; field
; field
= nextField
) {
936 nextField
= field
->Next
;
937 if (field
->Data
->embed
) {
938 embedField
= new ComplexType(*field
->Data
);
939 embedField
->parent
= this;
942 complexfields
.remove(field
);
943 } else if (field
->Data
->enumerated
) {
944 enumField
= new ComplexType(*field
->Data
);
945 enumField
->parent
= this;
948 complexfields
.remove(field
);
952 if (enumField
!= NULL
) {
953 //Insert the order field in the front
954 complexfields
.push_front(enumField
);
955 //Push the field names into the order field
956 for (List
<Mstring
>::iterator field
= enumNames
.begin(); field
; field
= field
->Next
) {
957 enumField
->enumfields
.push_back(field
->Data
);
961 if (embedField
!= NULL
) {
962 //Insert the embed field to the front
963 complexfields
.push_front(embedField
);
968 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
969 if (field
->Data
->name
.convertedValue
.foundAt("alt_") == field
->Data
->name
.convertedValue
.c_str()) {
971 field
->Data
->name
.upload(Mstring("alt_"));
973 field
->Data
->name
.upload(Mstring(mprintf("alt_%d", number
)));
980 AttributeType
* anyAttr
= NULL
;
981 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(), nextField
; field
; field
= nextField
) {
982 nextField
= field
->Next
;
983 field
->Data
->applyUseAttribute();
984 //Find anyattribute, and remove it
985 if (field
->Data
->isAnyAttribute()) {
986 anyAttr
= new AttributeType(*field
->Data
);
987 setParent(this, anyAttr
);
990 attribfields
.remove(field
);
991 } else if (field
->Data
->getUseVal() == prohibited
|| !field
->Data
->isVisible()) {
992 //Not visible attribute removed
995 attribfields
.remove(field
);
997 field
->Data
->SimpleType::finalModification();
1001 //Push anyattribute to the front
1002 if (anyAttr
!= NULL
) {
1003 anyAttr
->applyNamespaceAttribute(V_anyAttributes
);
1004 attribfields
.push_back(anyAttr
);
1007 //Substitution group ordering
1008 if(subsGroup
== this){ //We are a generated substitution group
1009 //Substitution group never empty
1010 ComplexType
* front
= complexfields
.front();
1011 List
<ComplexType
*>::iterator it
= complexfields
.begin();
1012 complexfields
.remove(it
);
1013 complexfields
.sort(compareComplexTypeNameSpaces
);
1014 complexfields
.sort(compareTypes
);
1015 complexfields
.push_front(front
);
1019 void ComplexType::finalModification() {
1020 finalModification2();
1021 setFieldPaths(empty_string
);
1022 List
<Mstring
> container
;
1023 collectVariants(container
);
1025 variant
= container
;
1028 void ComplexType::printToFile(FILE * file
) {
1029 printToFile(file
, 0, false);
1032 void ComplexType::printToFile(FILE * file
, const unsigned level
, const bool is_union
) {
1036 printComment(file
, level
);
1038 fprintf(file
, "type ");
1039 if(mode
== listMode
){
1040 printMinOccursMaxOccurs(file
, is_union
);
1041 fprintf(file
, "%s", type
.convertedValue
.c_str());
1043 fprintf(file
, "%s %s", type
.convertedValue
.c_str(), name
.convertedValue
.c_str());
1045 fprintf(file
, "\n{\n");
1047 if (attribfields
.empty() && complexfields
.empty()) {
1048 fprintf(file
, "\n");
1051 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(), nextField
; c
; c
= nextField
) {
1052 nextField
= c
->Next
;
1053 if (c
->Data
->embed
|| c
->Data
->enumerated
) {
1054 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1055 if (c
->Next
!= NULL
|| !attribfields
.empty()) {
1056 fprintf(file
, ",\n");
1058 fprintf(file
, "\n");
1062 complexfields
.remove(c
);
1066 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1067 f
->Data
->printToFile(file
, level
+ 1);
1068 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1069 fprintf(file
, ",\n");
1071 fprintf(file
, "\n");
1075 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1076 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1077 if (c
->Next
!= NULL
) {
1078 fprintf(file
, ",\n");
1080 fprintf(file
, "\n");
1084 const bool field_is_record
= getType().convertedValue
== Mstring("record");
1085 const bool field_is_union
= getType().convertedValue
== "union";
1086 if (complexfields
.empty() && attribfields
.empty() && (field_is_record
|| field_is_union
)) {
1087 if (field_is_record
) {
1088 indent(file
, level
);
1089 printMinOccursMaxOccurs(file
, is_union
);
1090 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1091 indent(file
, level
);
1092 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1094 fprintf(file
, " optional");
1096 } else if (field_is_union
) {
1097 indent(file
, level
);
1098 printMinOccursMaxOccurs(file
, is_union
);
1099 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1100 indent(file
, level
+ 1);
1101 fprintf(file
, "record length(0 .. 1) of enumerated { NULL_ } choice\n");
1102 indent(file
, level
);
1103 fprintf(file
, "} %s", getName().convertedValue
.c_str());
1105 fprintf(file
, " optional");
1109 indent(file
, level
);
1110 if (getEnumeration().modified
) {
1111 if (isFloatType(getBuiltInBase())) {
1112 fprintf(file
, "%s (", type
.convertedValue
.c_str());
1113 getEnumeration().sortFacets();
1114 getEnumeration().printToFile(file
);
1117 printMinOccursMaxOccurs(file
, with_union
);
1118 fprintf(file
, "enumerated {\n");
1119 //getEnumeration().sortFacets();
1120 getEnumeration().printToFile(file
, level
);
1121 fprintf(file
, "\n");
1122 indent(file
, level
);
1123 fprintf(file
, "} ");
1126 int multiplicity
= multi(module
, getReference(), this);
1127 if ((multiplicity
> 1) && getReference().get_ref()) {
1128 fprintf(file
, "%s.", getReference().get_ref()->getModule()->getModulename().c_str());
1130 if (field_is_record
|| field_is_union
) {
1131 printMinOccursMaxOccurs(file
, with_union
, !first_child
|| parent
->getXsdtype() != n_choice
);
1132 fprintf(file
, "%s {\n", getType().convertedValue
.c_str());
1133 for (List
<AttributeType
*>::iterator f
= attribfields
.begin(); f
; f
= f
->Next
) {
1134 f
->Data
->printToFile(file
, level
+ 1);
1135 if (f
->Next
!= NULL
|| !complexfields
.empty()) {
1136 fprintf(file
, ",\n");
1138 fprintf(file
, "\n");
1142 for (List
<ComplexType
*>::iterator c
= complexfields
.begin(); c
; c
= c
->Next
) {
1143 c
->Data
->printToFile(file
, level
+ 1, is_union
);
1144 if (c
->Next
!= NULL
) {
1145 fprintf(file
, ",\n");
1147 fprintf(file
, "\n");
1151 printMinOccursMaxOccurs(file
, with_union
, !first_child
);
1152 fprintf(file
, "%s ", getType().convertedValue
.c_str());
1153 if (getName().convertedValue
== Mstring("order") && getType().convertedValue
== Mstring("enumerated")) {
1154 fprintf(file
, "{\n");
1155 for (List
<Mstring
>::iterator e
= enumfields
.begin(); e
; e
= e
->Next
) {
1156 indent(file
, level
+ 1);
1157 fprintf(file
, "%s", e
->Data
.c_str());
1158 if (e
->Next
!= NULL
) {
1159 fprintf(file
, ",\n");
1161 fprintf(file
, "\n");
1164 indent(file
, level
);
1165 fprintf(file
, "} ");
1169 if (field_is_record
|| field_is_union
) {
1170 indent(file
, level
);
1171 fprintf(file
, "} ");
1174 fprintf(file
, "%s", getName().convertedValue
.c_str());
1175 getPattern().printToFile(file
);
1176 getValue().printToFile(file
);
1177 getLength().printToFile(file
);
1178 if (!with_union
&& isOptional
) {
1179 fprintf(file
, " optional");
1186 if(mode
== listMode
){
1187 fprintf(file
, " %s", name
.convertedValue
.c_str());
1190 fprintf(file
, ";\n\n\n");
1194 void ComplexType::collectVariants(List
<Mstring
>& container
) {
1196 if (e_flag_used
|| !isVisible()) {
1201 bool useUnionVariantWhenMainTypeIsRecordOf
= false;
1202 for (List
<Mstring
>::iterator var
= variant
.end(); var
; var
= var
->Prev
) {
1203 if ((minOccurs
!= 1 || maxOccurs
!= 1) && (var
->Data
== "\"useUnion\"")) { // main type is a record of
1204 useUnionVariantWhenMainTypeIsRecordOf
= true; // TR HL15893
1206 container
.push_back(Mstring("variant ") + Mstring(var
->Data
.c_str()) + Mstring(";\n"));
1209 if (useUnionVariantWhenMainTypeIsRecordOf
) {
1210 container
.push_back(Mstring("variant ([-]) \"useUnion\";\n"));
1214 //Collect variants of attributes
1215 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1216 field
->Data
->collectVariants(container
);
1219 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1221 if (!field
->Data
->isVisible()) {
1225 if (field
->Data
->getVariant().empty() && field
->Data
->getHiddenVariant().empty() &&
1226 field
->Data
->complexfields
.empty() && field
->Data
->attribfields
.empty() &&
1227 field
->Data
->enumeration
.variants
.empty()) {
1231 bool already_used
= false;
1233 for (List
<Mstring
>::iterator var2
= field
->Data
->getVariant().end(); var2
; var2
= var2
->Prev
) {
1234 if (var2
->Data
== "\"untagged\"" && !already_used
) {
1235 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1236 already_used
= true;
1238 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1239 (field
->Data
->getName().list_extension
|| var2
->Data
== "\"useUnion\"")) {
1240 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1241 } else if (var2
->Data
!= "\"untagged\"") {
1242 container
.push_back(Mstring("variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
1246 for (List
<Mstring
>::iterator hidden_var
= field
->Data
->getHiddenVariant().end();
1247 hidden_var
; hidden_var
= hidden_var
->Prev
) {
1248 if ((field
->Data
->getMinOccurs() != 1 || field
->Data
->getMaxOccurs() != 1) &&
1249 field
->Data
->getName().list_extension
) {
1250 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring("[-]) ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1252 container
.push_back(Mstring("//variant (") + field
->Data
->actualPath
+ Mstring(") ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
1256 if(field
->Data
->enumeration
.modified
){
1257 Mstring path
= empty_string
;
1258 if(field
->Data
->getMinOccurs() != 1 && field
->Data
->getMaxOccurs() != 1){
1259 path
= field
->Data
->actualPath
+ Mstring("[-]");
1261 path
= field
->Data
->actualPath
;
1263 for(List
<Mstring
>::iterator var
= field
->Data
->enumeration
.variants
.end(); var
; var
= var
->Prev
){
1264 if(var
->Data
.empty()) continue;
1265 container
.push_back("variant (" + path
+ ") " + var
->Data
+ ";\n");
1269 field
->Data
->collectVariants(container
);
1273 void ComplexType::printVariant(FILE * file
) {
1278 bool foundAtLeastOneVariant
= false;
1279 bool foundAtLeastOneHiddenVariant
= false;
1281 if (!variant
.empty()) {
1282 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1283 if (foundAtLeastOneVariant
&& foundAtLeastOneHiddenVariant
) {
1286 if (var
->Data
[0] != '/') {
1287 foundAtLeastOneVariant
= true;
1289 foundAtLeastOneHiddenVariant
= true;
1294 if (!foundAtLeastOneVariant
&& !foundAtLeastOneHiddenVariant
) {
1298 if (!foundAtLeastOneVariant
) {
1299 //No other variants, only commented, so the 'with' must be commented also.
1300 fprintf(file
, ";\n//with {\n");
1302 fprintf(file
, "\nwith {\n");
1305 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1306 fprintf(file
, "%s", var
->Data
.c_str());
1309 if (!foundAtLeastOneVariant
) {
1310 fprintf(file
, "//");
1315 void ComplexType::dump(unsigned int depth
) const {
1316 fprintf(stderr
, "%*s %sComplexType at %p | Top:%s\n", depth
* 2, "", isVisible() ? "" : "(hidden)", (const void*) this, top
? "true" : "false");
1317 if (parent
!= NULL
) {
1318 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %i | my xsdtype: %i\n", depth
* 2, "", (const void*) parent
, parent
->getXsdtype(), xsdtype
);
1320 fprintf(stderr
, "%*s parent: %p | parent xsdtype: %s | my xsdtype: %i\n", depth
* 2, "", "NULL", "NULL", xsdtype
);
1322 fprintf(stderr
, "%*s name='%s' -> '%s', type='%s' %d complexfields | %s | %s | %s\n", depth
* 2, "",
1323 name
.originalValueWoPrefix
.c_str(), name
.convertedValue
.c_str(), type
.convertedValue
.c_str(), (int) complexfields
.size(),
1324 outside_reference
.empty() ? "" : outside_reference
.get_val().c_str(), mode
== restrictionMode
? "restriction" : "",
1325 mode
== extensionMode
? "extension" : "");
1326 for (List
<ComplexType
*>::iterator field
= complexfields
.begin(); field
; field
= field
->Next
) {
1327 field
->Data
->dump(depth
+ 1);
1329 fprintf(stderr
, "%*s %d attribields\n", depth
* 2, "", (int) attribfields
.size());
1330 for (List
<AttributeType
*>::iterator field
= attribfields
.begin(); field
; field
= field
->Next
) {
1331 field
->Data
->dump(depth
+ 1);
1333 fprintf(stderr
, "%*s %d enumfields\n", depth
* 2, "", (int) enumfields
.size());
1334 for (List
<Mstring
>::iterator field
= enumfields
.begin(); field
; field
= field
->Next
) {
1335 fprintf(stderr
, "%*s enum: %s\n", depth
* 2 + depth
, "", field
->Data
.c_str());
1337 fprintf(stderr
, "%*s (%llu .. %llu) | Optional:%s | List:%s\n", (depth
+ 1) * 2, "", minOccurs
, maxOccurs
, isOptional
? "true" : "false", name
.list_extension
? "true" : "false");
1338 fprintf(stderr
, "%*s %d variants: ", (depth
+ 1) * 2, "", (int) variant
.size());
1339 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
1340 fprintf(stderr
, "%s, ", var
->Data
.c_str());
1342 fprintf(stderr
, "%*s pattern:%s | length:%i \n ", (depth
+ 1) * 2, "", this->pattern
.facet
.c_str(), (int) (this->length
.facet_maxLength
));
1343 fprintf(stderr
, "%*s enum: %i \n", (depth
+ 1)*2, "", (int) this->enumeration
.facets
.size());
1344 fprintf(stderr
, "\n");
1347 void ComplexType::setMinMaxOccurs(const unsigned long long min
, const unsigned long long max
, const bool generate_list_postfix
) {
1349 if (min
!= 1 || max
!= 1) {
1350 if (xsdtype
== n_choice
) {
1353 addVariant(V_untagged
);
1354 first_child
= false;
1355 } else if (xsdtype
== n_sequence
) {
1356 ComplexType
* rec
= new ComplexType(this);
1357 rec
->type
.upload(Mstring("record"));
1358 rec
->name
.upload(Mstring("sequence"));
1359 rec
->setXsdtype(n_sequence
);
1360 rec
->addVariant(V_untagged
);
1361 rec
->addVariant(V_untagged
);
1362 rec
->minOccurs
= min
;
1363 rec
->maxOccurs
= max
;
1364 complexfields
.push_back(rec
);
1366 if ((rec
->minOccurs
== 0 && rec
->maxOccurs
> 1) || rec
->minOccurs
> 0) {
1367 rec
->name
.list_extension
= true;
1372 if ((minOccurs
== 0 && maxOccurs
> 1) || minOccurs
> 0) {
1373 if (generate_list_postfix
) {
1374 name
.list_extension
= true;
1377 if (parent
!= NULL
&& parent
->getXsdtype() == n_choice
) {
1378 name
.list_extension
= true;
1379 if ((parent
!= NULL
&& parent
->getXsdtype() == n_choice
)) {
1380 if (parent
->first_child
== false && minOccurs
== 0) {
1381 parent
->first_child
= true;
1383 first_child
= false;
1393 if (maxOccurs
> 1 && generate_list_postfix
) {
1394 name
.list_extension
= true;
1398 void ComplexType::applyNamespaceAttribute(VariantMode varLabel
, const Mstring
& ns_list
) {
1399 List
<Mstring
> namespaces
;
1400 if (!ns_list
.empty()) {
1401 expstring_t valueToSplitIntoTokens
= mcopystr(ns_list
.c_str());
1403 token
= strtok(valueToSplitIntoTokens
, " ");
1404 while (token
!= NULL
) {
1405 namespaces
.push_back(Mstring(token
));
1406 token
= strtok(NULL
, " ");
1408 Free(valueToSplitIntoTokens
);
1413 // Note: libxml2 will verify the namespace list according to the schema
1414 // of XML Schema. It is either ##any, ##other, ##local, ##targetNamespace,
1415 // or a list of (namespace reference | ##local | ##targetNamespace).
1416 for (List
<Mstring
>::iterator ns
= namespaces
.begin(); ns
; ns
= ns
->Next
) {
1417 static const Mstring
xxany("##any"), xxother("##other"), xxlocal("##local"),
1418 xxtargetNamespace("##targetNamespace");
1419 if (!first
) any_ns
+= ',';
1421 if (ns
->Data
== xxany
) {
1422 }// this must be the only element, nothing to add
1423 else if (ns
->Data
== xxother
) { // this must be the only element
1424 any_ns
+= " except unqualified";
1425 if (module
->getTargetNamespace() != "NoTargetNamespace") {
1427 any_ns
+= parent
->getModule()->getTargetNamespace();
1430 }// The three cases below can happen multiple times
1432 if (first
) any_ns
+= " from ";
1433 // else a comma was already added
1434 if (ns
->Data
== xxtargetNamespace
) {
1436 any_ns
+= parent
->getModule()->getTargetNamespace();
1438 } else if (ns
->Data
== xxlocal
) {
1439 any_ns
+= "unqualified";
1450 addVariant(varLabel
, any_ns
, true);
1453 void ComplexType::addComment(const Mstring
& text
) {
1454 if (this == actfield
) {
1455 if (lastType
== n_attribute
) { // ez nem teljesen jo, stb, tobb lehetoseg, es rossy sorrend
1456 if (!attribfields
.empty()) {
1457 attribfields
.back()->addComment(text
);
1460 if (actfield
->getName().convertedValue
== Mstring("base") && parent
!= NULL
) {
1461 parent
->getComment().push_back(Mstring("/* " + text
+ " */\n"));
1463 comment
.push_back(Mstring("/* " + text
+ " */\n"));
1467 actfield
->addComment(text
);
1472 //Attribute extension logic when extending complextypes
1473 void ComplexType::applyAttributeExtension(ComplexType
* found_CT
, AttributeType
* anyAttrib
/* = NULL */) {
1474 for (List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1476 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1477 anyAttrib
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1480 for (List
<AttributeType
*>::iterator attr2
= attribfields
.begin(); attr2
; attr2
= attr2
->Next
) {
1481 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1482 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
) {
1483 if (attr
->Data
->getUseVal() == optional
) {
1484 attr2
->Data
->setUseVal(optional
);
1492 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1493 attribfields
.push_back(newAttrib
);
1494 setParent(this, newAttrib
);
1499 //Attribute restriction logic when restricting complextypes
1500 void ComplexType::applyAttributeRestriction(ComplexType
* found_CT
) {
1501 for (List
<AttributeType
*>::iterator attr
= attribfields
.begin(), nextAttr
; attr
; attr
= nextAttr
) {
1502 nextAttr
= attr
->Next
;
1504 for (List
<AttributeType
*>::iterator attr2
= found_CT
->attribfields
.begin(); attr2
; attr2
= attr2
->Next
) {
1505 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1506 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
) {
1514 attribfields
.remove(attr
);
1517 size_t size
= found_CT
->attribfields
.size();
1518 size_t size2
= attribfields
.size();
1520 List
<AttributeType
*>::iterator attr
= found_CT
->attribfields
.begin();
1521 for (; i
< size
; attr
= attr
->Next
, i
= i
+ 1) {
1524 List
<AttributeType
*>::iterator attr2
= attribfields
.begin();
1525 for (; j
< size2
; attr2
= attr2
->Next
, j
= j
+ 1) {
1526 if (attr
->Data
->getName().convertedValue
== attr2
->Data
->getName().convertedValue
&&
1527 attr
->Data
->getType().convertedValue
== attr2
->Data
->getType().convertedValue
&& !attr2
->Data
->getUsed()) {
1529 attr2
->Data
->setUsed(true);
1534 AttributeType
* newAttrib
= new AttributeType(*attr
->Data
);
1535 attribfields
.push_back(newAttrib
);
1536 setParent(this, newAttrib
);
1541 void ComplexType::addNameSpaceAsVariant(RootType
* root
, RootType
* other
) {
1542 if (other
->getModule()->getTargetNamespace() != root
->getModule()->getTargetNamespace() &&
1543 other
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1544 root
->addVariant(V_namespaceAs
, other
->getModule()->getTargetNamespace());
1548 void ComplexType::resolveAttribute(AttributeType
* attr
) {
1549 if (attr
->getXsdtype() == n_attribute
&& !attr
->getReference().empty()) {
1550 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(attr
, want_BOTH
);
1552 if (attr
->isFromRef()) {
1553 addNameSpaceAsVariant(attr
, st
);
1554 attr
->setTypeOfField(st
->getName().convertedValue
);
1555 attr
->setNameOfField(st
->getName().originalValueWoPrefix
);
1556 attr
->setOrigModule(st
->getModule());
1558 attr
->setTypeOfField(st
->getName().convertedValue
);
1559 if (st
->getType().convertedValue
== "record" || st
->getType().convertedValue
== "union") {
1560 st
->addToNameDepList(attr
);
1564 printError(module
->getSchemaname(), name
.convertedValue
,
1565 "Reference for a non-defined type: " + attr
->getReference().repr());
1566 TTCN3ModuleInventory::getInstance().incrNumErrors();
1571 void ComplexType::resolveAttributeGroup(SimpleType
* st
) {
1572 if (xsdtype
== n_attributeGroup
&& !outside_reference
.empty()) {
1573 ComplexType
* ct
= (ComplexType
*) st
;
1574 if(ct
->resolved
== No
){
1575 ct
->referenceResolving();
1577 outside_reference
.set_resolved(ct
);
1579 bool addNameSpaceas
= false;
1580 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1581 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1582 addNameSpaceas
= true;
1585 if(parent
->nillable
&& parent
->parent
!= NULL
){
1586 par
= parent
->parent
;
1590 List
<AttributeType
*>::iterator anyAttrib
= par
->attribfields
.begin();
1591 for (; anyAttrib
; anyAttrib
= anyAttrib
->Next
) {
1592 if (anyAttrib
->Data
->isAnyAttribute()) {
1596 for (List
<AttributeType
*>::iterator attr
= ct
->attribfields
.begin(); attr
; attr
= attr
->Next
) {
1597 AttributeType
* attrib
= new AttributeType(*attr
->Data
);
1598 attr
->Data
->setOrigModule(ct
->getModule());
1599 if (addNameSpaceas
) {
1600 attrib
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1602 if (anyAttrib
!= NULL
&& attr
->Data
->isAnyAttribute()) {
1603 anyAttrib
->Data
->addNameSpaceAttribute(attr
->Data
->getNameSpaceAttribute());
1605 //Nillable attribute placement is hard...
1606 if (parent
->nillable
&& parent
->parent
!= NULL
) {
1607 parent
->parent
->attribfields
.push_back(attrib
);
1608 attrib
->parent
= parent
->parent
;
1609 setParent(parent
->parent
, attrib
);
1610 } else if (parent
->nillable
&& !parent
->complexfields
.empty()) {
1611 parent
->complexfields
.back()->attribfields
.push_back(attrib
);
1612 attrib
->parent
= parent
->complexfields
.back();
1613 } else if (parent
->parent
!= NULL
&& (parent
->parent
->mode
== extensionMode
|| parent
->parent
->mode
== restrictionMode
)) {
1614 parent
->parent
->attribfields
.push_back(attrib
);
1615 setParent(parent
->parent
, attrib
);
1617 parent
->attribfields
.push_back(attrib
);
1618 setParent(parent
, attrib
);
1625 void ComplexType::resolveGroup(SimpleType
*st
) {
1626 if (xsdtype
== n_group
&& !outside_reference
.empty()) {
1627 ComplexType
* ct
= (ComplexType
*) st
;
1628 outside_reference
.set_resolved(ct
);
1630 if(ct
->resolved
== No
){
1631 ct
->referenceResolving();
1633 //Decide if namespaceas variant needs to be added
1634 bool addNameSpaceas
= false;
1635 if (ct
->getModule()->getTargetNamespace() != module
->getTargetNamespace() &&
1636 ct
->getModule()->getTargetNamespace() != "NoTargetNamespace") {
1637 addNameSpaceas
= true;
1639 if (ct
->getXsdtype() == n_sequence
&& minOccurs
== 1 && maxOccurs
== 1 && (parent
->getXsdtype() == n_complexType
|| parent
->getXsdtype() == n_sequence
)) {
1640 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1641 ComplexType
* newField
= new ComplexType(*c
->Data
);
1642 parent
->complexfields
.push_back(newField
);
1643 setParent(parent
, newField
);
1644 parent
->complexfields
.back()->setModule(getModule());
1645 if (addNameSpaceas
) {
1646 parent
->complexfields
.back()->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1649 } else if (ct
->getXsdtype() == n_all
) {
1650 //If the parent optional, then every field is optional
1651 for (List
<ComplexType
*>::iterator c
= ct
->complexfields
.begin(); c
; c
= c
->Next
) {
1652 ComplexType
* f
= new ComplexType(*c
->Data
);
1653 if (minOccurs
== 0 && !f
->enumerated
) {
1654 f
->isOptional
= true;
1656 ((ComplexType
*) parent
)->complexfields
.push_back(f
);
1657 setParent(parent
, f
);
1658 f
->setModule(getModule());
1659 if (addNameSpaceas
) {
1660 f
->addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1663 parent
->addVariant(V_useOrder
);
1665 if (name
.list_extension
) {
1666 addVariant(V_untagged
);
1668 type
.upload(ct
->getName().convertedValue
);
1669 name
.upload(ct
->getName().convertedValue
);
1670 ct
->addToNameDepList(this);
1673 if (addNameSpaceas
) {
1674 addVariant(V_namespaceAs
, ct
->getModule()->getTargetNamespace());
1680 void ComplexType::resolveElement(SimpleType
*st
) {
1681 if (xsdtype
== n_element
&& !outside_reference
.empty()) {
1682 outside_reference
.set_resolved(st
);
1683 type
.upload(st
->getModule()->getTargetNamespaceConnector() + Mstring(":") + st
->getName().convertedValue
);
1684 st
->addToNameDepList(this);
1686 if (name
.originalValueWoPrefix
.empty()) {
1687 name
.upload(st
->getName().convertedValue
);
1690 addNameSpaceAsVariant(this, st
);
1692 if(st
->getSubstitution() != NULL
){
1693 st
->getSubstitution()->addToNameDepList(this);
1694 nameDep
= st
->getSubstitution();
1699 void ComplexType::resolveSimpleTypeExtension() {
1700 if (mode
== extensionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1701 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1703 if (st
->getXsdtype() != n_NOTSET
&& ((ComplexType
*) st
)->basefield
!= NULL
) { // if the xsdtype != simpletype
1704 ComplexType
* ct
= (ComplexType
*) st
;
1705 if (ct
->resolved
== No
) {
1706 ct
->referenceResolving();
1708 basefield
->outside_reference
.set_resolved(ct
);
1709 ct
->basefield
->addToNameDepList(basefield
);
1710 basefield
->nameDep
= ct
->basefield
;
1711 basefield
->mode
= extensionMode
;
1712 basefield
->applyReference(*ct
->basefield
, true);
1713 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1714 applyAttributeExtension(ct
);
1716 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1717 st
->referenceResolving();
1719 st
->addToNameDepList(basefield
);
1720 addNameSpaceAsVariant(basefield
, st
);
1721 basefield
->nameDep
= st
;
1723 } else if(!isBuiltInType(basefield
->getType().convertedValue
)){
1724 printError(module
->getSchemaname(), name
.convertedValue
,
1725 "Reference for a non-defined type: " + basefield
->getReference().repr());
1726 TTCN3ModuleInventory::getInstance().incrNumErrors();
1733 void ComplexType::resolveSimpleTypeRestriction() {
1734 if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
&& !basefield
->outside_reference
.empty()) {
1735 SimpleType
* st
= (SimpleType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_BOTH
);
1737 printError(module
->getSchemaname(), name
.convertedValue
,
1738 "Reference for a non-defined type: " + basefield
->getReference().repr());
1739 TTCN3ModuleInventory::getInstance().incrNumErrors();
1742 basefield
->outside_reference
.set_resolved(st
);
1743 if (st
->getXsdtype() != n_NOTSET
) {
1744 ComplexType
* ct
= (ComplexType
*) st
;
1745 if (ct
->resolved
== No
) {
1746 ct
->referenceResolving();
1748 applyAttributeRestriction(ct
);
1749 basefield
->mode
= restrictionMode
;
1750 if (ct
->cmode
== CT_complextype_mode
) {
1751 applyReference(*ct
, true);
1752 type
.upload(ct
->getName().convertedValue
);
1753 basefield
->setInvisible();
1754 } else if (ct
->basefield
!= NULL
) {
1755 basefield
->applyReference(*ct
->basefield
);
1756 addNameSpaceAsVariant(basefield
, ct
->basefield
);
1757 } else if (ct
->basefield
== NULL
) {
1758 basefield
->applyReference(*ct
);
1759 addNameSpaceAsVariant(basefield
, ct
);
1762 if (!st
->getReference().empty() && !st
->getReference().is_resolved()) {
1763 st
->referenceResolving();
1765 if(xsdtype
== n_simpleContent
){
1766 basefield
->applyReference(*st
, true);
1767 addNameSpaceAsVariant(basefield
, st
);
1768 basefield
->mode
= restrictionMode
;
1769 }else if(xsdtype
== n_simpleType
){
1770 basefield
->setInvisible();
1771 applyReference(*basefield
, true);
1772 applyReference(*st
, true);
1773 addNameSpaceAsVariant(this, st
);
1774 basefield
->mode
= restrictionMode
;
1777 } else if (mode
== restrictionMode
&& cmode
== CT_simpletype_mode
&& basefield
!= NULL
) {
1778 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(basefield
, want_CT
);
1779 if (ct
== NULL
&& !isBuiltInType(basefield
->getType().convertedValue
)) {
1780 printError(module
->getSchemaname(), name
.convertedValue
,
1781 "Reference for a non-defined type: " + basefield
->getReference().repr());
1782 TTCN3ModuleInventory::getInstance().incrNumErrors();
1786 basefield
->outside_reference
.set_resolved(ct
);
1788 if (ct
->resolved
== No
) {
1789 ct
->referenceResolving();
1791 for (List
<AttributeType
*>::iterator f
= ct
->attribfields
.begin(); f
; f
= f
->Next
) {
1792 AttributeType
* attr
= new AttributeType(*f
->Data
);
1793 attribfields
.push_back(attr
);
1794 setParent(this, attr
);
1796 addNameSpaceAsVariant(this, ct
);
1798 if(!basefield
->parent
->top
){
1799 applyReference(*basefield
, true);
1800 basefield
->setInvisible();
1805 void ComplexType::resolveComplexTypeExtension() {
1806 if (mode
== extensionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1807 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1809 printError(module
->getSchemaname(), name
.convertedValue
,
1810 "Reference for a non-defined type: " + getReference().repr());
1811 TTCN3ModuleInventory::getInstance().incrNumErrors();
1814 if(ct
->getXsdtype() != n_NOTSET
){
1815 outside_reference
.set_resolved(ct
);
1816 if (ct
->resolved
== No
) {
1817 ct
->referenceResolving();
1819 List
<AttributeType
*>::iterator anyAttr
= attribfields
.begin();
1820 for (; anyAttr
; anyAttr
= anyAttr
->Next
) {
1821 if (anyAttr
->Data
->isAnyAttribute()) {
1826 if (anyAttr
!= NULL
) {
1827 applyAttributeExtension(ct
, anyAttr
->Data
);
1829 applyAttributeExtension(ct
);
1832 if (ct
->getName().convertedValue
== outside_reference
.get_val() && ct
->getModule()->getTargetNamespace() == outside_reference
.get_uri()) {
1834 outside_reference
.set_resolved(ct
);
1835 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1836 if (f
->Data
!= this) { //not a self recursive field
1837 ComplexType
* newField
= new ComplexType(*f
->Data
);
1838 complexfields
.push_front(newField
);
1839 setParent(this, newField
);
1841 //Self recursive field
1842 ComplexType
* field
= new ComplexType(this);
1843 field
->name
.upload(f
->Data
->getName().convertedValue
);
1844 field
->applyReference(*f
->Data
);
1845 field
->type
.upload(ct
->getName().convertedValue
+ Mstring(".") + f
->Data
->getName().convertedValue
);
1846 field
->type
.no_replace
= true;
1847 field
->minOccurs
= f
->Data
->minOccurs
;
1848 field
->maxOccurs
= f
->Data
->maxOccurs
;
1849 complexfields
.push_front(field
);
1850 setParent(this, field
);
1855 for (List
<ComplexType
*>::iterator f
= ct
->complexfields
.end(); f
; f
= f
->Prev
) {
1856 ComplexType
* newField
= new ComplexType(*f
->Data
);
1857 complexfields
.push_front(newField
);
1858 setParent(this, newField
);
1865 void ComplexType::resolveComplexTypeRestriction() {
1866 if (mode
== restrictionMode
&& cmode
== CT_complextype_mode
&& !outside_reference
.empty()) {
1867 ComplexType
* ct
= (ComplexType
*) TTCN3ModuleInventory::getInstance().lookup(this, want_CT
);
1868 if(ct
->getXsdtype() != n_NOTSET
){
1869 if (ct
->resolved
== No
) {
1870 ct
->referenceResolving();
1872 outside_reference
.set_resolved(ct
);
1873 applyAttributeRestriction(ct
);
1875 size_t size
= complexfields
.size();
1877 List
<ComplexType
*>::iterator field
= complexfields
.begin();
1878 for (; i
< size
; field
= field
->Next
, i
= i
+ 1){
1879 List
<ComplexType
*>::iterator field2
= ct
->complexfields
.begin();
1880 for (; field2
; field2
= field2
->Next
) {
1881 if (field
->Data
->getName().convertedValue
== field2
->Data
->getName().convertedValue
&&
1882 field
->Data
->getType().convertedValue
== field2
->Data
->getType().convertedValue
) {
1883 field
->Data
->applyReference(*field2
->Data
, false);
1888 field
->Data
->setInvisible();
1895 void ComplexType::resolveUnion(SimpleType
*st
) {
1896 if (parent
!= NULL
&& parent
->with_union
&& xsdtype
== n_simpleType
&& !outside_reference
.empty()) {
1897 if (st
->getXsdtype() != n_NOTSET
) {
1898 ComplexType
* ct
= (ComplexType
*) st
;
1899 outside_reference
.set_resolved(ct
);
1900 for (List
<ComplexType
*>::iterator field
= ct
->complexfields
.begin(); field
; field
= field
->Next
) {
1901 ComplexType
* newField
= new ComplexType(*field
->Data
);
1902 parent
->complexfields
.push_back(newField
);
1903 setParent(parent
, newField
);
1910 void ComplexType::modifyAttributeParent() {
1911 if (nillable_field
!= NULL
) {
1912 ((ComplexType
*) nillable_field
)->actfield
= nillable_field
;
1918 void ComplexType::addSubstitution(SimpleType
* st
){
1919 ComplexType
* element
;
1920 if(st
->getXsdtype() == n_NOTSET
|| !complexfields
.empty()){
1921 element
= new ComplexType(*st
, fromTagSubstition
);
1923 element
= new ComplexType(*(ComplexType
*)st
);
1924 element
->variant
.clear();
1926 element
->subsGroup
= this;
1927 element
->parent
= this;
1928 if(complexfields
.empty()){ //The first element(head)
1929 element
->setTypeValue(st
->getType().convertedValue
);
1930 if(st
->hasVariant(Mstring("\"abstract\""))){
1931 element
->addVariant(V_onlyValueHidden
, Mstring("\"abstract\""));
1935 if(st
->getType().convertedValue
== "anyType"){
1936 newType
= complexfields
.front()->getType().convertedValue
;
1938 newType
= st
->getName().convertedValue
;
1939 st
->addToNameDepList(element
);
1941 element
->setTypeValue(newType
);
1942 BlockValue front_block
= complexfields
.front()->getBlock();
1943 if(front_block
== all
|| front_block
== substitution
){
1944 element
->addVariant(V_onlyValueHidden
, Mstring("\"block\""));
1945 }else if(front_block
== restriction
|| front_block
== extension
){
1946 const Mstring
& head_type
= complexfields
.front()->getType().convertedValue
.getValueWithoutPrefix(':');
1947 Mstring elem_type
= findRoot(front_block
, st
, head_type
, true);
1948 if(head_type
== elem_type
){
1949 element
->addVariant(V_onlyValueHidden
, Mstring("\"block\""));
1954 element
->setNameValue(st
->getName().convertedValue
);
1955 element
->top
= false;
1956 complexfields
.push_back(element
);
1959 Mstring
ComplexType::findRoot(const BlockValue block_value
, SimpleType
* elem
, const Mstring
& head_type
, const bool first
){
1960 if(!first
&& elem
->getType().convertedValue
.getValueWithoutPrefix(':') == head_type
&& !isFromRef()){
1961 return elem
->getType().convertedValue
.getValueWithoutPrefix(':');
1962 }else if(elem
->getType().convertedValue
.getValueWithoutPrefix(':') == head_type
&& (isFromRef() && ((elem
->getMode() == restrictionMode
&& block_value
== restriction
) || (elem
->getMode() == extensionMode
&& block_value
== extension
)))){
1963 return elem
->getType().convertedValue
.getValueWithoutPrefix(':');
1965 SimpleType
* st
= NULL
;
1966 if((elem
->getMode() == restrictionMode
&& block_value
== restriction
) ||
1967 (elem
->getMode() == extensionMode
&& block_value
== extension
)){
1968 if(!elem
->getReference().is_resolved()){
1969 elem
->referenceResolving();
1971 if(elem
->getXsdtype() != n_NOTSET
){
1972 ComplexType
* ct
= (ComplexType
*)elem
;
1973 if(ct
->basefield
!= NULL
&& ct
->basefield
->getType().convertedValue
.getValueWithoutPrefix(':') == head_type
){
1975 }else if(ct
->basefield
!= NULL
){
1976 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(ct
->basefield
, want_BOTH
);
1980 st
= (SimpleType
*)(elem
->getReference().get_ref());
1982 }else if(elem
->getMode() == noMode
&& (block_value
== restriction
|| block_value
== extension
)){
1983 st
= (SimpleType
*)TTCN3ModuleInventory::getInstance().lookup(this, elem
->getType().convertedValue
, want_BOTH
);
1985 if(st
!= NULL
&& elem
!= st
){
1986 return findRoot(block_value
, st
, head_type
, false);
1989 if(elem
->getMode() == noMode
&& !first
){
1990 return elem
->getType().convertedValue
.getValueWithoutPrefix(':');
1992 return empty_string
;