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