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