Search in sources :

Example 1 with Label

use of com.squareup.wire.schema.Field.Label in project schema2proto by entur.

the class SchemaParser method processAttribute.

private void processAttribute(MessageType messageType, Set<Object> processedXmlObjects, XSAttributeUse attr) {
    if (!processedXmlObjects.contains(attr)) {
        processedXmlObjects.add(attr);
        XSAttributeDecl decl = attr.getDecl();
        XSSimpleType type = decl.getType();
        if (type.getPrimitiveType() != null || type.isList() || type.isUnion()) {
            String fieldName = decl.getName();
            String doc = resolveDocumentationAnnotation(decl, false);
            int tag = messageType.getNextFieldNum();
            Location fieldLocation = getLocation(decl);
            Options fieldOptions = getFieldOptions(decl);
            String packageName = NamespaceHelper.xmlNamespaceToProtoFieldPackagename(type.getTargetNamespace(), configuration.forceProtoPackage);
            Label label = type.isList() ? Label.REPEATED : null;
            if (type.isRestriction() && type.getFacet(XSFacet.FACET_ENUMERATION) != null) {
                String enumName = createEnum(fieldName, type.asRestriction(), decl.isLocal() ? messageType : null);
                Field field = new Field(packageName, fieldLocation, label, fieldName, doc, tag, enumName, fieldOptions, false);
                field.setFromAttribute(true);
                addField(messageType, field);
            } else {
                String typeName = findFieldType(type);
                Field field = new Field(basicTypes.contains(typeName) ? null : packageName, fieldLocation, label, fieldName, doc, tag, typeName, fieldOptions, false);
                field.setFromAttribute(true);
                addField(messageType, field);
            }
        } else {
            LOGGER.error("Unhandled attribute use {}", attr.getDecl());
        }
    }
}
Also used : Options(com.squareup.wire.schema.Options) Field(com.squareup.wire.schema.Field) XSSimpleType(com.sun.xml.xsom.XSSimpleType) XSAttributeDecl(com.sun.xml.xsom.XSAttributeDecl) Label(com.squareup.wire.schema.Field.Label) Location(com.squareup.wire.schema.Location)

Example 2 with Label

use of com.squareup.wire.schema.Field.Label in project schema-registry by confluentinc.

the class ProtobufSchemaUtils method toString.

private static String toString(Context ctx, FieldElement field, boolean normalize) {
    StringBuilder sb = new StringBuilder();
    Label label = field.getLabel();
    String fieldType = field.getType();
    ProtoType fieldProtoType = ProtoType.get(fieldType);
    if (normalize) {
        if (!fieldProtoType.isScalar() && !fieldProtoType.isMap()) {
            // See if the fieldType resolves to a message representing a map
            fieldType = resolve(ctx, fieldType);
            TypeElementInfo typeInfo = ctx.getTypeForFullName(fieldType, true);
            if (typeInfo != null && typeInfo.isMap()) {
                fieldProtoType = typeInfo.getMapType();
            } else {
                fieldProtoType = ProtoType.get(fieldType);
            }
        }
        ProtoType mapValueType = fieldProtoType.getValueType();
        if (fieldProtoType.isMap() && mapValueType != null) {
            // Ensure the value of the map is fully resolved
            String valueType = ctx.resolve(mapValueType.toString(), true);
            if (valueType != null) {
                fieldProtoType = ProtoType.get(// Note we add a leading dot to valueType
                "map<" + fieldProtoType.getKeyType() + ", ." + valueType + ">");
            }
            // don't emit label for map
            label = null;
        }
        fieldType = fieldProtoType.toString();
    }
    if (label != null) {
        sb.append(label.name().toLowerCase(Locale.US));
        sb.append(" ");
    }
    sb.append(fieldType);
    sb.append(" ");
    sb.append(field.getName());
    sb.append(" = ");
    sb.append(field.getTag());
    List<OptionElement> optionsWithSpecialValues = new ArrayList<>(field.getOptions());
    String defaultValue = field.getDefaultValue();
    if (defaultValue != null) {
        optionsWithSpecialValues.add(OptionElement.Companion.create("default", toKind(fieldProtoType), defaultValue));
    }
    String jsonName = field.getJsonName();
    if (jsonName != null) {
        optionsWithSpecialValues.add(OptionElement.Companion.create("json_name", Kind.STRING, jsonName));
    }
    if (!optionsWithSpecialValues.isEmpty()) {
        sb.append(" ");
        if (normalize) {
            optionsWithSpecialValues.sort(Comparator.comparing(OptionElement::getName));
        }
        appendOptions(sb, optionsWithSpecialValues, normalize);
    }
    sb.append(";\n");
    return sb.toString();
}
Also used : ProtoType(com.squareup.wire.schema.ProtoType) OptionElement(com.squareup.wire.schema.internal.parser.OptionElement) Label(com.squareup.wire.schema.Field.Label) ArrayList(java.util.ArrayList) TypeElementInfo(io.confluent.kafka.schemaregistry.protobuf.diff.Context.TypeElementInfo)

