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

Commit 4b13be5

Browse files
committed
Updates __new__ to take one arg input (#183)
* Adds section for required property type writing * Adds required property classes * Adds template adjustment for optional properties * Adds template to write optional properties typeddict * Successfully generates required and optional typeddicts * Writes DictInput class to store required and optional input properties * Changes new dict inptut type for arg_ and changes args_* to arg_ * Update new signature * Removes unsets from optional properties, allows self in when optionalandreqproperties exist * Typeddicts only generated when addProps is false * Tweaks when reqanoptprops are generated * Adds types to dictchema input * Adds many use cases object inputs * Adds req property mapping writing when addprops set * Adds last required object type definition * Fixes allAreInline for DictInput * Adds optional properties type hint when addProps unset * Adds and uses new partial * Adds mapping type for required + opt + addProps * Writes all property input mapping types * Updates new signature to use DictInput for all object use cases * Updates 3 test files * Fixes more python tests * Fixes manual tests * Fixes python tests * Converts example properties into example keys, fixes schema naming bug * Adds braces aroudn object input * Fixes example addProp key * arg_ -> arg * Schema input configuration_ -> configuration * Removes 'from_openapi_data_' * Fixes java tests * Samples regenerated * Unit test sample updated * Fixes bug with allof/anyOf/oneOf type names * Fixes python non compliant discriminator test
1 parent 9bc1ae1 commit 4b13be5

File tree

620 files changed

+9502
-8950
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

620 files changed

+9502
-8950
lines changed

modules/openapi-json-schema-generator/src/main/java/org/openapijsonschematools/codegen/DefaultCodegen.java

+92-20
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,8 @@ public void processOpts() {
430430
this.setEnumUnknownDefaultCase(Boolean.parseBoolean(additionalProperties
431431
.get(CodegenConstants.ENUM_UNKNOWN_DEFAULT_CASE).toString()));
432432
}
433+
requiredAddPropUnsetSchema = fromSchema(new Schema(), null, null);
434+
433435
}
434436

