Skip to content

Commit

Permalink
Resolve conflict and apply project API changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lnash94 committed Aug 22, 2023
1 parent bada06f commit de895aa
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ public enum DiagnosticMessages {
DiagnosticSeverity.WARNING),
OAS_CONVERTOR_114("OAS_CONVERTOR_114", "Generated OpenAPI definition does not contain information " +
"for Ballerina type '%s'. ", DiagnosticSeverity.WARNING),
OAS_CONVERTOR_115("OAS_CONVERTOR_115", "Failed to parser the Number value due to: %s ",
DiagnosticSeverity.ERROR),
"for Ballerina type '%s'. ", DiagnosticSeverity.WARNING),
//todo resolve conflicts
OAS_CONVERTOR_115("OAS_CONVERTOR_115", "Given Ballerina file does not contain any HTTP service.",
DiagnosticSeverity.ERROR),
OAS_CONVERTOR_116("OAS_CONVERTOR_116", "Failed to parser the Number value due to: %s ",
DiagnosticSeverity.ERROR);
//todo resolve conflicts
;

private final String code;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
import io.ballerina.compiler.syntax.tree.NodeVisitor;
import io.ballerina.compiler.syntax.tree.TypeDefinitionNode;

import java.util.LinkedList;
import java.util.List;
import java.util.LinkedHashSet;

