Skip to content

Commit

Permalink
http-client-java, use wire type for unknown encode (#6244)
Browse files Browse the repository at this point in the history
user can put any value in `@encode` decorator and apparently emitter
cannot support all of them.
```
@encode("whatever-user-wanted")
prop: duration;
```

Hence fallback to wire type, with a warning.
  • Loading branch information
weidongxu-microsoft authored Mar 4, 2025
1 parent 41efd5f commit d4d5c3d
Showing 8 changed files with 173 additions and 7 deletions.
40 changes: 35 additions & 5 deletions packages/http-client-java/emitter/src/code-model-builder.ts
Original file line number Diff line number Diff line change
@@ -128,6 +128,9 @@ import {
operationIsMultipleContentTypes,
} from "./operation-utils.js";
import {
BYTES_KNOWN_ENCODING,
DATETIME_KNOWN_ENCODING,
DURATION_KNOWN_ENCODING,
ProcessingCache,
getAccess,
getDurationFormat,
@@ -2054,17 +2057,35 @@ export class CodeModelBuilder {
return this.processArraySchema(type, nameHint);

case "duration":
return this.processDurationSchema(type, nameHint, getDurationFormat(type));
if (DURATION_KNOWN_ENCODING.includes(type.encode)) {
return this.processDurationSchema(type, nameHint, getDurationFormat(type));
} else {
reportDiagnostic(this.program, {
code: "unknown-encode",
format: { encode: type.encode },
target: type.__raw ?? NoTarget,
});
return this.processBuiltInType(type.wireType, nameHint);
}

case "constant":
return this.processConstantSchema(type, nameHint);

case "utcDateTime":
case "offsetDateTime":
if (type.encode === "unixTimestamp") {
return this.processUnixTimeSchema(type, nameHint);
if (DATETIME_KNOWN_ENCODING.includes(type.encode)) {
if (type.encode === "unixTimestamp") {
return this.processUnixTimeSchema(type, nameHint);
} else {
return this.processDateTimeSchema(type, nameHint, type.encode === "rfc7231");
}
} else {
return this.processDateTimeSchema(type, nameHint, type.encode === "rfc7231");
reportDiagnostic(this.program, {
code: "unknown-encode",
format: { encode: type.encode },
target: type.__raw ?? NoTarget,
});
return this.processBuiltInType(type.wireType, nameHint);
}
}
}
@@ -2100,7 +2121,16 @@ export class CodeModelBuilder {
return this.processDecimalSchema(type, nameHint);

case "bytes":
return this.processByteArraySchema(type, nameHint);
if (!type.encode || BYTES_KNOWN_ENCODING.includes(type.encode)) {
return this.processByteArraySchema(type, nameHint);
} else {
reportDiagnostic(this.program, {
code: "unknown-encode",
format: { encode: type.encode },
target: type.__raw ?? NoTarget,
});
return this.processStringSchema(type, nameHint);
}

case "boolean":
return this.processBooleanSchema(type, nameHint);
6 changes: 6 additions & 0 deletions packages/http-client-java/emitter/src/lib.ts
Original file line number Diff line number Diff line change
@@ -166,6 +166,12 @@ export const $lib = createTypeSpecLibrary({
default: paramMessage`Header parameter format '${"format"}' is not supported.`,
},
},
"unknown-encode": {
severity: "warning",
messages: {
default: paramMessage`Encode '${"encode"}' is not supported.`,
},
},
},
emitter: {
options: EmitterOptionsSchema as JSONSchemaType<EmitterOptions>,
8 changes: 6 additions & 2 deletions packages/http-client-java/emitter/src/type-utils.ts
Original file line number Diff line number Diff line change
@@ -32,6 +32,10 @@ import { DurationSchema } from "./common/schemas/time.js";
import { SchemaContext } from "./common/schemas/usage.js";
import { getNamespace } from "./utils.js";

export const DURATION_KNOWN_ENCODING = ["ISO8601", "seconds"];
export const DATETIME_KNOWN_ENCODING = ["rfc3339", "rfc7231", "unixTimestamp"];
export const BYTES_KNOWN_ENCODING = ["base64", "base64url"];

/** Acts as a cache for processing inputs.
*
* If the input is undefined, the output is always undefined.
@@ -342,11 +346,11 @@ export function isArmCommonType(entity: Type): boolean {
}

export function getPropertySerializedName(property: SdkBodyModelPropertyType): string {
// TODO: remove the "property.serializedName" after bug https://github.com/microsoft/typespec/pull/5702 is fixed
// still fallback to "property.name", as for orphan model, serializationOptions.json is undefined
return (
property.serializationOptions.json?.name ??
property.serializationOptions.multipart?.name ??
property.serializedName
property.name
);
}

Original file line number Diff line number Diff line change
@@ -94,6 +94,9 @@ public final class BuiltinAsyncClient {
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
@@ -152,6 +155,9 @@ public Mono<Response<BinaryData>> readWithResponse(String queryParam, String que
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
Original file line number Diff line number Diff line change
@@ -92,6 +92,9 @@ public final class BuiltinClient {
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
@@ -150,6 +153,9 @@ public Response<BinaryData> readWithResponse(String queryParam, String queryPara
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
Original file line number Diff line number Diff line change
@@ -154,6 +154,9 @@ Response<Void> writeSync(@HostParam("endpoint") String endpoint,
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
@@ -229,6 +232,9 @@ public Mono<Response<BinaryData>> readWithResponseAsync(String queryParam, Strin
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
@@ -288,6 +294,9 @@ public Response<BinaryData> readWithResponse(String queryParam, String queryPara
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
@@ -345,6 +354,9 @@ public Mono<Response<Void>> writeWithResponseAsync(BinaryData body, RequestOptio
* unixTimestamp: Long (Optional)
* base64: byte[] (Optional)
* base64url: Base64Url (Optional)
* unknownDurationFormat: String (Optional)
* unknownDateTimeFormat: String (Optional)
* unknownBytes: String (Optional)
* }
* }
* }
Original file line number Diff line number Diff line change
@@ -68,6 +68,24 @@ public final class Encoded implements JsonSerializable<Encoded> {
@Generated
private Base64Url base64url;

/*
* The unknownDurationFormat property.
*/
@Generated
private String unknownDurationFormat;

/*
* The unknownDateTimeFormat property.
*/
@Generated
private String unknownDateTimeFormat;

/*
* The unknownBytes property.
*/
@Generated
private String unknownBytes;

/**
* Creates an instance of Encoded class.
*/
@@ -264,6 +282,72 @@ public Encoded setBase64url(byte[] base64url) {
return this;
}

/**
* Get the unknownDurationFormat property: The unknownDurationFormat property.
*
* @return the unknownDurationFormat value.
*/
@Generated
public String getUnknownDurationFormat() {
return this.unknownDurationFormat;
}

/**
* Set the unknownDurationFormat property: The unknownDurationFormat property.
*
* @param unknownDurationFormat the unknownDurationFormat value to set.
* @return the Encoded object itself.
*/
@Generated
public Encoded setUnknownDurationFormat(String unknownDurationFormat) {
this.unknownDurationFormat = unknownDurationFormat;
return this;
}

/**
* Get the unknownDateTimeFormat property: The unknownDateTimeFormat property.
*
* @return the unknownDateTimeFormat value.
*/
@Generated
public String getUnknownDateTimeFormat() {
return this.unknownDateTimeFormat;
}

/**
* Set the unknownDateTimeFormat property: The unknownDateTimeFormat property.
*
* @param unknownDateTimeFormat the unknownDateTimeFormat value to set.
* @return the Encoded object itself.
*/
@Generated
public Encoded setUnknownDateTimeFormat(String unknownDateTimeFormat) {
this.unknownDateTimeFormat = unknownDateTimeFormat;
return this;
}

/**
* Get the unknownBytes property: The unknownBytes property.
*
* @return the unknownBytes value.
*/
@Generated
public String getUnknownBytes() {
return this.unknownBytes;
}

/**
* Set the unknownBytes property: The unknownBytes property.
*
* @param unknownBytes the unknownBytes value to set.
* @return the Encoded object itself.
*/
@Generated
public Encoded setUnknownBytes(String unknownBytes) {
this.unknownBytes = unknownBytes;
return this;
}

/**
* {@inheritDoc}
*/
@@ -279,6 +363,9 @@ public JsonWriter toJson(JsonWriter jsonWriter) throws IOException {
jsonWriter.writeNumberField("unixTimestamp", this.unixTimestamp);
jsonWriter.writeBinaryField("base64", this.base64);
jsonWriter.writeStringField("base64url", Objects.toString(this.base64url, null));
jsonWriter.writeStringField("unknownDurationFormat", this.unknownDurationFormat);
jsonWriter.writeStringField("unknownDateTimeFormat", this.unknownDateTimeFormat);
jsonWriter.writeStringField("unknownBytes", this.unknownBytes);
return jsonWriter.writeEndObject();
}

@@ -315,6 +402,12 @@ public static Encoded fromJson(JsonReader jsonReader) throws IOException {
} else if ("base64url".equals(fieldName)) {
deserializedEncoded.base64url
= reader.getNullable(nonNullReader -> new Base64Url(nonNullReader.getString()));
} else if ("unknownDurationFormat".equals(fieldName)) {
deserializedEncoded.unknownDurationFormat = reader.getString();
} else if ("unknownDateTimeFormat".equals(fieldName)) {
deserializedEncoded.unknownDateTimeFormat = reader.getString();
} else if ("unknownBytes".equals(fieldName)) {
deserializedEncoded.unknownBytes = reader.getString();
} else {
reader.skipChildren();
}
Original file line number Diff line number Diff line change
@@ -52,6 +52,15 @@ model Encoded {

@encode(BytesKnownEncoding.base64url)
base64url?: bytes;

@encode("unknown-duration")
unknownDurationFormat?: duration;

@encode("unknown-datetime")
unknownDateTimeFormat?: utcDateTime;

@encode("unknown-bytes")
unknownBytes?: bytes;
}

model Request {

0 comments on commit d4d5c3d

Please sign in to comment.