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());
}
}
}
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();
}
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);
}
}
}
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;
}
Aggregations