Example 3 with Label

use of com.squareup.wire.schema.Field.Label in project schema2proto by entur.

the class SchemaParser method navigateSubTypes.

private void navigateSubTypes(XSParticle parentParticle, MessageType messageType, Set<Object> processedXmlObjects, XSSchemaSet schemaSet, String enclosingName, String targetNamespace, XSComplexType enclosingType) {
    XSTerm currTerm = parentParticle.getTerm();
    Label label = getLabel(parentParticle, currTerm);
    Options fieldOptions = getFieldOptions(parentParticle);
    if (currTerm.isElementDecl()) {
        XSElementDecl currElementDecl = currTerm.asElementDecl();
        if (!processedXmlObjects.contains(currElementDecl)) {
            processedXmlObjects.add(currElementDecl);
            XSType type = currElementDecl.getType();
            String fieldDoc = resolveDocumentationAnnotation(currElementDecl, false);
            Location fieldLocation = getLocation(currElementDecl);
            String packageName = NamespaceHelper.xmlNamespaceToProtoFieldPackagename(type.getTargetNamespace(), configuration.forceProtoPackage);
            if (type.isSimpleType()) {
                if (type.asSimpleType().isRestriction() && type.asSimpleType().getFacet(XSFacet.FACET_ENUMERATION) != null) {
                    String enumName = createEnum(currElementDecl.getName(), type.asSimpleType().asRestriction(), type.isGlobal() ? null : messageType);
                    Field field = new Field(packageName, fieldLocation, label, currElementDecl.getName(), fieldDoc, messageType.getNextFieldNum(), enumName, fieldOptions, true);
                    addField(messageType, field);
                } else {
                    String typeName = findFieldType(type);
                    Field field = new Field(basicTypes.contains(typeName) ? null : packageName, fieldLocation, label, currElementDecl.getName(), fieldDoc, messageType.getNextFieldNum(), typeName, fieldOptions, true);
                    addField(messageType, field);
                }
            } else {
                if (type.isGlobal()) {
                    Set<XSElementDecl> substitutables = (Set<XSElementDecl>) currElementDecl.getSubstitutables();
                    LinkedHashSet<XSElementDecl> subsumptionSubstitutables = new LinkedHashSet<>();
                    if (configuration.derivationBySubsumption && type.isComplexType() && type.asComplexType().isAbstract()) {
                        // https://cs.au.dk/~amoeller/XML/schemas/xmlschema-inheritance.html
                        findGlobalElementsBySubsumption(schemaSet, subsumptionSubstitutables, (XSComplexType) type);
                    }
                    if (substitutables.size() <= 1 && subsumptionSubstitutables.isEmpty()) {
                        Field field = new Field(packageName, fieldLocation, label, currElementDecl.getName(), fieldDoc, messageType.getNextFieldNum(), type.getName(), fieldOptions, true);
                        addField(messageType, field);
                    } else {
                        if (label == Label.REPEATED) {
                            String wrapperName = createWrapperName(messageType, XSModelGroup.Compositor.CHOICE, enclosingName, (XSComplexType) type);
                            LOGGER.debug("Repeated element with multiple subs, created wrapper name {} from {}", wrapperName, enclosingName);
                            messageType = createWrapper(wrapperName, messageType, currElementDecl.getName(), type.getTargetNamespace(), parentParticle, fieldDoc, fieldLocation, (XSComplexType) type, "Generated wrapper for repeated oneOfs");
                        }
                        String oneOfName = currElementDecl.getType().getName();
                        // Current element is always a substitute for itself
                        if (substitutables.size() == 1 && substitutables.iterator().next() == currElementDecl && !subsumptionSubstitutables.isEmpty()) {
                            oneOfName = currElementDecl.getName();
                        }
                        List<Field> fields = new ArrayList<>();
                        OneOf oneOf = new OneOf(oneOfName, fieldDoc, fields, null);
                        messageType.oneOfs().add(oneOf);
                        LinkedHashSet<XSElementDecl> allSubtitutables = new LinkedHashSet<>();
                        allSubtitutables.addAll(substitutables);
                        allSubtitutables.addAll(subsumptionSubstitutables);
                        for (XSElementDecl substitutable : allSubtitutables) {
                            if (substitutable.isAbstract() || (substitutable.getType().isComplexType() && substitutable.getType().asComplexType().isAbstract())) {
                            // No abstract concept in protobuf, only concrete messages
                            } else {
                                addOneOfField(messageType, schemaSet, fieldOptions, fieldLocation, oneOf, substitutable);
                            }
                        }
                    }
                } else {
                    // Local
                    MessageType referencedMessageType = processComplexType(type.asComplexType(), currElementDecl.getName(), schemaSet, null, null);
                    Field field = new Field(packageName, fieldLocation, label, currElementDecl.getName(), fieldDoc, messageType.getNextFieldNum(), referencedMessageType.getName(), fieldOptions, true);
                    addField(messageType, field);
                    if (!currElementDecl.isGlobal()) {
                        messageType.nestedTypes().add(referencedMessageType);
                        localTypes.add(new LocalType(type, referencedMessageType, messageType, field, NamespaceHelper.xmlNamespaceToProtoPackage(type.getTargetNamespace(), configuration.forceProtoPackage), enclosingType));
                    }
                }
            }
        }
    } else if (currTerm.isWildcard()) {
        Location fieldLocation;
        if (currTerm.getLocator() != null) {
            fieldLocation = getLocation(currTerm.asWildcard());
        } else {
            fieldLocation = messageType.location();
        }
        Field field = new Field(null, fieldLocation, label, "any", resolveDocumentationAnnotation(currTerm.asWildcard(), false), messageType.getNextFieldNum(), "anyType", fieldOptions, true);
        addField(messageType, field);
    } else {
        XSModelGroup modelGroup = getModelGroup(currTerm);
        if (modelGroup != null) {
            processGroup(modelGroup, parentParticle, messageType, processedXmlObjects, schemaSet, enclosingName, targetNamespace, enclosingType);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Options(com.squareup.wire.schema.Options) XSSchemaSet(com.sun.xml.xsom.XSSchemaSet) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) XSTerm(com.sun.xml.xsom.XSTerm) Label(com.squareup.wire.schema.Field.Label) ArrayList(java.util.ArrayList) XSType(com.sun.xml.xsom.XSType) Field(com.squareup.wire.schema.Field) OneOf(com.squareup.wire.schema.OneOf) XSComplexType(com.sun.xml.xsom.XSComplexType) XSElementDecl(com.sun.xml.xsom.XSElementDecl) MessageType(com.squareup.wire.schema.MessageType) Location(com.squareup.wire.schema.Location) XSModelGroup(com.sun.xml.xsom.XSModelGroup)

Example 4 with Label

use of com.squareup.wire.schema.Field.Label in project schema2proto by entur.

the class SchemaParser method processComplexType.

private MessageType processComplexType(XSComplexType complexType, String elementName, XSSchemaSet schemaSet, MessageType messageType, Set<Object> processedXmlObjects) {
    nestingLevel++;
    LOGGER.debug("{} ComplexType {}, proto {}", StringUtils.leftPad(" ", nestingLevel), complexType, messageType);
    boolean isBaseLevel = messageType == null;
    String typeName = null;
    if (messageType != null) {
        typeName = messageType.getName();
    }
    if (messageType == null) {
        if (configuration.skipEmptyTypeInheritance) {
            while (complexType.getContentType().asParticle() == null && complexType.getAttributeUses().isEmpty() && complexType.getBaseType().isComplexType()) {
                // Empty complex type
                complexType = complexType.getBaseType().asComplexType();
            }
        }
        typeName = complexType.getName();
        String nameSpace = complexType.getTargetNamespace();
        if (complexType.getScope() != null) {
            elementName = complexType.getScope().getName();
        }
        if (typeName == null) {
            typeName = elementName + GENERATED_NAME_PLACEHOLDER;
        }
        messageType = (MessageType) getType(nameSpace, typeName);
        if (messageType == null && !basicTypes.contains(typeName)) {
            String doc = resolveDocumentationAnnotation(complexType, true);
            Location location = getLocation(complexType);
            List<OptionElement> messageOptions = new ArrayList<>();
            if (configuration.includeXsdOptions) {
                XSType baseType = getBaseType(schemaSet, complexType);
                if (baseType != null) {
                    String prefix = "";
                    String packageName = NamespaceHelper.xmlNamespaceToProtoPackage(baseType.getTargetNamespace(), configuration.defaultProtoPackage);
                    if (StringUtils.trimToNull(packageName) != null && !baseType.getTargetNamespace().equals(nameSpace)) {
                        prefix = packageName + ".";
                    }
                    OptionElement e = new OptionElement(XSD_MESSAGE_OPTIONS_PACKAGE + "." + MessageType.BASE_TYPE_MESSAGE_OPTION, OptionElement.Kind.STRING, prefix + baseType.getName(), true);
                    messageOptions.add(e);
                }
            }
            Options options = new Options(Options.MESSAGE_OPTIONS, messageOptions);
            // Add message type to file
            messageType = new MessageType(ProtoType.get(typeName), location, doc, typeName, options);
            if (complexType.isGlobal() || (complexType.getScope() != null && complexType.getScope().isGlobal())) {
                /*
					 * Type is global OR scope is global
					 */
                addType(nameSpace, messageType);
            }
            processedXmlObjects = new HashSet<>();
            elementDeclarationsPerMessageType.put(messageType, processedXmlObjects);
        } else {
            LOGGER.debug("{} Already processed ComplexType {}, ignored", StringUtils.leftPad(" ", nestingLevel), typeName);
            nestingLevel--;
            return messageType;
        }
    }
    XSType parent = complexType.getBaseType();
    if (configuration.inheritanceToComposition && complexType.getContentType().asParticle() != null) {
        List<MessageType> parentTypes = new ArrayList<>();
        while (parent != schemaSet.getAnyType() && parent.isComplexType()) {
            // Ensure no duplicate element parsing
            MessageType parentType = processComplexType(parent.asComplexType(), elementName, schemaSet, null, null);
            processedXmlObjects.addAll(elementDeclarationsPerMessageType.get(parentType));
            parentTypes.add(parentType);
            parent = parent.getBaseType();
        }
        if (!isAbstract(complexType)) {
            Collections.reverse(parentTypes);
            for (MessageType parentMessageType : parentTypes) {
                String fieldDoc = parentMessageType.documentation();
                List<OptionElement> optionElements = new ArrayList<>();
                Options fieldOptions = new Options(Options.FIELD_OPTIONS, optionElements);
                int tag = messageType.getNextFieldNum();
                Location fieldLocation = getLocation(complexType);
                Field field = new Field(findPackageNameForType(parentMessageType), fieldLocation, null, "_" + parentMessageType.getName(), fieldDoc, tag, parentMessageType.getName(), fieldOptions, true);
                addField(messageType, field);
            }
            if (!parentTypes.isEmpty()) {
                messageType.advanceFieldNum();
            }
        }
    } else {
        if (parent != schemaSet.getAnyType() && parent.isComplexType()) {
            processComplexType(parent.asComplexType(), elementName, schemaSet, messageType, processedXmlObjects);
        }
    }
    if (complexType.getAttributeUses() != null) {
        processAttributes(complexType, messageType, processedXmlObjects);
    }
    if (complexType.getContentType().asParticle() != null) {
        XSParticle particle = complexType.getContentType().asParticle();
        XSTerm term = particle.getTerm();
        XSModelGroup modelGroup = getModelGroup(term);
        if (modelGroup != null) {
            String enclosingName = typeName;
            if (modelGroup.isModelGroupDecl()) {
                enclosingName = modelGroup.asModelGroupDecl().getName();
            }
            processGroup(modelGroup, particle, messageType, processedXmlObjects, schemaSet, enclosingName, complexType.getTargetNamespace(), complexType);
        }
    } else if (complexType.getContentType().asSimpleType() != null) {
        XSSimpleType xsSimpleType = complexType.getContentType().asSimpleType();
        if (isBaseLevel) {
            // Only add simpleContent from concrete type?
            boolean isList = xsSimpleType.isList();
            if (isList) {
                xsSimpleType = xsSimpleType.asList().getItemType();
            }
            String name;
            if (xsSimpleType.isUnion()) {
                name = DEFAULT_PROTO_PRIMITIVE;
            } else {
                name = xsSimpleType.getName();
            }
            Location fieldLocation = getLocation(xsSimpleType);
            Label label = isList || isCurrentOrParentList(xsSimpleType) ? Label.REPEATED : null;
            Options fieldOptions = getFieldOptions(xsSimpleType);
            String doc = resolveDocumentationAnnotation(complexType, false);
            if (name == null) {
                String simpleTypeName = findFieldType(xsSimpleType);
                String packageName = NamespaceHelper.xmlNamespaceToProtoFieldPackagename(xsSimpleType.getTargetNamespace(), configuration.forceProtoPackage);
                Field field = new Field(basicTypes.contains(simpleTypeName) ? null : packageName, fieldLocation, label, SIMPLECONTENT_VALUE_FIELD_NAME, doc, messageType.getNextFieldNum(), simpleTypeName, fieldOptions, true);
                addField(messageType, field);
            } else if (basicTypes.contains(name)) {
                Field field = new Field(null, fieldLocation, label, SIMPLECONTENT_VALUE_FIELD_NAME, doc, messageType.getNextFieldNum(), name, fieldOptions, true);
                addField(messageType, field);
            } else {
                XSSimpleType primitiveType = xsSimpleType.getPrimitiveType();
                if (primitiveType != null) {
                    Field field = new Field(null, fieldLocation, label, SIMPLECONTENT_VALUE_FIELD_NAME, doc, messageType.getNextFieldNum(), primitiveType.getName(), fieldOptions, true);
                    addField(messageType, field);
                } else {
                    LOGGER.warn("Unhandled simpleType {}", xsSimpleType);
                }
            }
        }
    }
    nestingLevel--;
    return messageType;
}
Also used : Options(com.squareup.wire.schema.Options) XSParticle(com.sun.xml.xsom.XSParticle) XSTerm(com.sun.xml.xsom.XSTerm) ArrayList(java.util.ArrayList) Label(com.squareup.wire.schema.Field.Label) XSType(com.sun.xml.xsom.XSType) Field(com.squareup.wire.schema.Field) XSSimpleType(com.sun.xml.xsom.XSSimpleType) OptionElement(com.squareup.wire.schema.internal.parser.OptionElement) MessageType(com.squareup.wire.schema.MessageType) Location(com.squareup.wire.schema.Location) XSModelGroup(com.sun.xml.xsom.XSModelGroup)

Aggregations

Label (com.squareup.wire.schema.Field.Label)4 Field (com.squareup.wire.schema.Field)3 Location (com.squareup.wire.schema.Location)3 Options (com.squareup.wire.schema.Options)3 ArrayList (java.util.ArrayList)3 MessageType (com.squareup.wire.schema.MessageType)2 OptionElement (com.squareup.wire.schema.internal.parser.OptionElement)2 XSModelGroup (com.sun.xml.xsom.XSModelGroup)2 XSSimpleType (com.sun.xml.xsom.XSSimpleType)2 XSTerm (com.sun.xml.xsom.XSTerm)2 XSType (com.sun.xml.xsom.XSType)2 OneOf (com.squareup.wire.schema.OneOf)1 ProtoType (com.squareup.wire.schema.ProtoType)1 XSAttributeDecl (com.sun.xml.xsom.XSAttributeDecl)1 XSComplexType (com.sun.xml.xsom.XSComplexType)1 XSElementDecl (com.sun.xml.xsom.XSElementDecl)1 XSParticle (com.sun.xml.xsom.XSParticle)1 XSSchemaSet (com.sun.xml.xsom.XSSchemaSet)1 TypeElementInfo (io.confluent.kafka.schemaregistry.protobuf.diff.Context.TypeElementInfo)1 HashSet (java.util.HashSet)1