<commit_before>package org.ops4j.ramler.openapi;

import static java.util.stream.Collectors.toList;

import java.util.List;

import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import org.eclipse.microprofile.openapi.models.Paths;
import org.eclipse.microprofile.openapi.models.info.Info;
import org.eclipse.microprofile.openapi.models.media.Schema;
import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType;
import org.ops4j.ramler.common.model.ApiVisitor;
import org.ops4j.ramler.common.model.CommonConstants;
import org.ops4j.ramler.common.model.EnumValue;
import org.raml.v2.api.model.v10.api.Api;
import org.raml.v2.api.model.v10.datamodel.AnyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.ArrayTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.BooleanTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTimeOnlyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTimeTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.IntegerTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.NumberTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.ObjectTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.StringTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.TimeOnlyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.TypeDeclaration;

import io.smallrye.openapi.api.models.ComponentsImpl;
import io.smallrye.openapi.api.models.OpenAPIImpl;
import io.smallrye.openapi.api.models.PathsImpl;
import io.smallrye.openapi.api.models.info.InfoImpl;
import io.smallrye.openapi.api.models.media.SchemaImpl;

/**
 * Generates an OpenAPI specification by visiting a RAML model.
 *
 * @author <NAME>
 *
 */
public class OpenApiCreatingApiVisitor implements ApiVisitor {

    private OpenApiGeneratorContext context;

    private OpenAPI openApi;

    private Components components;

    private Schema objectSchema;

    private boolean generateAny;

    /**
     * Creates a visitor with the given generator context.
     *
     * @param context
     *            generator context
     */
    public OpenApiCreatingApiVisitor(OpenApiGeneratorContext context) {
        this.context = context;
        this.openApi = new OpenAPIImpl();
    }

    public OpenAPI getOpenApi() {
        return openApi;
    }

    @Override
    public void visitApiStart(Api api) {
        openApi.setOpenapi("3.0.2");
        Info info = new InfoImpl();
        info.setTitle(api.title().value());
        String version = (api.version() == null) ? "undefined" : api.version().value();
        info.setVersion(version);
        openApi.setInfo(info);

        Paths paths = new PathsImpl();
        openApi.setPaths(paths);

        components = new ComponentsImpl();
        openApi.setComponents(components);

    }

    @Override
    public void visitApiEnd(Api api) {
        if (generateAny) {
            Schema anySchema = new SchemaImpl();
            anySchema.setTitle("Any");
            anySchema.setDescription("Can be any simple or complex type");
            components.addSchema("Any", anySchema);
        }
    }

    @Override
    public void visitObjectTypeStart(ObjectTypeDeclaration type) {
        if (context.getApiModel().isInternal(type)) {
            return;
        }
        objectSchema = new SchemaImpl();
        components.addSchema(type.name(), objectSchema);
        objectSchema.setTitle(type.name());
        if (type.description() != null) {
            objectSchema.setDescription(type.description().value());
        }
        TypeDeclaration parentType = type.parentTypes().get(0);
        if (parentType.name().equals(CommonConstants.OBJECT)) {
            objectSchema.setType(SchemaType.OBJECT);
        } else {
            Schema base = new SchemaImpl();
            base.setRef(parentType.name());
            objectSchema.addAllOf(base);
            Schema derived = new SchemaImpl();
            derived.setType(SchemaType.OBJECT);
            objectSchema.addAllOf(derived);
            objectSchema = derived;
        }
    }

    @Override
    public void visitObjectTypeEnd(ObjectTypeDeclaration type) {
        objectSchema = null;
    }

