Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport main] Add support for codegen overrides #1185

Merged
merged 2 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.opensearch.client.codegen.model.OperationGroupMatcher;
import org.opensearch.client.codegen.model.ShapeRenderingContext;
import org.opensearch.client.codegen.model.SpecTransformer;
import org.opensearch.client.codegen.model.overrides.Overrides;
import org.opensearch.client.codegen.openapi.OpenApiSpecification;

public class CodeGenerator {
Expand Down Expand Up @@ -121,7 +122,7 @@ public static void main(String[] args) {

private static Namespace parseSpec(URI location) throws ApiSpecificationParseException {
var spec = OpenApiSpecification.retrieve(location);
var transformer = new SpecTransformer(OPERATION_MATCHER);
var transformer = new SpecTransformer(OPERATION_MATCHER, Overrides.OVERRIDES);
transformer.visit(spec);
return transformer.getRoot();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ public static final class Builder extends ObjectBuilderBase<ShapeRenderingContex
private JavaCodeFormatter javaCodeFormatter;
private boolean ownedJavaCodeFormatter;

private Builder() {
super(ShapeRenderingContext::new);
}
private Builder() {}

@Nonnull
@Override
protected @Nonnull Builder self() {
return this;
protected ShapeRenderingContext construct() {
return new ShapeRenderingContext(this);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.apache.commons.lang3.NotImplementedException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.client.codegen.model.overrides.Overrides;
import org.opensearch.client.codegen.model.overrides.PropertyOverride;
import org.opensearch.client.codegen.openapi.HttpStatusCode;
import org.opensearch.client.codegen.openapi.In;
import org.opensearch.client.codegen.openapi.JsonPointer;
Expand All @@ -48,14 +50,17 @@ public class SpecTransformer {
@Nonnull
private final OperationGroupMatcher matcher;
@Nonnull
private final Overrides overrides;
@Nonnull
private final Namespace root = new Namespace();
@Nonnull
private final Set<OpenApiSchema> visitedSchemas = new HashSet<>();
@Nonnull
private final Map<OpenApiSchema, Type> schemaToType = new ConcurrentHashMap<>();

public SpecTransformer(@Nonnull OperationGroupMatcher matcher) {
public SpecTransformer(@Nonnull OperationGroupMatcher matcher, @Nonnull Overrides overrides) {
this.matcher = Objects.requireNonNull(matcher, "matcher must not be null");
this.overrides = Objects.requireNonNull(overrides, "overrides must not be null");
}

@Nonnull
Expand Down Expand Up @@ -285,9 +290,12 @@ private void visitInto(OpenApiSchema schema, ObjectShape shape) {
final var additionalProperties = new ArrayList<OpenApiSchema>();
final var required = collectObjectProperties(schema, properties, additionalProperties);

properties.forEach(
(k, v) -> shape.addBodyField(new Field(k, mapType(v), required.contains(k), v.getDescription().orElse(null), null))
);
final var overrides = this.overrides.getSchema(schema.getPointer());

properties.forEach((k, v) -> {
var type = overrides.flatMap(so -> so.getProperty(k)).flatMap(PropertyOverride::getMappedType).orElseGet(() -> mapType(v));
shape.addBodyField(new Field(k, type, required.contains(k), v.getDescription().orElse(null), null));
});

if (!additionalProperties.isEmpty()) {
var valueSchema = additionalProperties.size() == 1 ? additionalProperties.get(0) : OpenApiSchema.ANONYMOUS_UNTYPED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public class Type {
"float",
"Float",
"double",
"Double"
"Double",
"Number"
);

public static Builder builder() {
Expand Down Expand Up @@ -148,6 +149,10 @@ public boolean isPrimitive() {
return PRIMITIVES.contains(name);
}

public boolean isNumber() {
return "Number".equals(name);
}

public boolean isEnum() {
return isEnum;
}
Expand Down Expand Up @@ -218,13 +223,12 @@ public static final class Builder extends ObjectBuilderBase<Type, Builder> {
private Type[] typeParams;
private boolean isEnum;

private Builder() {
super(Type::new);
}
private Builder() {}

@Nonnull
@Override
protected @Nonnull Builder self() {
return this;
protected Type construct() {
return new Type(this);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ public static final class Builder extends ObjectBuilderBase<TypeParameterDefinit
private String name;
private Type extendsType;

private Builder() {
super(TypeParameterDefinition::new);
}
private Builder() {}

@Nonnull
@Override
protected @Nonnull Builder self() {
return this;
protected TypeParameterDefinition construct() {
return new TypeParameterDefinition(this);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ public static Builder builder() {
public static class Builder extends ObjectBuilderBase<TypeParameterDiamond, Builder> {
private Either<Type[], TypeParameterDefinition[]> params;

private Builder() {
super(TypeParameterDiamond::new);
}
private Builder() {}

@Nonnull
@Override
protected @Nonnull Builder self() {
return this;
protected TypeParameterDiamond construct() {
return new TypeParameterDiamond(this);
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public static final class Lang {
public static final Type Float = Type.builder().withPackage(PACKAGE).withName("Float").build();
public static final Type Double = Type.builder().withPackage(PACKAGE).withName("Double").build();
public static final Type Object = Type.builder().withPackage(PACKAGE).withName("Object").build();
public static final Type Number = Type.builder().withPackage(PACKAGE).withName("Number").build();
}

public static final class Util {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.codegen.model.overrides;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensearch.client.codegen.openapi.JsonPointer;
import org.opensearch.client.codegen.utils.ObjectBuilder;
import org.opensearch.client.codegen.utils.ObjectBuilderBase;

public class Overrides {
public static final Overrides OVERRIDES = builder().build();

@Nonnull
private final Map<JsonPointer, SchemaOverride> schemas;

private Overrides(Builder builder) {
this.schemas = builder.schemas != null ? Collections.unmodifiableMap(builder.schemas) : Collections.emptyMap();
}

@Nonnull
public Optional<SchemaOverride> getSchema(@Nonnull JsonPointer pointer) {
return Optional.ofNullable(schemas.get(pointer));
}

@Nonnull
public static Builder builder() {
return new Builder();
}

public static final class Builder extends ObjectBuilderBase<Overrides, Builder> {
@Nullable
private Map<JsonPointer, SchemaOverride> schemas;

private Builder() {}

@Nonnull
@Override
protected Overrides construct() {
return new Overrides(this);
}

@Nonnull
public Builder withSchemas(@Nonnull Function<SchemaOverride.MapBuilder, ObjectBuilder<Map<JsonPointer, SchemaOverride>>> fn) {
this.schemas = Objects.requireNonNull(fn, "fn must not be null").apply(SchemaOverride.mapBuilder()).build();
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.codegen.model.overrides;

import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensearch.client.codegen.model.Type;
import org.opensearch.client.codegen.utils.MapBuilderBase;
import org.opensearch.client.codegen.utils.ObjectBuilderBase;

public final class PropertyOverride {
@Nullable
private final Type mappedType;

private PropertyOverride(Builder builder) {
this.mappedType = builder.mappedType;
}

@Nonnull
public Optional<Type> getMappedType() {
return Optional.ofNullable(mappedType);
}

@Nonnull
public static Builder builder() {
return new Builder();
}

@Nonnull
public static MapBuilder mapBuilder() {
return new MapBuilder();
}

public static final class Builder extends ObjectBuilderBase<PropertyOverride, Builder> {
@Nullable
private Type mappedType;

private Builder() {}

@Nonnull
@Override
protected PropertyOverride construct() {
return new PropertyOverride(this);
}

@Nonnull
public Builder withMappedType(@Nullable Type mappedType) {
this.mappedType = mappedType;
return this;
}
}

public static final class MapBuilder extends MapBuilderBase<String, PropertyOverride, Builder, MapBuilder> {
private MapBuilder() {}

@Nonnull
@Override
protected Builder valueBuilder() {
return builder();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.client.codegen.model.overrides;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opensearch.client.codegen.openapi.JsonPointer;
import org.opensearch.client.codegen.utils.MapBuilderBase;
import org.opensearch.client.codegen.utils.ObjectBuilder;
import org.opensearch.client.codegen.utils.ObjectBuilderBase;

public final class SchemaOverride {
@Nonnull
private final Map<String, PropertyOverride> properties;

private SchemaOverride(Builder builder) {
this.properties = builder.properties != null ? Collections.unmodifiableMap(builder.properties) : Collections.emptyMap();
}

@Nonnull
public Optional<PropertyOverride> getProperty(@Nonnull String key) {
return Optional.ofNullable(properties.get(key));
}

@Nonnull
public static Builder builder() {
return new Builder();
}

@Nonnull
public static MapBuilder mapBuilder() {
return new MapBuilder();
}

public static final class Builder extends ObjectBuilderBase<SchemaOverride, Builder> {
@Nullable
private Map<String, PropertyOverride> properties;

private Builder() {}

@Nonnull
@Override
protected SchemaOverride construct() {
return new SchemaOverride(this);
}

@Nonnull
public Builder withProperties(@Nonnull Function<PropertyOverride.MapBuilder, ObjectBuilder<Map<String, PropertyOverride>>> fn) {
this.properties = Objects.requireNonNull(fn, "fn must not be null").apply(PropertyOverride.mapBuilder()).build();
return this;
}
}

public static final class MapBuilder extends MapBuilderBase<JsonPointer, SchemaOverride, Builder, MapBuilder> {
private MapBuilder() {}

@Nonnull
@Override
protected Builder valueBuilder() {
return builder();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,12 @@ public static class Builder extends ObjectBuilderBase<OpenApiSchema, Builder> {
@Nullable
private Semver versionRemoved;

private Builder() {
super(OpenApiSchema::new);
}
private Builder() {}

@Nonnull
@Override
protected @Nonnull Builder self() {
return this;
protected OpenApiSchema construct() {
return new OpenApiSchema(this);
}

@Nonnull
Expand Down
Loading
Loading