435437
/***
@@ -1560,7 +1562,7 @@ public String toModelName(final String name, String jsonPath) {
15601562
Map<String, CodegenParameter> codegenParameterCache = new HashMap<>();
15611563
HashMap<String, HashMap<String, Integer>> sourceJsonPathToKeyToQty = new HashMap<>();
15621564
Map<String, CodegenTag> codegenTagCache = new HashMap<>();
1563-
private final CodegenSchema requiredAddPropUnsetSchema = fromSchema(new Schema(), null, null);
1565+
private CodegenSchema requiredAddPropUnsetSchema = null;
15641566

15651567
protected void updateModelForComposedSchema(CodegenSchema m, Schema schema, String sourceJsonPath) {
15661568
final ComposedSchema composed = (ComposedSchema) schema;
@@ -2265,6 +2267,8 @@ public CodegenSchema fromSchema(Schema p, String sourceJsonPath, String currentJ
22652267
setSchemaLocationInfo(null, sourceJsonPath, currentJsonPath, property);
22662268
HashMap<String, CodegenKey> requiredAndOptionalProperties = new HashMap<>();
22672269
property.properties = getProperties(((Schema<?>) p).getProperties(), sourceJsonPath, currentJsonPath, requiredAndOptionalProperties);
2270+
LinkedHashSet<String> required = p.getRequired() == null ? new LinkedHashSet<>()
2271+
: new LinkedHashSet<>(((Schema<?>) p).getRequired());
22682272
List<Schema> oneOfs = ((Schema<?>) p).getOneOf();
22692273
if (oneOfs != null && !oneOfs.isEmpty()) {
22702274
property.oneOf = getComposedProperties(oneOfs, "oneOf", sourceJsonPath, currentJsonPath);
@@ -2286,6 +2290,21 @@ public CodegenSchema fromSchema(Schema p, String sourceJsonPath, String currentJ
22862290
property.allOf = getComposedProperties(allOfs, "allOf", sourceJsonPath, currentJsonPath);
22872291
}
22882292
property.additionalProperties = getAdditionalProperties(p, sourceJsonPath, currentJsonPath);
2293+
// ideally requiredProperties would come before properties
2294+
property.requiredProperties = getRequiredProperties(required, property.properties, property.additionalProperties, requiredAndOptionalProperties, sourceJsonPath, ((Schema<?>) p).getProperties());
2295+
property.optionalProperties = getOptionalProperties(property.properties, required, sourceJsonPath);
2296+
if ((property.types == null || property.types.contains("object")) && sourceJsonPath != null) {
2297+
// only set mapInputJsonPathPiece when object input is possible
2298+
if (property.requiredProperties != null && property.optionalProperties == null) {
2299+
property.mapInputJsonPathPiece = property.requiredProperties.jsonPathPiece();
2300+
} else if (property.requiredProperties == null && property.optionalProperties != null) {
2301+
property.mapInputJsonPathPiece = property.optionalProperties.jsonPathPiece();
2302+
} else if (property.requiredProperties != null && property.optionalProperties != null) {
2303+
property.mapInputJsonPathPiece = getKey("DictInput", "schemaProperty", sourceJsonPath);
2304+
} else {
2305+
property.mapInputJsonPathPiece = getKey("DictInput", "schemaProperty", sourceJsonPath);
2306+
}
2307+
}
22892308
// end of properties that need to be ordered to set correct camelCase jsonPathPieces
22902309

22912310
if (currentJsonPath != null) {
@@ -2352,10 +2371,6 @@ public CodegenSchema fromSchema(Schema p, String sourceJsonPath, String currentJ
23522371
}
23532372
}
23542373
property.patternInfo = getPatternInfo(p.getPattern());
2355-
LinkedHashSet<String> required = p.getRequired() == null ? new LinkedHashSet<>()
2356-
: new LinkedHashSet<>(((Schema<?>) p).getRequired());
2357-
property.optionalProperties = getOptionalProperties(property.properties, required);
2358-
property.requiredProperties = getRequiredProperties(required, property.properties, property.additionalProperties, requiredAndOptionalProperties);
23592374

23602375
property.example = toExampleValue(p);
23612376
if (addSchemaImportsFromV3SpecLocations && sourceJsonPath != null && sourceJsonPath.equals(currentJsonPath)) {
@@ -3295,26 +3310,41 @@ protected LinkedHashMapWithContext<CodegenKey, CodegenSchema> getProperties(Map<
32953310
* @param required a set of required properties' name
32963311
* @return the optional properties
32973312
*/
3298-
protected LinkedHashMap<CodegenKey, CodegenSchema> getOptionalProperties(LinkedHashMap<CodegenKey, CodegenSchema> properties, Set<String> required) {
3313+
protected LinkedHashMapWithContext<CodegenKey, CodegenSchema> getOptionalProperties(LinkedHashMapWithContext<CodegenKey, CodegenSchema> properties, Set<String> required, String sourceJsonPath) {
32993314
if (properties == null) {
33003315
return null;
33013316
}
3302-
if (required.size() == properties.size()) {
3303-
return null;
3304-
}
33053317
if (required.isEmpty()) {
3306-
return properties;
3318+
// all properties optional and there is no required
3319+
LinkedHashMapWithContext<CodegenKey, CodegenSchema> optionalProperties = new LinkedHashMapWithContext<>();
3320+
optionalProperties.putAll(properties);
3321+
optionalProperties.setAllAreInline(properties.allAreInline());
3322+
CodegenKey jsonPathPiece = getKey("DictInput", "schemaProperty", sourceJsonPath);
3323+
optionalProperties.setJsonPathPiece(jsonPathPiece);
3324+
return optionalProperties;
33073325
}
33083326

3309-
LinkedHashMap<CodegenKey, CodegenSchema> optionalProperties = new LinkedHashMap<>();
3327+
// required exists and it can come from addProps or props
3328+
LinkedHashMapWithContext<CodegenKey, CodegenSchema> optionalProperties = new LinkedHashMapWithContext<>();
3329+
boolean allAreInline = true;
33103330
for (Map.Entry<CodegenKey, CodegenSchema> entry : properties.entrySet()) {
33113331
final CodegenKey key = entry.getKey();
33123332
if (required.contains(key.original)) {
33133333
continue;
33143334
}
33153335
final CodegenSchema prop = entry.getValue();
3336+
if (prop.refInfo != null) {
3337+
allAreInline = false;
3338+
}
33163339
optionalProperties.put(key, prop);
33173340
}
3341+
if (optionalProperties.isEmpty()) {
3342+
// no optional props, all required properties came from props
3343+
return null;
3344+
}
3345+
optionalProperties.setAllAreInline(allAreInline);
3346+
CodegenKey jsonPathPiece = getKey("OptionalDictInput", "schemaProperty", sourceJsonPath);
3347+
optionalProperties.setJsonPathPiece(jsonPathPiece);
33183348
return optionalProperties;
33193349
}
33203350

@@ -4280,8 +4310,8 @@ public CodegenRequestBody fromRequestBody(RequestBody requestBody, String source
42804310
}
42814311

42824312
@Override
4283-
public CodegenKey getKey(String key, String expectedComponentType) {
4284-
return getKey(key, expectedComponentType, null);
4313+
public CodegenKey getKey(String key, String keyType) {
4314+
return getKey(key, keyType, null);
42854315
}
42864316

42874317
public CodegenKey getKey(String key, String keyType, String sourceJsonPath) {
@@ -4299,9 +4329,13 @@ public CodegenKey getKey(String key, String keyType, String sourceJsonPath) {
42994329
if (!sourceJsonPathToKeyToQty.containsKey(sourceJsonPath)) {
43004330
sourceJsonPathToKeyToQty.put(sourceJsonPath, keyToQty);
43014331
}
4302-
Integer qty = keyToQty.getOrDefault(usedKey, 0);
4332+
/*
4333+
saw use case with component named Client and nested property named client
4334+
lowercase to ensure they increment the same key
4335+
*/
4336+
Integer qty = keyToQty.getOrDefault(usedKey.toLowerCase(Locale.ROOT), 0);
43034337
qty += 1;
4304-
keyToQty.put(usedKey, qty);
4338+
keyToQty.put(usedKey.toLowerCase(Locale.ROOT), qty);
43054339
if (qty > 1) {
43064340
suffix = qty.toString();
43074341
}
@@ -4352,38 +4386,61 @@ public CodegenKey getKey(String key, String keyType, String sourceJsonPath) {
43524386
);
43534387
}
43544388

4355-
protected LinkedHashMap<CodegenKey, CodegenSchema> getRequiredProperties(LinkedHashSet<String> required, LinkedHashMap<CodegenKey, CodegenSchema> properties, CodegenSchema additionalProperties, HashMap<String, CodegenKey> requiredAndOptionalProperties) {
4389+
protected LinkedHashMapWithContext<CodegenKey, CodegenSchema> getRequiredProperties(LinkedHashSet<String> required, LinkedHashMap<CodegenKey, CodegenSchema> properties, CodegenSchema additionalProperties, HashMap<String, CodegenKey> requiredAndOptionalProperties, String sourceJsonPath, Map<String, Schema> schemaProperties) {
43564390
if (required.isEmpty()) {
43574391
return null;
43584392
}
43594393
/*
4394+
requiredProperties use cases:
4395+
- no required properties: null or empty list
4396+
- requiredProperties + optionalProperties (properties must exist)
4397+
- requiredProperties + no optionalProperties
4398+
- 1. requiredPropsWithDefAllFromProp - required all come from properties
4399+
- 2. requiredPropsWithDefAllFromAddProp - required all come from addProp and there is no properties
4400+
- 3. required consume all properties and remainder from addProps
43604401
this should be called after vars and additionalProperties are set
43614402
Features added by storing codegenProperty values:
43624403
- refClass stores reference to additionalProperties definition
43634404
- baseName stores original name (can be invalid in a programming language)
43644405
- nameInSnakeCase can store valid name for a programming language
43654406
*/
4366-
LinkedHashMap<CodegenKey, CodegenSchema> requiredProperties = new LinkedHashMap<>();
4407+
boolean requiredPropsWithDefAllFromProp = true;
4408+
boolean requiredPropsWithDefAllFromAddProp = true;
4409+
int propReqProps = 0;
4410+
int addPropReqProps = 0;
4411+
int reqPropsWithDef = 0;
4412+
LinkedHashMapWithContext<CodegenKey, CodegenSchema> requiredProperties = new LinkedHashMapWithContext<>();
4413+
boolean allAreInline = true;
43674414
for (String requiredPropertyName: required) {
43684415
// required property is defined in properties, value is that CodegenSchema
43694416
if (properties != null && requiredAndOptionalProperties.containsKey(requiredPropertyName)) {
43704417
CodegenKey key = requiredAndOptionalProperties.get(requiredPropertyName);
43714418
// get cp from property
43724419
CodegenSchema prop = properties.get(key);
43734420
if (prop != null) {
4421+
requiredPropsWithDefAllFromAddProp = false;
43744422
requiredProperties.put(key, prop);
4423+
reqPropsWithDef++;
4424+
propReqProps++;
4425+
if (prop.refInfo != null) {
4426+
allAreInline = false;
4427+
}
43754428
} else {
43764429
throw new RuntimeException("Property " + requiredPropertyName + " is missing from getVars");
43774430
}
43784431
} else if (additionalProperties != null && additionalProperties.isBooleanSchemaFalse) {
43794432
// required property is not defined in properties, and additionalProperties is false, value is null
4380-
CodegenKey key = getKey(requiredPropertyName, "schemas");
4433+
// no schema definition: error use case?
4434+
CodegenKey key = getKey(requiredPropertyName, "schemas", null);
43814435
requiredProperties.put(key, null);
43824436
requiredAndOptionalProperties.put(requiredPropertyName, key);
43834437
} else {
43844438
// required property is not defined in properties
43854439
if (supportsAdditionalPropertiesWithComposedSchema && !disallowAdditionalPropertiesIfNotPresent) {
43864440
CodegenSchema prop;
4441+
requiredPropsWithDefAllFromProp = false;
4442+
reqPropsWithDef++;
4443+
addPropReqProps++;
43874444
if (additionalProperties == null) {
43884445
// additionalProperties is null
43894446
// there is NO schema definition for this so the json paths are null
@@ -4394,13 +4451,28 @@ protected LinkedHashMap<CodegenKey, CodegenSchema> getRequiredProperties(LinkedH
43944451
} else {
43954452
// additionalProperties is schema
43964453
prop = additionalProperties;
4454+
if (prop.refInfo != null) {
4455+
allAreInline = false;
4456+
}
43974457
}
4398-
CodegenKey key = getKey(requiredPropertyName, "schemas");
4458+
CodegenKey key = getKey(requiredPropertyName, "schemas", sourceJsonPath);
43994459
requiredProperties.put(key, prop);
44004460
requiredAndOptionalProperties.put(requiredPropertyName, key);
44014461
}
44024462
}
44034463
}
4464+
String keyName;
4465+
boolean onlyReqPropsCase1 = (requiredPropsWithDefAllFromProp && properties != null && requiredProperties.size() == properties.size());
4466+
boolean onlyReqPropsCase2 = (requiredPropsWithDefAllFromAddProp && properties == null);
4467+
boolean onlyReqPropsCase3 = (propReqProps != 0 && addPropReqProps != 0 && propReqProps + addPropReqProps == reqPropsWithDef && schemaProperties != null && required.containsAll(schemaProperties.keySet()));
4468+
if (onlyReqPropsCase1 || onlyReqPropsCase2 || onlyReqPropsCase3) {
4469+
keyName = "DictInput";
4470+
} else {
4471+
keyName = "RequiredDictInput";
4472+
}
4473+
requiredProperties.setAllAreInline(allAreInline);
4474+
CodegenKey jsonPathPiece = getKey(keyName, "schemaProperty", sourceJsonPath);
4475+
requiredProperties.setJsonPathPiece(jsonPathPiece);
44044476
return requiredProperties;
44054477
}
44064478

@@ -4783,7 +4855,7 @@ private ArrayListWithContext<CodegenSchema> getComposedProperties(List<Schema> x
47834855
i += 1;
47844856
}
47854857
xOf.setAllAreInline(allAreInline);
4786-
CodegenKey jsonPathPiece = getKey(collectionName, "schemaProperty");
4858+
CodegenKey jsonPathPiece = getKey(collectionName, "schemaProperty", sourceJsonPath);
47874859
xOf.setJsonPathPiece(jsonPathPiece);
47884860
return xOf;
47894861
}

modules/openapi-json-schema-generator/src/main/java/org/openapijsonschematools/codegen/languages/PythonClientCodegen.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,10 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
12851285
if (modelName != null) {
12861286
openChars = modelName + "(";
12871287
closeChars = ")";
1288+
if (ModelUtils.isTypeObjectSchema(schema)) {
1289+
openChars = openChars + "{";
1290+
closeChars = "}" + closeChars;
1291+
}
12881292
}
12891293

12901294
String fullPrefix = currentIndentation + prefix + openChars;
@@ -1361,7 +1365,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
13611365
String schemaName = getSchemaName(mm.modelName);
13621366
Schema modelSchema = getModelNameToSchemaCache().get(schemaName);
13631367
CodegenSchema cp = new CodegenSchema();
1364-
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc");
1368+
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc", null);
13651369
cp.example = discPropNameValue;
13661370
return exampleForObjectModel(modelSchema, fullPrefix, closeChars, cp, indentationLevel, exampleLine, closingIndentation, includedSchemas);
13671371
}
@@ -1483,8 +1487,8 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
14831487
}
14841488
} else if (ModelUtils.isTypeObjectSchema(schema)) {
14851489
if (modelName == null) {
1486-
fullPrefix += "dict(";
1487-
closeChars = ")";
1490+
fullPrefix += "{";
1491+
closeChars = "}";
14881492
}
14891493
if (cycleFound) {
14901494
return fullPrefix + closeChars;
@@ -1528,7 +1532,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
15281532
String schemaName = getSchemaName(mm.modelName);
15291533
Schema modelSchema = getModelNameToSchemaCache().get(schemaName);
15301534
CodegenSchema cp = new CodegenSchema();
1531-
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc");
1535+
cp.jsonPathPiece = getKey(disc.propertyName.original, "misc", null);
15321536
cp.example = discPropNameValue;
15331537
return exampleForObjectModel(modelSchema, fullPrefix, closeChars, cp, indentationLevel, exampleLine, closingIndentation, includedSchemas);
15341538
}
@@ -1544,10 +1548,7 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
15441548
key = addPropsSchema.getEnum().get(0).toString();
15451549
}
15461550
addPropsExample = exampleFromStringOrArraySchema(addPropsSchema, addPropsExample, key);
1547-
String addPropPrefix = key + "=";
1548-
if (modelName == null) {
1549-
addPropPrefix = ensureQuotes(key) + ": ";
1550-
}
1551+
String addPropPrefix = ensureQuotes(key) + ": ";
15511552
String addPropsModelName = getRefClassWithRefModule(addPropsSchema);
15521553
if(includedSchemas.contains(schema)) {
15531554
return "";
@@ -1602,7 +1603,7 @@ private String exampleForObjectModel(Schema schema, String fullPrefix, String cl
16021603
propSchema,
16031604
propExample,
16041605
indentationLevel + 1,
1605-
propName + "=",
1606+
"\"" + propName + "\": ",
16061607
exampleLine + 1,
16071608
includedSchemas)).append(",\n");
16081609
}

0 commit comments

Comments
 (0)