    @Override
    public void visitObjectTypeProperty(ObjectTypeDeclaration type, TypeDeclaration property) {
        if (objectSchema == null) {
            return;
        }
        Schema propertySchema = toSchema(property);
        if (property.description() != null) {
            propertySchema.setDescription(property.description().value());
        }

        objectSchema.addProperty(property.name(), propertySchema);
        if (Boolean.TRUE.equals(property.required())) {
            objectSchema.addRequired(property.name());
        }<commit_msg>output discriminator<commit_after>package org.ops4j.ramler.openapi;

import static java.util.stream.Collectors.toList;

import java.util.List;

import org.eclipse.microprofile.openapi.models.Components;
import org.eclipse.microprofile.openapi.models.OpenAPI;
import org.eclipse.microprofile.openapi.models.Paths;
import org.eclipse.microprofile.openapi.models.info.Info;
import org.eclipse.microprofile.openapi.models.media.Discriminator;
import org.eclipse.microprofile.openapi.models.media.Schema;
import org.eclipse.microprofile.openapi.models.media.Schema.SchemaType;
import org.ops4j.ramler.common.model.ApiVisitor;
import org.ops4j.ramler.common.model.CommonConstants;
import org.ops4j.ramler.common.model.EnumValue;
import org.raml.v2.api.model.v10.api.Api;
import org.raml.v2.api.model.v10.datamodel.AnyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.ArrayTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.BooleanTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTimeOnlyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTimeTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.DateTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.IntegerTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.NumberTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.ObjectTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.StringTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.TimeOnlyTypeDeclaration;
import org.raml.v2.api.model.v10.datamodel.TypeDeclaration;

import io.smallrye.openapi.api.models.ComponentsImpl;
import io.smallrye.openapi.api.models.OpenAPIImpl;
import io.smallrye.openapi.api.models.PathsImpl;
import io.smallrye.openapi.api.models.info.InfoImpl;
import io.smallrye.openapi.api.models.media.DiscriminatorImpl;
import io.smallrye.openapi.api.models.media.SchemaImpl;

/**
 * Generates an OpenAPI specification by visiting a RAML model.
 *
 * @author <NAME>
 *
 */
public class OpenApiCreatingApiVisitor implements ApiVisitor {

    private OpenApiGeneratorContext context;

    private OpenAPI openApi;

    private Components components;

    private Schema objectSchema;

    private boolean generateAny;

    /**
     * Creates a visitor with the given generator context.
     *
     * @param context
     *            generator context
     */
    public OpenApiCreatingApiVisitor(OpenApiGeneratorContext context) {
        this.context = context;
        this.openApi = new OpenAPIImpl();
    }

    public OpenAPI getOpenApi() {
        return openApi;
    }

    @Override
    public void visitApiStart(Api api) {
        openApi.setOpenapi("3.0.2");
        Info info = new InfoImpl();
        info.setTitle(api.title().value());
        String version = (api.version() == null) ? "undefined" : api.version().value();
        info.setVersion(version);
        openApi.setInfo(info);

        Paths paths = new PathsImpl();
        openApi.setPaths(paths);

        components = new ComponentsImpl();
        openApi.setComponents(components);

    }

    @Override
    public void visitApiEnd(Api api) {
        if (generateAny) {
            Schema anySchema = new SchemaImpl();
            anySchema.setTitle("Any");
            anySchema.setDescription("Can be any simple or complex type");
            components.addSchema("Any", anySchema);
        }
    }

    @Override
    public void visitObjectTypeStart(ObjectTypeDeclaration type) {
        if (context.getApiModel().isInternal(type)) {
            return;
        }
        objectSchema = new SchemaImpl();
        components.addSchema(type.name(), objectSchema);
        objectSchema.setTitle(type.name());
        if (type.description() != null) {
            objectSchema.setDescription(type.description().value());
        }
        TypeDeclaration parentType = type.parentTypes().get(0);
        if (parentType.name().equals(CommonConstants.OBJECT)) {
            objectSchema.setType(SchemaType.OBJECT);
        } else {
            Schema base = new SchemaImpl();
            base.setRef(parentType.name());
            objectSchema.addAllOf(base);
            Schema derived = new SchemaImpl();
            derived.setType(SchemaType.OBJECT);
            objectSchema.addAllOf(derived);
            objectSchema = derived;
        }

        if (type.discriminator() != null) {
            Discriminator discriminator = new DiscriminatorImpl();
            discriminator.setPropertyName(type.discriminator());
            objectSchema.setDiscriminator(discriminator);
        }
    }

    @Override
    public void visitObjectTypeEnd(ObjectTypeDeclaration type) {
        objectSchema = null;
    }

    @Override
    public void visitObjectTypeProperty(ObjectTypeDeclaration type, TypeDeclaration property) {
        if (objectSchema == null) {
            return;
        }
        Schema propertySchema = toSchema(property);
        if (property.description() != null) {
            propertySchema.setDescription(property.description().value());
        }

        objectSchema.addProperty(property.name(), propertySchema);
        if (Boolean.TRUE.equals(property.required())) {
            objectSchema.addRequired(property.name());
        }
{'fraction_non_alphanumeric': 0.10989010989010989, 'fraction_numerical': 0.009306009306009305, 'mean_word_length': 3.153782894736842, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '380162', 'n_tokens_mistral': 3013, 'n_tokens_neox': 2912, 'n_words': 484}