private void processParticles()

in src/com/intellij/idea/plugin/hybris/system/type/model/generator/XSDModelLoader.java [521:773]


    private void processParticles(
        final XSObject def,
        final LinkedList<PEntry> plist,
        final Map<String, NamespaceDesc> nsdMap,
        final Map<String, TypeDesc> jtMap,
        final TypeDesc td,
        final List<XSModel> models,
        final ArrayList<XSComplexTypeDefinition> toAdd,
        final TypeDesc baseClass
    ) {
        final boolean globalMerge = jtMap.containsKey(model.toJavaQualifiedTypeName(
            def,
            nsdMap,
            td.type == TypeDesc.TypeEnum.ENUM
        ));
        final HashMap<XSParticle, String> globalChoice = new HashMap<>();
        final ArrayList<XSObjectList> choiceList = new ArrayList<>();
        final ArrayList<TypeDesc> supers = new ArrayList<>();
        if (baseClass != null) {
            supers.add(baseClass);
        }
        while (!plist.isEmpty()) {
            final PEntry pentry = plist.removeFirst();
            final XSParticle p = pentry.p;
            if (p.getTerm() instanceof final XSElementDecl el) {
                if (el.getConstraintType() == XSConstants.VC_FIXED) {
                    continue;
                }
                XSTypeDefinition etRoot = el.getTypeDefinition();
                XSTypeDefinition et = etRoot;
                XSAnnotation ann = el.getAnnotation();
                String documentation = parseAnnotationString(
                    "Element " + el.getNamespace() + ':' + el.getName() + " documentation",
                    ann != null ? ann.getAnnotationString() : null
                );
                final FieldDesc fd1 = new FieldDesc(
                    FieldDesc.STR,
                    Util.toJavaFieldName(el.getName()),
                    et.getName(),
                    null,
                    "null",
                    !pentry.many && p.getMinOccurs() > 0
                );
                fd1.documentation = documentation;
                fd1.tagName = el.getName();
                while (et.getBaseType() != null && !"anySimpleType".equals(et.getBaseType()
                                                                             .getName()) && !"anyType".equals(et.getBaseType()
                                                                                                                .getName())) {
                    et = et.getBaseType();
                }
                if (checkEnumType(etRoot)) {
                    if (etRoot.getAnonymous()) {
                        etRoot = makeTypeFromAnonymous(el);
                        if (toAdd != null) {
                            toAdd.add((XSComplexTypeDefinition) etRoot);
                        }
                    }
                    fd1.type = toJavaTypeName(etRoot, nsdMap);
                    fd1.clType = FieldDesc.OBJ;
                    fd1.contentQualifiedName = model.toJavaQualifiedTypeName(etRoot, nsdMap, true);
                    // forward decl
                    if (!jtMap.containsKey(fd1.contentQualifiedName)) {
                        // logwarn("forward decl: "+et);
                        final TypeDesc ftd = new TypeDesc(
                            etRoot.getName(),
                            etRoot.getNamespace(),
                            fd1.type,
                            TypeDesc.TypeEnum.ENUM
                        );
                        jtMap.put(fd1.contentQualifiedName, ftd);
                    }
                } else if (checkComplexType(etRoot)) {
                    if (etRoot.getAnonymous()) {
                        etRoot = makeTypeFromAnonymous(el);
                        if (toAdd != null) {
                            toAdd.add((XSComplexTypeDefinition) etRoot);
                        }
                    }
                    fd1.type = toJavaTypeName(etRoot, nsdMap);
                    fd1.clType = FieldDesc.OBJ;
                    fd1.contentQualifiedName = model.toJavaQualifiedTypeName(etRoot, nsdMap, false);
                    // forward decl
                    if (jtMap.get(fd1.contentQualifiedName) == null) {
                        //logwarn("forward decl: "+etRoot);
                        jtMap.put(
                            fd1.contentQualifiedName,
                            new TypeDesc(
                                etRoot.getName(),
                                etRoot.getNamespace(),
                                fd1.type,
                                TypeDesc.TypeEnum.CLASS
                            )
                        );
                    }
                } else if (checkBooleanType(etRoot)) {
                    fd1.type = "boolean";
                    fd1.clType = FieldDesc.BOOL;
                } else {
                    if (etRoot instanceof final XSComplexTypeDefinition ct) {
                        // XXX xerces2.7.1 wierd annotation inheritance bug fix
                        //ann = (XSAnnotation) (ct.getAnnotations()!=null && ct.getAnnotations().getLength()>0?ct.getAnnotations().item(0):null);
                        ann = (XSAnnotation) (ct.getAnnotations() != null && ct.getAnnotations().getLength() > 0
                                                  ? ct.getAnnotations().item(ct.getAnnotations().getLength() - 1)
                                                  : null);
                        documentation = parseAnnotationString(
                            "Type " + ct.getNamespace() + ':' + ct.getName() + " documentation",
                            ann != null ? ann.getAnnotationString() : null
                        );
                        if (documentation != null) {
                            fd1.documentation = fd1.documentation != null
                                ? fd1.documentation + '\n' + documentation
                                : documentation;
                        }
                    }
                    fd1.simpleTypesString = getSimpleTypesString(etRoot);

                    // "fully-qualified-classType", "jndi-nameType", "transaction-typeType"
                    // "java-identifierType", "pathType"
                    fd1.type = et.getName();
                    if (fd1.type == null) {
                        fd1.type = "String";
                        fd1.def = "null";
                        fd1.clType = FieldDesc.STR;
//            fd1.type = "boolean";
//            fd1.def = "false";
//            fd1.clType = FieldDesc.BOOL;
                    } else if (fd1.type.equals("string") || fd1.type.equals("anyURI")) {
                        fd1.type = "String";
                    } else if (fd1.type.equals("boolean")) {
                        fd1.type = "String";
                    } else if (fd1.type.equals("emptyType")) {
                        fd1.type = "boolean";
                        fd1.def = "false";
                        fd1.clType = FieldDesc.BOOL;
                    } else if (fd1.type.equals("decimal")) {
                        fd1.type = "String";
                        fd1.def = "\"0.0\"";
                    } else if (fd1.type.equals("QName")) {
                        fd1.type = "String";
                    } else if (fd1.type.equals("extensibleType")) {
                        fd1.type = "Object";
                    } else {
                        if (et.getBaseType() != null &&
                            ("anySimpleType".equals(et.getBaseType().getName())
                             || "anyType".equals(et.getBaseType().getName()))) {
                            fd1.type = "String";
                            fd1.def = "null";
                            fd1.clType = FieldDesc.STR;
                        } else {
                            fd1.type = "boolean";
                            fd1.def = "false";
                            fd1.clType = FieldDesc.BOOL;
                        }
                        Util.logwarn("using '" + fd1.type + "' for unknown base type: " + et.getName() + " for " + el);
                    }
                }
                if ((pentry.many || p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1) && fd1.clType != FieldDesc.BOOL) {
                    fd1.elementType = fd1.type;
                    fd1.elementName = fd1.name;
                    fd1.type = "List<" + fd1.elementType + '>';
                    fd1.name = Util.pluralize(fd1.name);
                    fd1.def = "new ArrayList(0)";
                    fd1.clType = -fd1.clType;
                    fd1.comment = "array of " + fd1.elementType;
                }
                fd1.realIndex = td.fdMap.size();
                final boolean merge = globalMerge || globalChoice.containsKey(p) && globalChoice.values().contains(fd1.name);
                td.duplicates = Util.addToNameMap(td.fdMap, fd1, merge) || td.duplicates;
                globalChoice.put(p, fd1.name);
            } else if (p.getTerm() instanceof XSModelGroup) {
                boolean addToGlobalChoice = false;
                final boolean many = p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1;
                final XSObjectList l = ((XSModelGroup) p.getTerm()).getParticles();
                if (!many) {
                    if (((XSModelGroup) p.getTerm()).getCompositor() == XSModelGroup.COMPOSITOR_CHOICE) {
                        addToGlobalChoice = true;
                        choiceList.add(l);
                    } else {
                        // generate group interface???
                        final XSModelGroup groupDef = (XSModelGroup) p.getTerm();
                        final TypeDesc gtd = processGroup(groupDef, models, jtMap, nsdMap);
                        if (gtd != null) {
                            supers.add(gtd);
                        }
                    }
                }
                if (globalChoice.containsKey(p)) {
                    addToGlobalChoice = true;
                }
                for (int i = 0; i < l.getLength(); i++) {
                    final PEntry o = new PEntry((XSParticle) l.item(i), many);
                    plist.add(o);
                    if (addToGlobalChoice && !globalChoice.containsKey(o.p)) {
                        globalChoice.put(o.p, null);
                    }
                }
            }
        }
        int i = 0;
        for (final Iterator<FieldDesc> it = td.fdMap.values().iterator(); it.hasNext(); i++) {
            final FieldDesc fd = it.next();
            fd.idx = i;
        }
        for (XSObjectList l : choiceList) {
            final ArrayList<XSParticle> clist = new ArrayList<>();
            final LinkedList<XSParticle> elist = new LinkedList<>();
            for (i = 0; i < l.getLength(); i++) {
                elist.add((XSParticle) l.item(i));
            }
            while (!elist.isEmpty()) {
                final XSParticle p = elist.removeFirst();
                if (p.getTerm() instanceof XSModelGroup) {
                    final XSObjectList l2 = ((XSModelGroup) p.getTerm()).getParticles();
                    for (int i2 = 0; i2 < l2.getLength(); i2++) {
                        elist.addFirst((XSParticle) l2.item(i2));
                    }
                } else if (p.getTerm() instanceof XSElementDecl) {
                    clist.add(p);
                }
            }
            boolean choiceOpt = true;
            final FieldDesc[] choice = new FieldDesc[clist.size()];
            for (i = 0; i < choice.length; i++) {
                final XSParticle p = clist.get(i);
                final XSElementDecl el = (XSElementDecl) p.getTerm();
                String s = Util.toJavaFieldName(el.getName());
                if (p.getMaxOccursUnbounded() || p.getMaxOccurs() > 1) {
                    s = Util.pluralize(s);
                }
                FieldDesc fd = td.fdMap.get(s);
                if (fd == null) {
                    fd = td.fdMap.get(Util.pluralize(s));
                    if (fd == null) {
                        Util.logerr("uknown choice element: " + s);
                    }
                }

                if (fd != null) {
                    choice[i] = fd;
                    choice[i].choice = choice;
                    if (fd.required) {
                        choiceOpt = false;
                    }
                }
            }
            for (i = 0; i < choice.length; i++) {
                if (choice[i] != null) {
                    choice[i].choiceOpt = choiceOpt;
                }
            }
        }
        td.supers = supers.toArray(new TypeDesc[supers.size()]);
    }