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