use of com.squareup.wire.schema.Options in project apicurio-registry by Apicurio.
the class FileDescriptorUtils method toMessage.
private static MessageElement toMessage(FileDescriptorProto file, DescriptorProto descriptor) {
String name = descriptor.getName();
ImmutableList.Builder<FieldElement> fields = ImmutableList.builder();
ImmutableList.Builder<TypeElement> nested = ImmutableList.builder();
ImmutableList.Builder<ReservedElement> reserved = ImmutableList.builder();
ImmutableList.Builder<ExtensionsElement> extensions = ImmutableList.builder();
LinkedHashMap<String, ImmutableList.Builder<FieldElement>> oneofsMap = new LinkedHashMap<>();
for (OneofDescriptorProto od : descriptor.getOneofDeclList()) {
oneofsMap.put(od.getName(), ImmutableList.builder());
}
List<Map.Entry<String, ImmutableList.Builder<FieldElement>>> oneofs = new ArrayList<>(oneofsMap.entrySet());
List<FieldElement> proto3OptionalFields = new ArrayList<>();
for (FieldDescriptorProto fd : descriptor.getFieldList()) {
if (fd.hasProto3Optional()) {
proto3OptionalFields.add(toField(file, fd, false));
continue;
}
if (fd.hasOneofIndex()) {
FieldElement field = toField(file, fd, true);
oneofs.get(fd.getOneofIndex()).getValue().add(field);
} else {
FieldElement field = toField(file, fd, false);
fields.add(field);
}
}
fields.addAll(proto3OptionalFields);
for (DescriptorProto nestedDesc : descriptor.getNestedTypeList()) {
MessageElement nestedMessage = toMessage(file, nestedDesc);
nested.add(nestedMessage);
}
for (EnumDescriptorProto nestedDesc : descriptor.getEnumTypeList()) {
EnumElement nestedEnum = toEnum(nestedDesc);
nested.add(nestedEnum);
}
for (String reservedName : descriptor.getReservedNameList()) {
ReservedElement reservedElem = new ReservedElement(DEFAULT_LOCATION, "", Collections.singletonList(reservedName));
reserved.add(reservedElem);
}
for (DescriptorProto.ReservedRange reservedRange : descriptor.getReservedRangeList()) {
List<IntRange> values = new ArrayList<>();
int start = reservedRange.getStart();
int end = reservedRange.getEnd() - 1;
values.add(new IntRange(start, end));
ReservedElement reservedElem = new ReservedElement(DEFAULT_LOCATION, "", values);
reserved.add(reservedElem);
}
for (DescriptorProto.ExtensionRange extensionRange : descriptor.getExtensionRangeList()) {
List<IntRange> values = new ArrayList<>();
int start = extensionRange.getStart();
int end = extensionRange.getEnd() - 1;
values.add(new IntRange(start, end));
ExtensionsElement extensionsElement = new ExtensionsElement(DEFAULT_LOCATION, "", values);
extensions.add(extensionsElement);
}
ImmutableList.Builder<OptionElement> options = ImmutableList.builder();
if (descriptor.getOptions().hasMapEntry()) {
OptionElement option = new OptionElement(MAP_ENTRY_OPTION, booleanKind, descriptor.getOptions().getMapEntry(), false);
options.add(option);
}
if (descriptor.getOptions().hasNoStandardDescriptorAccessor()) {
OptionElement option = new OptionElement(NO_STANDARD_DESCRIPTOR_OPTION, booleanKind, descriptor.getOptions().getNoStandardDescriptorAccessor(), false);
options.add(option);
}
return new MessageElement(DEFAULT_LOCATION, name, "", nested.build(), options.build(), reserved.build(), fields.build(), oneofs.stream().filter(e -> e.getValue().build().size() != 0).map(e -> toOneof(e.getKey(), e.getValue())).collect(Collectors.toList()), extensions.build(), Collections.emptyList());
}
use of com.squareup.wire.schema.Options in project schema2proto by entur.
the class ProtoSerializer method updateTypeReferences.
private void updateTypeReferences(String packageNameOfType, String oldName, String newName, MessageType mt, Collection<Field> fields, String currentMessageTypePackage) {
for (Field field : fields) {
if (samePackage(field.packageName(), packageNameOfType)) {
String fieldType = field.getElementType();
if (fieldType.equals(oldName)) {
field.updateElementType(newName);
LOGGER.debug("Updating field {} in type {} to {}", oldName, mt.getName(), newName);
}
}
}
Options options = mt.options();
// Avoid concurrent mod exception
List<OptionElement> listCopy = new ArrayList<>(options.getOptionElements());
listCopy.stream().filter(e -> e.getName().equals(MessageType.XSD_BASE_TYPE_MESSAGE_OPTION_NAME)).forEach(e -> {
String packageAndType = (String) e.getValue();
if (packageAndType.equals(".")) {
String packageName = packageAndType.substring(0, packageAndType.lastIndexOf('.'));
String messageName = packageAndType.substring(packageName.hashCode() + 1);
if (packageName.equals(packageAndType) && oldName.equals(messageName)) {
options.replaceOption(MessageType.XSD_BASE_TYPE_MESSAGE_OPTION_NAME, new OptionElement(MessageType.XSD_BASE_TYPE_MESSAGE_OPTION_NAME, Kind.STRING, packageName + "." + newName, true));
}
} else if (currentMessageTypePackage.equals(packageNameOfType) && packageAndType.equals(oldName)) {
options.replaceOption(MessageType.XSD_BASE_TYPE_MESSAGE_OPTION_NAME, new OptionElement(MessageType.XSD_BASE_TYPE_MESSAGE_OPTION_NAME, Kind.STRING, newName, true));
}
});
}
use of com.squareup.wire.schema.Options in project schema2proto by entur.
the class ProtoSerializer method updateEnum.
private void updateEnum(EnumType e) {
// add UNSPECIFIED value first
List<OptionElement> optionElementsUnspecified = new ArrayList<>();
// Prefix with enum type name
String enumValuePrefix = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, e.name()) + UNDERSCORE;
for (EnumConstant ec : e.constants()) {
String enumValue = escapeEnumValue(ec.getName());
if (enumValue.equalsIgnoreCase("UNSPECIFIED")) {
// Handle collision with UNSPECIFIED special value according to Google style guide
enumValue = "UNSPECIFIED_ENUM_VALUE";
}
ec.updateName(enumValuePrefix + enumValue);
}
EnumConstant unspecified = new EnumConstant(new Location("", "", 0, 0), enumValuePrefix + "UNSPECIFIED", 0, "Default", new Options(Options.ENUM_VALUE_OPTIONS, optionElementsUnspecified));
e.constants().add(0, unspecified);
}
use of com.squareup.wire.schema.Options 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.Options 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