/**
* Visitor to get the TypeDefinitionNode and ListenerDeclarationNodes.
Expand All @@ -32,9 +31,10 @@
*/
public class ModuleMemberVisitor extends NodeVisitor {

LinkedList<TypeDefinitionNode> typeDefinitionNodes = new LinkedList<>();
LinkedList<ListenerDeclarationNode> listenerDeclarationNodes = new LinkedList<>();

LinkedHashSet<TypeDefinitionNode> typeDefinitionNodes = new LinkedHashSet<>();
LinkedHashSet<ListenerDeclarationNode> listenerDeclarationNodes = new LinkedHashSet<>();
LinkedHashSet<TypeDefinitionNode> allTypeDefinitionNodes = new LinkedHashSet<>();
LinkedHashSet<ListenerDeclarationNode> allListenerDeclarationNodes = new LinkedHashSet<>();
@Override
public void visit(TypeDefinitionNode typeDefinitionNode) {
typeDefinitionNodes.add(typeDefinitionNode);
Expand All @@ -45,11 +45,27 @@ public void visit(ListenerDeclarationNode listenerDeclarationNode) {
listenerDeclarationNodes.add(listenerDeclarationNode);
}

public List<TypeDefinitionNode> getTypeDefinitionNodes() {
public LinkedHashSet<TypeDefinitionNode> getTypeDefinitionNodes() {
return typeDefinitionNodes;
}

public List<ListenerDeclarationNode> getListenerDeclarationNodes() {
public LinkedHashSet<ListenerDeclarationNode> getListenerDeclarationNodes() {
return listenerDeclarationNodes;
}

public LinkedHashSet<TypeDefinitionNode> getAllTypeDefinitionNodes() {
return allTypeDefinitionNodes;
}

public LinkedHashSet<ListenerDeclarationNode> getAllListenerDeclarationNodes() {
return allListenerDeclarationNodes;
}

public void setAllListenerDeclarationNodes(LinkedHashSet<ListenerDeclarationNode> allListenerDeclarationNodes) {
this.allListenerDeclarationNodes = allListenerDeclarationNodes;
}

public void setAllTypeDefinitionNodes(LinkedHashSet<TypeDefinitionNode> typeDefinitionNodes) {
this.allTypeDefinitionNodes = typeDefinitionNodes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@
import io.ballerina.compiler.api.symbols.UnionTypeSymbol;
import io.ballerina.compiler.syntax.tree.AnnotationNode;
import io.ballerina.compiler.syntax.tree.ExpressionNode;
import io.ballerina.compiler.syntax.tree.IntersectionTypeDescriptorNode;
import io.ballerina.compiler.syntax.tree.MappingConstructorExpressionNode;
import io.ballerina.compiler.syntax.tree.MappingFieldNode;
import io.ballerina.compiler.syntax.tree.MetadataNode;
import io.ballerina.compiler.syntax.tree.ModulePartNode;
import io.ballerina.compiler.syntax.tree.Node;
import io.ballerina.compiler.syntax.tree.NodeList;
import io.ballerina.compiler.syntax.tree.NonTerminalNode;
import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode;
import io.ballerina.compiler.syntax.tree.RecordFieldNode;
import io.ballerina.compiler.syntax.tree.RecordTypeDescriptorNode;
import io.ballerina.compiler.syntax.tree.SpecificFieldNode;
import io.ballerina.compiler.syntax.tree.SyntaxKind;
import io.ballerina.compiler.syntax.tree.TypeDefinitionNode;
Expand All @@ -70,6 +71,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand All @@ -89,14 +91,14 @@
public class OpenAPIComponentMapper {
private final Components components;
private final List<OpenAPIConverterDiagnostic> diagnostics;
private final NonTerminalNode rootNode;
private final HashSet<String> visitedTypeDefinitionNames = new HashSet<>();
private final LinkedHashSet<TypeDefinitionNode> typeDefinitionNodes;


public OpenAPIComponentMapper(Components components, NonTerminalNode rootNode) {
public OpenAPIComponentMapper(Components components, ModuleMemberVisitor moduleMemberVisitor) {
this.components = components;
this.rootNode = rootNode;
this.diagnostics = new ArrayList<>();
this.typeDefinitionNodes = moduleMemberVisitor.getTypeDefinitionNodes();
}

public List<OpenAPIConverterDiagnostic> getDiagnostics() {
Expand Down Expand Up @@ -129,17 +131,18 @@ public void createComponentSchema(Map<String, Schema> schema, TypeSymbol typeSym

//Access module part node for finding the node to given typeSymbol.
//TODO: this works for module reference.
ModulePartNode modulePartNode = rootNode.syntaxTree().rootNode();
NonTerminalNode nonTerminalNode = modulePartNode.findNode(typeSymbol.getLocation().get().textRange());
ConstraintAnnotation.ConstraintAnnotationBuilder constraintBuilder =
new ConstraintAnnotation.ConstraintAnnotationBuilder();
if (nonTerminalNode instanceof TypeDefinitionNode) {
TypeDefinitionNode node = (TypeDefinitionNode) nonTerminalNode;
((TypeReferenceTypeSymbol) typeSymbol).definition().getName().ifPresent(name -> {
for (TypeDefinitionNode typeDefinitionNode : typeDefinitionNodes) {
if (typeDefinitionNode.typeName().text().equals(name)) {
if (typeDefinitionNode.metadata().isPresent()) {
extractedConstraintAnnotation(typeDefinitionNode.metadata().get(), constraintBuilder);
}
}

if (node.metadata().isPresent()) {
extractedConstraintAnnotation(node.metadata().get(), constraintBuilder);
}
}
});
ConstraintAnnotation constraintAnnot = constraintBuilder.build();

switch (type.typeKind()) {
Expand Down Expand Up @@ -366,18 +369,39 @@ private ObjectSchema generateObjectSchemaFromRecordFields(Map<String, Schema> sc
List<String> required = new ArrayList<>();
componentSchema.setDescription(apiDocs.get(componentName));
Map<String, Schema> schemaProperties = new LinkedHashMap<>();
RecordTypeDescriptorNode record = null;
for (TypeDefinitionNode typeDefinitionNode : typeDefinitionNodes) {
if (typeDefinitionNode.typeName().text().equals(componentName)) {
if (typeDefinitionNode.typeDescriptor().kind().equals(SyntaxKind.RECORD_TYPE_DESC)) {
record = (RecordTypeDescriptorNode) typeDefinitionNode.typeDescriptor();
} else if (typeDefinitionNode.typeDescriptor().kind().equals(SyntaxKind.INTERSECTION_TYPE_DESC)) {
IntersectionTypeDescriptorNode intersecNode =
(IntersectionTypeDescriptorNode) typeDefinitionNode.typeDescriptor();
Node leftTypeDesc = intersecNode.leftTypeDesc();
Node rightTypeDesc = intersecNode.rightTypeDesc();
if (leftTypeDesc.kind().equals(SyntaxKind.RECORD_TYPE_DESC)) {
record = (RecordTypeDescriptorNode) leftTypeDesc;
}
if (rightTypeDesc.kind().equals(SyntaxKind.RECORD_TYPE_DESC)) {
record = (RecordTypeDescriptorNode) rightTypeDesc;
}
}
}
}

for (Map.Entry<String, RecordFieldSymbol> field : rfields.entrySet()) {
ConstraintAnnotation.ConstraintAnnotationBuilder constraintBuilder =
new ConstraintAnnotation.ConstraintAnnotationBuilder();

if (!(rootNode instanceof QualifiedNameReferenceNode)) {
ModulePartNode modulePartNode = rootNode.syntaxTree().rootNode();
NonTerminalNode node = modulePartNode.findNode(field.getValue().getLocation().get().textRange());
if (node instanceof RecordFieldNode) {
RecordFieldNode fieldNode = (RecordFieldNode) modulePartNode.
findNode(field.getValue().getLocation().get().textRange());
Optional<MetadataNode> metadata = fieldNode.metadata();
metadata.ifPresent(metadataNode -> extractedConstraintAnnotation(metadataNode, constraintBuilder));
if (record != null) {
for (Node node : record.fields()) {
if (node instanceof RecordFieldNode) {
RecordFieldNode fieldNode = (RecordFieldNode) node;
if (fieldNode.fieldName().toString().equals(field.getKey())) {
Optional<MetadataNode> metadata = fieldNode.metadata();
metadata.ifPresent(metadataNode -> extractedConstraintAnnotation(metadataNode,
constraintBuilder));
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,14 @@ public class OpenAPIHeaderMapper {
private final Components components;
private final SemanticModel semanticModel;
private final Map<String, String> apidocs;
private final ModuleMemberVisitor moduleMemberVisitor;

public OpenAPIHeaderMapper(Components components, SemanticModel semanticModel, Map<String, String> apidocs) {
public OpenAPIHeaderMapper(Components components, SemanticModel semanticModel, Map<String, String> apidocs,
ModuleMemberVisitor moduleMemberVisitor) {
this.apidocs = apidocs;
this.components = components;
this.semanticModel = semanticModel;
this.moduleMemberVisitor = moduleMemberVisitor;
}

/**
Expand All @@ -86,7 +89,7 @@ public List<Parameter> setHeaderParameter(RequiredParameterNode headerParam) {

if (headerDetailNode.kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) {
SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) headerDetailNode;
headerTypeSchema = handleReference(semanticModel, components, refNode);
headerTypeSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor);
} else {
headerTypeSchema = ConverterCommonUtils.getOpenApiSchema(getHeaderType(headerParam));
}
Expand Down Expand Up @@ -126,7 +129,7 @@ public List<Parameter> setHeaderParameter(DefaultableParameterNode headerParam)
Schema<?> headerTypeSchema;
if (headerParam.typeName().kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) {
SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) headerParam.typeName();
headerTypeSchema = handleReference(semanticModel, components, refNode);
headerTypeSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor);
} else {
headerTypeSchema = ConverterCommonUtils.getOpenApiSchema(getHeaderType(headerParam));
}
Expand Down Expand Up @@ -184,7 +187,7 @@ private void completeHeaderParameter(List<Parameter> parameters, String headerNa
Schema<?> itemSchema;
if (kind == SyntaxKind.SIMPLE_NAME_REFERENCE) {
SimpleNameReferenceNode refNode = (SimpleNameReferenceNode) arrayNode.memberTypeDesc();
itemSchema = handleReference(semanticModel, components, refNode);
itemSchema = handleReference(semanticModel, components, refNode, moduleMemberVisitor);
} else {
itemSchema = ConverterCommonUtils.getOpenApiSchema(kind);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import static io.ballerina.openapi.converter.Constants.WILD_CARD_CONTENT_KEY;
import static io.ballerina.openapi.converter.Constants.WILD_CARD_SUMMARY;
import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.extractCustomMediaType;
import static io.ballerina.openapi.converter.utils.ConverterCommonUtils.unescapeIdentifier;

/**
* OpenAPIParameterMapper provides functionality for converting ballerina parameter to OAS parameter model.
Expand All @@ -69,20 +70,23 @@ public class OpenAPIParameterMapper {
private final List<OpenAPIConverterDiagnostic> errors = new ArrayList<>();
private final Components components;
private final SemanticModel semanticModel;
private final ModuleMemberVisitor moduleMemberVisitor;

public List<OpenAPIConverterDiagnostic> getErrors() {
return errors;
}

public OpenAPIParameterMapper(FunctionDefinitionNode functionDefinitionNode,
OperationAdaptor operationAdaptor, Map<String, String> apidocs,
Components components, SemanticModel semanticModel) {
Components components, SemanticModel semanticModel,
ModuleMemberVisitor moduleMemberVisitor) {

this.functionDefinitionNode = functionDefinitionNode;
this.operationAdaptor = operationAdaptor;
this.apidocs = apidocs;
this.components = components;
this.semanticModel = semanticModel;
this.moduleMemberVisitor = moduleMemberVisitor;
}


Expand All @@ -100,7 +104,7 @@ public void getResourceInputs(Components components, SemanticModel semanticModel
SeparatedNodeList<ParameterNode> parameterList = functionSignature.parameters();
for (ParameterNode parameterNode : parameterList) {
OpenAPIQueryParameterMapper queryParameterMapper = new OpenAPIQueryParameterMapper(apidocs, components,
semanticModel);
semanticModel, moduleMemberVisitor);
if (parameterNode.kind() == SyntaxKind.REQUIRED_PARAM) {
RequiredParameterNode requiredParameterNode = (RequiredParameterNode) parameterNode;
// Handle query parameter
Expand Down Expand Up @@ -159,11 +163,14 @@ private void createPathParameters(List<Parameter> parameters, NodeList<Node> pat
ResourcePathParameterNode pathParam = (ResourcePathParameterNode) param;
if (pathParam.typeDescriptor().kind() == SyntaxKind.SIMPLE_NAME_REFERENCE) {
SimpleNameReferenceNode queryNode = (SimpleNameReferenceNode) pathParam.typeDescriptor();
OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, pathParam);
OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components,
moduleMemberVisitor);

// OpenAPIComponentMapper componentMapper = new OpenAPIComponentMapper(components, pathParam);
TypeSymbol typeSymbol = (TypeSymbol) semanticModel.symbol(queryNode).orElseThrow();
componentMapper.createComponentSchema(components.getSchemas(), typeSymbol);
Schema schema = new Schema();
schema.set$ref(ConverterCommonUtils.unescapeIdentifier(queryNode.name().text().trim()));
schema.set$ref(unescapeIdentifier(queryNode.name().text().trim()));
pathParameterOAS.setSchema(schema);
} else {
pathParameterOAS.schema(ConverterCommonUtils.getOpenApiSchema(
Expand Down Expand Up @@ -195,12 +202,13 @@ private void handleAnnotationParameters(Components components,
for (AnnotationNode annotation: annotations) {
if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_HEADER)) {
// Handle headers.
OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs);
OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs,
moduleMemberVisitor);
parameters.addAll(openAPIHeaderMapper.setHeaderParameter(requiredParameterNode));
} else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_QUERY)) {
// Handle query parameter.
OpenAPIQueryParameterMapper openAPIQueryParameterMapper = new OpenAPIQueryParameterMapper(apidocs,
components, semanticModel);
components, semanticModel, moduleMemberVisitor);
parameters.add(openAPIQueryParameterMapper.createQueryParameter(requiredParameterNode));
} else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_PAYLOAD) &&
(!Constants.GET.toLowerCase(Locale.ENGLISH).equalsIgnoreCase(
Expand All @@ -210,8 +218,9 @@ private void handleAnnotationParameters(Components components,
Optional<String> customMediaType = extractCustomMediaType(functionDefinitionNode);
OpenAPIRequestBodyMapper openAPIRequestBodyMapper = customMediaType.map(
value -> new OpenAPIRequestBodyMapper(components,
operationAdaptor, semanticModel, value)).orElse(new OpenAPIRequestBodyMapper(components,
operationAdaptor, semanticModel));
operationAdaptor, semanticModel, value, moduleMemberVisitor)).orElse(
new OpenAPIRequestBodyMapper(components,
operationAdaptor, semanticModel, moduleMemberVisitor));
openAPIRequestBodyMapper.handlePayloadAnnotation(requiredParameterNode, schema, annotation, apidocs);
errors.addAll(openAPIRequestBodyMapper.getDiagnostics());
} else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_PAYLOAD) &&
Expand All @@ -233,12 +242,13 @@ private List<Parameter> handleDefaultableAnnotationParameters(DefaultableParamet
for (AnnotationNode annotation: annotations) {
if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_HEADER)) {
// Handle headers.
OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs);
OpenAPIHeaderMapper openAPIHeaderMapper = new OpenAPIHeaderMapper(components, semanticModel, apidocs,
moduleMemberVisitor);
parameters = openAPIHeaderMapper.setHeaderParameter(defaultableParameterNode);
} else if ((annotation.annotReference().toString()).trim().equals(Constants.HTTP_QUERY)) {
// Handle query parameter.
OpenAPIQueryParameterMapper openAPIQueryParameterMapper = new OpenAPIQueryParameterMapper(apidocs,
components, semanticModel);
components, semanticModel, moduleMemberVisitor);
parameters.add(openAPIQueryParameterMapper.createQueryParameter(defaultableParameterNode));
}
}
Expand Down
Loading

0 comments on commit de895aa

Please sign in to comment.