Skip to content
This repository has been archived by the owner on Dec 25, 2024. It is now read-only.

v3 convert nested schemas into sequential schemas #177

Merged
merged 57 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
72ab53e
Writes nested schemas earlier and uses them later
spacether May 29, 2023
139003f
Refactors order CodegenSchema properties are set in to match the orde…
spacether May 31, 2023
8ffdd97
Adjusts ref input to setSchemaLocationInfo
spacether May 31, 2023
3bb45f5
Tweak improves schema template
spacether Jun 1, 2023
b75c129
Adds properties classes
spacether Jun 1, 2023
e499a61
Replaces properties with field
spacether Jun 1, 2023
94c8da6
Uses Schema_()
spacether Jun 1, 2023
be573a1
Uses dataclass properties
spacether Jun 1, 2023
1b23f54
Adds missing type info
spacether Jun 1, 2023
24b21e6
Updates all_of
spacether Jun 1, 2023
6b11b44
Adds any_of, all_of tuples
spacether Jun 1, 2023
9a4bde5
Fixes types definition
spacether Jun 1, 2023
8156a7a
Fixed test_any_type_schema tests
spacether Jun 1, 2023
7a620c8
Fixes dataclass type setting issues
spacether Jun 1, 2023
fcf53e3
Fixes simple schema format type
spacether Jun 1, 2023
fb5fd3d
Adds and uses PatternInfo for pattern schema info, validate_regex cha…
spacether Jun 1, 2023
14cf8b9
Fixes not constraint tests
spacether Jun 1, 2023
23a8a1d
Adds tuple_to_instance
spacether Jun 1, 2023
6a1c104
Writes out allOf/anyOf/oneOf types
spacether Jun 1, 2023
54a176d
Updates classproperty decorator
spacether Jun 2, 2023
c162dec
Adds enum return types
spacether Jun 2, 2023
d7803e1
Fixes type errors in schemas.py
spacether Jun 2, 2023
27f2475
Adds schema singleton metaclass
spacether Jun 2, 2023
0a1064d
Replaces CodegenServer variables with object schema containing variab…
spacether Jun 2, 2023
729944d
Generates server variables as an object schema to keep all schemas at…
spacether Jun 2, 2023
efd5a35
Fixes new signatures in servers schemas
spacether Jun 2, 2023
998762b
Simplifies Server variables definition
spacether Jun 2, 2023
46da2bc
Uses schema default for server variables
spacether Jun 3, 2023
0a744d1
Adds required vars in server definition
spacether Jun 3, 2023
a62f189
Fixes classproperty and SchemaBase classes
spacether Jun 3, 2023
a8aec72
Fixes broken configuration tests
spacether Jun 4, 2023
9416dcf
Fixes server docs
spacether Jun 4, 2023
1a09813
Adds isInlineDefinition
spacether Jun 5, 2023
5cc5c50
Adds allOf/anyOf/oneOf/properties jsonPathPiece
spacether Jun 5, 2023
eadd977
Uses jsonPathPiece in properties/allOf/anyOf/oneOf
spacether Jun 5, 2023
5dc4acf
Fixes properties typeddict name
spacether Jun 5, 2023
826ec84
Templates updated to write allOf/anyOf/oneOf/properties earlier if po…
spacether Jun 5, 2023
895304f
generates properties/allOf/anyOf/oneOf before class if possible
spacether Jun 5, 2023
b1b9389
Adds and uses schemas.INPUT_TYPES_ALL_INCL_SCHEMA
spacether Jun 5, 2023
bf3c818
Adds another usage of schemas.INPUT_TYPES_ALL_INCL_SCHEMA
spacether Jun 5, 2023
81095c1
Changes SchemaBase to SingletonMeta
spacether Jun 5, 2023
86a1b46
Only calculates allSchemas once
spacether Jun 5, 2023
81d20bf
Reduces iteration through allSchemas from 2x to 1x
spacether Jun 5, 2023
73aace1
Removes some getKey invocations
spacether Jun 6, 2023
21a5ae0
Consolidates more getKey usages
spacether Jun 6, 2023
5098218
Deletes getKey with one input
spacether Jun 6, 2023
18d9a29
Adds comment
spacether Jun 6, 2023
a87d6b6
Updates the definition of required properties, reduces the number of …
spacether Jun 6, 2023
ec8c6eb
Updates getKey to use sourceJsonPath
spacether Jun 6, 2023
ab1bca2
Adds class name generation that includes numbered suffixes when needed
spacether Jun 6, 2023
e09212c
Uses pre order traversal for naming schema classes
spacether Jun 6, 2023
f715b21
Fixes oneOf/anyOf/allOf type aliases
spacether Jun 6, 2023
df41b59
Adds and uses schemas.INPUT_BASE_TYPES
spacether Jun 6, 2023
bb9b6d1
Adds string representation of CodegenKey
spacether Jun 6, 2023
810c737
Fixes java tests
spacether Jun 6, 2023
b8287d6
Samples regenerated
spacether Jun 6, 2023
db29328
Samples regenerated
spacether Jun 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public interface CodegenConfig {

CodegenOperation fromOperation(Operation operation, String jsonPath);

CodegenKey getKey(String key);
CodegenKey getKey(String key, String keyType);

CodegenSecurityScheme fromSecurityScheme(SecurityScheme securityScheme, String jsonPath);

Expand All @@ -156,7 +156,7 @@ public interface CodegenConfig {

List<CodegenServer> fromServers(List<Server> servers, String jsonPath);

HashMap<CodegenKey, CodegenSchema> fromServerVariables(Map<String, ServerVariable> variables, String jsonPath);
CodegenSchema fromServerVariables(Map<String, ServerVariable> variables, String jsonPath);

Map<String, String> typeMapping();

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -765,8 +765,13 @@ public String toModuleFilename(String name, String jsonPath) {
return underscore(dropDots(toModelName(name, jsonPath)));
}

/*
This method requires jsonPath to be passed in
It handles responses and schemas
*/
@Override
public String toModelName(String name, String jsonPath) {
boolean rootEntity = (jsonPath != null && jsonPath.endsWith(name));
PairCacheKey key = new PairCacheKey(name, jsonPath);
if (modelNameCache.containsKey(key)) {
return modelNameCache.get(key);
Expand Down Expand Up @@ -809,8 +814,8 @@ public String toModelName(String name, String jsonPath) {
// model name cannot use reserved keyword, e.g. return
if (isReservedWord(camelizedName)) {
String modelName = "_" + camelizedName; // e.g. return => ModelReturn (after camelize)
if (isComponent) {
LOGGER.warn("{} (reserved word) cannot be used as component name. Renamed to {}", camelizedName, modelName);
if (isComponent && rootEntity) {
LOGGER.warn("{} (reserved word) cannot be used as name. Renamed to {}", camelizedName, modelName);
}
modelNameCache.put(key, modelName);
return modelName;
Expand All @@ -820,7 +825,7 @@ public String toModelName(String name, String jsonPath) {
// model name starts with number
if (camelizedName.matches("^\\d.*")) {
String modelName = "_" + camelizedName; // e.g. return => ModelReturn (after camelize)
if (isComponent) {
if (isComponent && rootEntity) {
LOGGER.warn("{} (component name starts with number) cannot be used as name. Renamed to {}", camelizedName, modelName);
}
modelNameCache.put(key, modelName);
Expand Down Expand Up @@ -1356,7 +1361,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
String schemaName = getSchemaName(mm.modelName);
Schema modelSchema = getModelNameToSchemaCache().get(schemaName);
CodegenSchema cp = new CodegenSchema();
cp.jsonPathPiece = getKey(disc.propertyName.original);
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc");
cp.example = discPropNameValue;
return exampleForObjectModel(modelSchema, fullPrefix, closeChars, cp, indentationLevel, exampleLine, closingIndentation, includedSchemas);
}
Expand Down Expand Up @@ -1523,7 +1528,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
String schemaName = getSchemaName(mm.modelName);
Schema modelSchema = getModelNameToSchemaCache().get(schemaName);
CodegenSchema cp = new CodegenSchema();
cp.jsonPathPiece = getKey(disc.propertyName.original);
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc");
cp.example = discPropNameValue;
return exampleForObjectModel(modelSchema, fullPrefix, closeChars, cp, indentationLevel, exampleLine, closingIndentation, includedSchemas);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.openapijsonschematools.codegen.model;

import java.util.ArrayList;

/**
* A class to store inline codegenschema definitions
*/
public class ArrayListWithContext<E> extends ArrayList<E> implements InlineContext {
private boolean internalallAreInline = false;
private CodegenKey internalJsonPathPiece = null;
public boolean allAreInline() {
return internalallAreInline;
}

public void setAllAreInline(boolean allAreInline) {
this.internalallAreInline = allAreInline;
}

public CodegenKey jsonPathPiece() {
return internalJsonPathPiece;
}

public void setJsonPathPiece(CodegenKey jsonPathPiece) {
this.internalJsonPathPiece = jsonPathPiece;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public boolean equals(Object o) {
Objects.equals(anchorPiece, that.anchorPiece);
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("CodegenKey{");
sb.append("original=").append(original);
sb.append(", isValid=").append(isValid);
sb.append(", snakeCase=").append(snakeCase);
sb.append(", camelCase=").append(camelCase);
sb.append(", anchorPiece=").append(anchorPiece);
sb.append('}');
return sb.toString();
}

@Override
public int hashCode() {
return Objects.hash(original, isValid, snakeCase, camelCase, anchorPiece);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import io.swagger.v3.oas.models.ExternalDocumentation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -46,12 +47,12 @@ public class CodegenSchema {
public LinkedHashMap<CodegenKey, CodegenSchema> requiredProperties; // used to store required info
public LinkedHashMap<EnumValue, String> enumValueToName; // enum info
public String type;
public List<CodegenSchema> allOf = null;
public List<CodegenSchema> anyOf = null;
public List<CodegenSchema> oneOf = null;
public ArrayListWithContext<CodegenSchema> allOf = null;
public ArrayListWithContext<CodegenSchema> anyOf = null;
public ArrayListWithContext<CodegenSchema> oneOf = null;
public CodegenSchema not = null;
public CodegenSchema items;
public LinkedHashMap<CodegenKey, CodegenSchema> properties;
public LinkedHashMapWithContext<CodegenKey, CodegenSchema> properties;
public CodegenSchema additionalProperties;
public String description;
public String format;
Expand Down Expand Up @@ -86,6 +87,12 @@ public class CodegenSchema {
public LinkedHashMap<CodegenKey, CodegenSchema> optionalProperties;
public boolean schemaIsFromAdditionalProperties;
public HashMap<String, SchemaTestCase> testCases = new HashMap<>();
/**
* schema/allOfType/anyOfType/oneOfType/propertiesType/importsType
* used in getAllSchemas to write type definitions for allOfType/anyOfType/oneOfType/propertiesType
*/
public String instanceType;
private ArrayList<CodegenSchema> allSchemas = null;

public boolean hasValidation() {
return maxItems != null || minItems != null || minProperties != null || maxProperties != null || minLength != null || maxLength != null || multipleOf != null || patternInfo != null || minimum != null || maximum != null || exclusiveMinimum != null || exclusiveMaximum != null || uniqueItems != null;
Expand Down Expand Up @@ -126,6 +133,118 @@ public CodegenSchema getSelfOrDeepestRef() {
return refObject;
}

/**
* Returns all schemas in post order traversal, used by templates to write schema classes
* @param schemasBeforeImports the input list that stores this and all required schemas
* @return the list that stores this and all required schemas
*/
private void getAllSchemas(ArrayList<CodegenSchema> schemasBeforeImports, ArrayList<CodegenSchema> schemasAfterImports, int level) {
/*
post order traversal using alphabetic json schema keywords as the order
keywords with schemas:
additionalProperties
allOf
anyOf
items
not
oneOf
properties
(self)

excluded:
discriminator (not actually applicable because all values would be refs and do not need to be defined)
$ref (because it is an import)
*/
if (isBooleanSchemaFalse) {
// return early for isBooleanSchemaFalse so not_ will not be written
schemasBeforeImports.add(this);
return;
}
if (additionalProperties != null) {
additionalProperties.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
if (allOf != null) {
for (CodegenSchema someSchema: allOf) {
someSchema.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
CodegenSchema extraSchema = new CodegenSchema();
extraSchema.instanceType = "allOfType";
extraSchema.allOf = allOf;
if (allOf.allAreInline()) {
schemasBeforeImports.add(extraSchema);
} else {
schemasAfterImports.add(extraSchema);
}
}
if (anyOf != null) {
for (CodegenSchema someSchema: anyOf) {
someSchema.getAllSchemas(schemasBeforeImports, schemasAfterImports,level + 1);
}
CodegenSchema extraSchema = new CodegenSchema();
extraSchema.instanceType = "anyOfType";
extraSchema.anyOf = anyOf;
if (anyOf.allAreInline()) {
schemasBeforeImports.add(extraSchema);
} else {
schemasAfterImports.add(extraSchema);
}
}
if (items != null) {
items.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
if (not != null) {
not.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
if (oneOf != null) {
for (CodegenSchema someSchema: oneOf) {
someSchema.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
CodegenSchema extraSchema = new CodegenSchema();
extraSchema.instanceType = "oneOfType";
extraSchema.oneOf = oneOf;
if (oneOf.allAreInline()) {
schemasBeforeImports.add(extraSchema);
} else {
schemasAfterImports.add(extraSchema);
}
}
if (properties != null) {
for (CodegenSchema someSchema: properties.values()) {
someSchema.getAllSchemas(schemasBeforeImports, schemasAfterImports, level + 1);
}
CodegenSchema extraSchema = new CodegenSchema();
extraSchema.instanceType = "propertiesType";
extraSchema.properties = properties;
if (properties.allAreInline()) {
schemasBeforeImports.add(extraSchema);
} else {
schemasAfterImports.add(extraSchema);
}
}
if (refInfo != null && level > 0) {
// do not add ref to schemas
return;
}
schemasBeforeImports.add(this);
if (level == 0 && imports != null && !imports.isEmpty()) {
CodegenSchema extraSchema = new CodegenSchema();
extraSchema.instanceType = "importsType";
extraSchema.imports = imports;
schemasBeforeImports.add(extraSchema);
}
}

public ArrayList<CodegenSchema> getSchemas() {
if (allSchemas == null) {
ArrayList<CodegenSchema> schemasBeforeImports = new ArrayList<>();
ArrayList<CodegenSchema> schemasAfterImports = new ArrayList<>();
getAllSchemas(schemasBeforeImports, schemasAfterImports, 0);
schemasBeforeImports.addAll(schemasAfterImports);
allSchemas = schemasBeforeImports;
}
return allSchemas;
}

public boolean isComplicated() {
// used by templates

Expand All @@ -137,7 +256,7 @@ public boolean isComplicated() {

protected void addInstanceInfo(StringBuilder sb) {
sb.append(", description='").append(description).append('\'');
sb.append(", name='").append(jsonPathPiece).append('\'');
sb.append(", jsonPathPiece='").append(jsonPathPiece).append('\'');
sb.append(", defaultValue='").append(defaultValue).append('\'');
sb.append(", title='").append(title).append('\'');
sb.append(", unescapedDescription='").append(unescapedDescription).append('\'');
Expand Down Expand Up @@ -186,6 +305,7 @@ protected void addInstanceInfo(StringBuilder sb) {
sb.append(", imports=").append(imports);
sb.append(", componentModule=").append(componentModule);
sb.append(", testCases=").append(testCases);
sb.append(", instanceType=").append(instanceType);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ public class CodegenServer {
public final String url;
public final String defaultUrl;
public final String description;
public final LinkedHashMap<CodegenKey, CodegenSchema> variables;
public final CodegenSchema variables;
public final CodegenKey jsonPathPiece;
public final boolean rootServer;

public CodegenServer(String url, String description, LinkedHashMap<CodegenKey, CodegenSchema> variables, CodegenKey jsonPathPiece, boolean rootServer) {
public CodegenServer(String url, String description, CodegenSchema variables, CodegenKey jsonPathPiece, boolean rootServer) {
this.url = url;
this.description = description;
this.variables = variables;
Expand All @@ -21,7 +21,7 @@ public CodegenServer(String url, String description, LinkedHashMap<CodegenKey, C
this.defaultUrl = url;
} else {
String defaultUrl = url;
for (CodegenSchema variable: variables.values()) {
for (CodegenSchema variable: variables.properties.values()) {
defaultUrl = defaultUrl.replace("{" + variable.jsonPathPiece.original + "}", (String) variable.defaultValue.value);
}
this.defaultUrl = defaultUrl;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.openapijsonschematools.codegen.model;

public interface InlineContext {
public boolean allAreInline();

public void setAllAreInline(boolean allAreInline);

public CodegenKey jsonPathPiece();

public void setJsonPathPiece(CodegenKey jsonPathPiece);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.openapijsonschematools.codegen.model;

import java.util.LinkedHashMap;

public class LinkedHashMapWithContext<K, V> extends LinkedHashMap<K, V> implements InlineContext {
private boolean internalallAreInline = false;
private CodegenKey internalJsonPathPiece = null;
public boolean allAreInline() {
return internalallAreInline;
}

public void setAllAreInline(boolean allAreInline) {
this.internalallAreInline = allAreInline;
}

public CodegenKey jsonPathPiece() {
return internalJsonPathPiece;
}

public void setJsonPathPiece(CodegenKey jsonPathPiece) {
this.internalJsonPathPiece = jsonPathPiece;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ None,
bytes,
io.FileIO,
io.BufferedReader,
'Schema',
'Schema',
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{allOf.jsonPathPiece.camelCase}} = typing.Tuple[
{{#each allOf}}
{{#if refInfo.refClass}}
typing.Type[{{#if refInfo.refModule}}{{refInfo.refModule}}.{{/if}}{{refInfo.refClass}}],
{{else}}
typing.Type[{{jsonPathPiece.camelCase}}[schemas.U]],
{{/if}}
{{/each}}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{anyOf.jsonPathPiece.camelCase}} = typing.Tuple[
{{#each anyOf}}
{{#if refInfo.refClass}}
typing.Type[{{#if refInfo.refModule}}{{refInfo.refModule}}.{{/if}}{{refInfo.refClass}}],
{{else}}
typing.Type[{{jsonPathPiece.camelCase}}[schemas.U]],
{{/if}}
{{/each}}
]
Loading