@azure-tools/typespec-java 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/src/code-model-builder.d.ts +102 -0
  2. package/dist/src/code-model-builder.d.ts.map +1 -0
  3. package/dist/src/code-model-builder.js +1675 -0
  4. package/dist/src/code-model-builder.js.map +1 -0
  5. package/dist/src/common/client.d.ts +18 -0
  6. package/dist/src/common/client.d.ts.map +1 -0
  7. package/dist/src/common/client.js +29 -0
  8. package/dist/src/common/client.js.map +1 -0
  9. package/dist/src/common/code-model.d.ts +26 -0
  10. package/dist/src/common/code-model.d.ts.map +1 -0
  11. package/dist/src/common/code-model.js +59 -0
  12. package/dist/src/common/code-model.js.map +1 -0
  13. package/dist/src/common/operation.d.ts +80 -0
  14. package/dist/src/common/operation.d.ts.map +1 -0
  15. package/dist/src/common/operation.js +88 -0
  16. package/dist/src/common/operation.js.map +1 -0
  17. package/dist/src/common/schemas/choice.d.ts +28 -0
  18. package/dist/src/common/schemas/choice.d.ts.map +1 -0
  19. package/dist/src/common/schemas/choice.js +14 -0
  20. package/dist/src/common/schemas/choice.js.map +1 -0
  21. package/dist/src/common/schemas/relationship.d.ts +44 -0
  22. package/dist/src/common/schemas/relationship.d.ts.map +1 -0
  23. package/dist/src/common/schemas/relationship.js +15 -0
  24. package/dist/src/common/schemas/relationship.js.map +1 -0
  25. package/dist/src/common/schemas/usage.d.ts +22 -0
  26. package/dist/src/common/schemas/usage.d.ts.map +1 -0
  27. package/dist/src/common/schemas/usage.js +16 -0
  28. package/dist/src/common/schemas/usage.js.map +1 -0
  29. package/dist/src/emitter.d.ts +21 -0
  30. package/dist/src/emitter.d.ts.map +1 -0
  31. package/dist/src/emitter.js +84 -0
  32. package/dist/src/emitter.js.map +1 -0
  33. package/dist/src/index.d.ts +2 -0
  34. package/dist/src/index.d.ts.map +1 -0
  35. package/dist/src/index.js +2 -0
  36. package/dist/src/index.js.map +1 -0
  37. package/dist/src/models.d.ts +15 -0
  38. package/dist/src/models.d.ts.map +1 -0
  39. package/dist/src/models.js +21 -0
  40. package/dist/src/models.js.map +1 -0
  41. package/dist/src/prenamer/naming-utils.d.ts +67 -0
  42. package/dist/src/prenamer/naming-utils.d.ts.map +1 -0
  43. package/dist/src/prenamer/naming-utils.js +146 -0
  44. package/dist/src/prenamer/naming-utils.js.map +1 -0
  45. package/dist/src/prenamer/prenamer.d.ts +36 -0
  46. package/dist/src/prenamer/prenamer.d.ts.map +1 -0
  47. package/dist/src/prenamer/prenamer.js +332 -0
  48. package/dist/src/prenamer/prenamer.js.map +1 -0
  49. package/dist/tsconfig.tsbuildinfo +1 -0
  50. package/package.json +65 -0
  51. package/readme.md +74 -0
  52. package/target/azure-cadl-extension-jar-with-dependencies.jar +0 -0
@@ -0,0 +1,1675 @@
1
+ import { getDoc, getEffectiveModelType, getFormat, getFriendlyName, getKnownValues, getSummary, getVisibility, ignoreDiagnostics, isArrayModelType, isRecordModelType, isTemplateDeclaration, isTemplateInstance, isUnknownType, getDiscriminator, isNeverType, listServices, getNamespaceFullName, isNullType, NoTarget, getTypeName, getProjectedName, getService, } from "@typespec/compiler";
2
+ import { getResourceOperation, getSegment } from "@typespec/rest";
3
+ import { getAuthentication, getHeaderFieldName, getPathParamName, getQueryParamName, getServers, getStatusCodeDescription, isStatusCode, getHttpOperation, getQueryParamOptions, getHeaderFieldOptions, } from "@typespec/http";
4
+ import { getVersion } from "@typespec/versioning";
5
+ import { isPollingLocation, getPagedResult, getOperationLinks, isFixed } from "@azure-tools/typespec-azure-core";
6
+ import { listClients, listOperationGroups, listOperationsInOperationGroup, isApiVersion, shouldGenerateConvenient, createDpgContext, shouldGenerateProtocol, } from "@azure-tools/typespec-client-generator-core";
7
+ import { fail } from "assert";
8
+ import { AnySchema, ArraySchema, BinaryResponse, BinarySchema, BooleanSchema, ByteArraySchema, ChoiceValue, ConstantSchema, ConstantValue, DateTimeSchema, DateSchema, DictionarySchema, Discriminator, DurationSchema, HttpHeader, HttpParameter, ImplementationLocation, NumberSchema, ObjectSchema, Parameter, ParameterLocation, Property, Relations, Response, SchemaResponse, SchemaType, StringSchema, TimeSchema, Security, OAuth2SecurityScheme, KeySecurityScheme, OperationGroup, UriSchema, VirtualParameter, GroupSchema, GroupProperty, ApiVersion, SerializationStyle, } from "@autorest/codemodel";
9
+ import { CodeModel } from "./common/code-model.js";
10
+ import { Client as CodeModelClient, ServiceVersion } from "./common/client.js";
11
+ import { ConvenienceApi, Operation as CodeModelOperation, OperationLink, Request } from "./common/operation.js";
12
+ import { SchemaContext } from "./common/schemas/usage.js";
13
+ import { ChoiceSchema, SealedChoiceSchema } from "./common/schemas/choice.js";
14
+ import { OrSchema } from "./common/schemas/relationship.js";
15
+ import { PreNamer } from "./prenamer/prenamer.js";
16
+ import { ClientContext, LongRunningMetadata } from "./models.js";
17
+ import pkg from "lodash";
18
+ const { isEqual } = pkg;
19
+ export class CodeModelBuilder {
20
+ constructor(program1, context) {
21
+ this.schemaCache = new ProcessingCache((type, name) => this.processSchemaImpl(type, name));
22
+ this.operationCache = new Map();
23
+ this.options = context.options;
24
+ this.program = program1;
25
+ this.dpgContext = createDpgContext(context);
26
+ const service = listServices(this.program)[0];
27
+ const serviceNamespace = service.type;
28
+ if (serviceNamespace === undefined) {
29
+ throw Error("Can not emit yaml for a namespace that doesn't exist.");
30
+ }
31
+ // java namespace
32
+ this.namespace = getNamespaceFullName(serviceNamespace) || "Azure.Client";
33
+ const javaNamespace = getJavaNamespace(this.namespace);
34
+ const namespace1 = this.namespace;
35
+ this.typeNameOptions = {
36
+ // shorten type names by removing TypeSpec and service namespace
37
+ namespaceFilter(ns) {
38
+ const name = getNamespaceFullName(ns);
39
+ return name !== "Cadl" && name !== namespace1;
40
+ },
41
+ };
42
+ // init code model
43
+ const title = serviceNamespace.name;
44
+ const description = this.getDoc(serviceNamespace);
45
+ this.codeModel = new CodeModel(title, false, {
46
+ info: {
47
+ description: description,
48
+ },
49
+ language: {
50
+ default: {
51
+ name: title,
52
+ description: description,
53
+ summary: this.getSummary(serviceNamespace),
54
+ namespace: this.namespace,
55
+ },
56
+ java: {
57
+ namespace: javaNamespace,
58
+ },
59
+ },
60
+ });
61
+ // auth
62
+ // TODO: it is not very likely, but different client could have different auth
63
+ const auth = getAuthentication(this.program, serviceNamespace);
64
+ if (auth) {
65
+ this.processAuth(auth);
66
+ }
67
+ }
68
+ build() {
69
+ var _a;
70
+ this.processClients();
71
+ (_a = this.codeModel.schemas.objects) === null || _a === void 0 ? void 0 : _a.forEach((it) => this.propagateSchemaUsage(it));
72
+ if (this.options.namer) {
73
+ this.codeModel = new PreNamer(this.codeModel).init().process();
74
+ }
75
+ return this.codeModel;
76
+ }
77
+ processHost(server) {
78
+ const hostParameters = [];
79
+ if (server) {
80
+ server.parameters.forEach((it) => {
81
+ let parameter;
82
+ if (isApiVersion(this.dpgContext, it)) {
83
+ parameter = this.createApiVersionParameter(it.name, ParameterLocation.Uri);
84
+ }
85
+ else {
86
+ const schema = this.processSchema(it.type, it.name);
87
+ parameter = new Parameter(it.name, this.getDoc(it), schema, {
88
+ implementation: ImplementationLocation.Client,
89
+ origin: "modelerfour:synthesized/host",
90
+ required: true,
91
+ protocol: {
92
+ http: new HttpParameter(ParameterLocation.Uri),
93
+ },
94
+ clientDefaultValue: this.getDefaultValue(it.default),
95
+ language: {
96
+ default: {
97
+ serializedName: it.name,
98
+ },
99
+ },
100
+ extensions: {
101
+ "x-ms-skip-url-encoding": schema instanceof UriSchema,
102
+ },
103
+ });
104
+ }
105
+ hostParameters.push(this.codeModel.addGlobalParameter(parameter));
106
+ });
107
+ return hostParameters;
108
+ }
109
+ else {
110
+ hostParameters.push(this.codeModel.addGlobalParameter(new Parameter("endpoint", "Server parameter", this.stringSchema, {
111
+ implementation: ImplementationLocation.Client,
112
+ origin: "modelerfour:synthesized/host",
113
+ required: true,
114
+ protocol: {
115
+ http: new HttpParameter(ParameterLocation.Uri),
116
+ },
117
+ language: {
118
+ default: {
119
+ serializedName: "endpoint",
120
+ },
121
+ },
122
+ extensions: {
123
+ "x-ms-skip-url-encoding": true,
124
+ },
125
+ })));
126
+ return hostParameters;
127
+ }
128
+ }
129
+ processAuth(auth) {
130
+ const securitySchemes = [];
131
+ for (const option of auth.options) {
132
+ for (const scheme of option.schemes) {
133
+ switch (scheme.type) {
134
+ case "oauth2":
135
+ {
136
+ const oauth2Scheme = new OAuth2SecurityScheme({
137
+ scopes: [],
138
+ });
139
+ scheme.flows.forEach((it) => oauth2Scheme.scopes.push(...it.scopes.map((it) => it.value)));
140
+ securitySchemes.push(oauth2Scheme);
141
+ }
142
+ break;
143
+ case "apiKey":
144
+ {
145
+ const keyScheme = new KeySecurityScheme({
146
+ name: scheme.name,
147
+ });
148
+ securitySchemes.push(keyScheme);
149
+ }
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ if (securitySchemes.length > 0) {
155
+ this.codeModel.security = new Security(true, {
156
+ schemes: securitySchemes,
157
+ });
158
+ }
159
+ }
160
+ processClients() {
161
+ var _a;
162
+ const clients = listClients(this.dpgContext);
163
+ for (const client of clients) {
164
+ const codeModelClient = new CodeModelClient(client.name, this.getDoc(client.type), {
165
+ summary: this.getSummary(client.type),
166
+ // at present, use global security definition
167
+ security: this.codeModel.security,
168
+ });
169
+ // versioning
170
+ const versioning = getVersion(this.program, client.service);
171
+ if (versioning && versioning.getVersions()) {
172
+ // @versioned in versioning
173
+ codeModelClient.apiVersions = [];
174
+ for (const version of versioning.getVersions()) {
175
+ const apiVersion = new ApiVersion();
176
+ apiVersion.version = version.value;
177
+ codeModelClient.apiVersions.push(apiVersion);
178
+ }
179
+ }
180
+ else {
181
+ // fallback to @service.version
182
+ const service = getService(this.program, client.service);
183
+ if (service === null || service === void 0 ? void 0 : service.version) {
184
+ codeModelClient.apiVersions = [];
185
+ const apiVersion = new ApiVersion();
186
+ apiVersion.version = service.version;
187
+ codeModelClient.apiVersions.push(apiVersion);
188
+ }
189
+ else {
190
+ throw new Error(`API version not available for client ${client.name}.`);
191
+ }
192
+ }
193
+ // server
194
+ let baseUri = "{endpoint}";
195
+ const servers = getServers(this.program, client.service);
196
+ if (servers && servers.length === 1) {
197
+ baseUri = servers[0].url;
198
+ }
199
+ const hostParameters = this.processHost((servers === null || servers === void 0 ? void 0 : servers.length) === 1 ? servers[0] : undefined);
200
+ codeModelClient.addGlobalParameters(hostParameters);
201
+ const clientContext = new ClientContext(baseUri, hostParameters, codeModelClient.globalParameters);
202
+ const operationGroups = listOperationGroups(this.dpgContext, client);
203
+ const operationWithoutGroup = listOperationsInOperationGroup(this.dpgContext, client);
204
+ let codeModelGroup = new OperationGroup("");
205
+ for (const operation of operationWithoutGroup) {
206
+ codeModelGroup.addOperation(this.processOperation("", operation, clientContext));
207
+ }
208
+ if (((_a = codeModelGroup.operations) === null || _a === void 0 ? void 0 : _a.length) > 0) {
209
+ codeModelClient.operationGroups.push(codeModelGroup);
210
+ }
211
+ for (const operationGroup of operationGroups) {
212
+ const operations = listOperationsInOperationGroup(this.dpgContext, operationGroup);
213
+ codeModelGroup = new OperationGroup(operationGroup.type.name);
214
+ for (const operation of operations) {
215
+ codeModelGroup.addOperation(this.processOperation(operationGroup.type.name, operation, clientContext));
216
+ }
217
+ codeModelClient.operationGroups.push(codeModelGroup);
218
+ }
219
+ this.codeModel.clients.push(codeModelClient);
220
+ }
221
+ // postprocess for ServiceVersion
222
+ let apiVersionSameForAllClients = true;
223
+ let sharedApiVersions = undefined;
224
+ for (const client of this.codeModel.clients) {
225
+ const apiVersions = getClientApiVersions(client);
226
+ if (!apiVersions) {
227
+ // client does not have apiVersions
228
+ apiVersionSameForAllClients = false;
229
+ }
230
+ else if (!sharedApiVersions) {
231
+ // first client, set it to sharedApiVersions
232
+ sharedApiVersions = apiVersions;
233
+ }
234
+ else {
235
+ apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
236
+ }
237
+ if (!apiVersionSameForAllClients) {
238
+ break;
239
+ }
240
+ }
241
+ if (apiVersionSameForAllClients) {
242
+ const serviceVersion = getServiceVersion(this.codeModel);
243
+ for (const client of this.codeModel.clients) {
244
+ client.serviceVersion = serviceVersion;
245
+ }
246
+ }
247
+ else {
248
+ for (const client of this.codeModel.clients) {
249
+ const apiVersions = getClientApiVersions(client);
250
+ if (apiVersions) {
251
+ client.serviceVersion = getServiceVersion(client);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ processOperation(groupName, operation, clientContext, fromLinkedOperation = false) {
257
+ var _a;
258
+ const op = ignoreDiagnostics(getHttpOperation(this.program, operation));
259
+ const operationGroup = this.codeModel.getOperationGroup(groupName);
260
+ const operationName = this.getName(operation);
261
+ const opId = groupName ? `${groupName}_${operationName}` : `${operationName}`;
262
+ const codeModelOperation = new CodeModelOperation(operationName, this.getDoc(operation), {
263
+ operationId: opId,
264
+ summary: this.getSummary(operation),
265
+ });
266
+ if (fromLinkedOperation || !operationContainsJsonMergePatch(op)) {
267
+ // do not generate convenience method for JSON Merge Patch
268
+ const convenienceApiName = this.getConvenienceApiName(operation);
269
+ if (convenienceApiName) {
270
+ codeModelOperation.convenienceApi = new ConvenienceApi(convenienceApiName);
271
+ }
272
+ }
273
+ if (!fromLinkedOperation) {
274
+ // cache for later reference from operationLinks
275
+ this.operationCache.set(operation, codeModelOperation);
276
+ }
277
+ codeModelOperation.addRequest(new Request({
278
+ protocol: {
279
+ http: {
280
+ path: op.path,
281
+ method: op.verb,
282
+ uri: clientContext.baseUri,
283
+ },
284
+ },
285
+ }));
286
+ // host
287
+ clientContext.hostParameters.forEach((it) => codeModelOperation.addParameter(it));
288
+ // parameters
289
+ op.parameters.parameters.map((it) => this.processParameter(codeModelOperation, it, clientContext));
290
+ // "accept" header
291
+ this.addAcceptHeaderParameter(codeModelOperation, op.responses);
292
+ // body
293
+ if (op.parameters.body) {
294
+ if (op.parameters.body.parameter) {
295
+ this.processParameterBody(codeModelOperation, op.parameters.body.parameter, operation.parameters);
296
+ }
297
+ else if (op.parameters.body.type) {
298
+ let bodyType = this.getEffectiveSchemaType(op.parameters.body.type);
299
+ if (bodyType.kind === "Model") {
300
+ // try use resource type as round-trip model
301
+ const resourceType = (_a = getResourceOperation(this.program, operation)) === null || _a === void 0 ? void 0 : _a.resourceType;
302
+ if (resourceType && op.responses && op.responses.length > 0) {
303
+ const resp = op.responses[0];
304
+ if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
305
+ const responseBody = resp.responses[0].body;
306
+ const bodyTypeInResponse = this.findResponseBody(responseBody.type);
307
+ // response body type is resource type, and request body type (if templated) contains resource type
308
+ if (bodyTypeInResponse === resourceType && isModelReferredInTemplate(bodyType, resourceType)) {
309
+ bodyType = resourceType;
310
+ }
311
+ }
312
+ }
313
+ this.processParameterBody(codeModelOperation, bodyType, operation.parameters);
314
+ }
315
+ }
316
+ }
317
+ // linked operations
318
+ const lroMetadata = this.processLinkedOperation(codeModelOperation, groupName, operation, clientContext);
319
+ // responses
320
+ const candidateResponseSchema = lroMetadata.pollResultType; // candidate: response body type of pollingOperation
321
+ op.responses.map((it) => this.processResponse(codeModelOperation, it, candidateResponseSchema));
322
+ // check for paged
323
+ this.processRouteForPaged(codeModelOperation, op.responses);
324
+ // check for long-running operation
325
+ this.processRouteForLongRunning(codeModelOperation, op.responses, lroMetadata.longRunning);
326
+ // check for generating protocol api or not
327
+ codeModelOperation.generateProtocolApi = shouldGenerateProtocol(this.dpgContext, operation);
328
+ operationGroup.addOperation(codeModelOperation);
329
+ return codeModelOperation;
330
+ }
331
+ processRouteForPaged(op, responses) {
332
+ var _a, _b, _c, _d;
333
+ for (const response of responses) {
334
+ if (response.responses && response.responses.length > 0 && response.responses[0].body) {
335
+ const responseBody = response.responses[0].body;
336
+ const bodyType = this.findResponseBody(responseBody.type);
337
+ if (bodyType.kind === "Model") {
338
+ const pagedResult = getPagedResult(this.program, bodyType);
339
+ if (pagedResult) {
340
+ op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
341
+ op.extensions["x-ms-pageable"] = {
342
+ itemName: (_b = pagedResult.itemsProperty) === null || _b === void 0 ? void 0 : _b.name,
343
+ nextLinkName: (_c = pagedResult.nextLinkProperty) === null || _c === void 0 ? void 0 : _c.name,
344
+ };
345
+ (_d = op.responses) === null || _d === void 0 ? void 0 : _d.forEach((r) => {
346
+ if (r instanceof SchemaResponse) {
347
+ this.trackSchemaUsage(r.schema, { usage: [SchemaContext.Paged] });
348
+ }
349
+ });
350
+ break;
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ processLinkedOperation(op, groupName, operation, clientContext) {
357
+ let pollingSchema = undefined;
358
+ let finalSchema = undefined;
359
+ let pollingFoundInOperationLinks = false;
360
+ const operationLinks = getOperationLinks(this.program, operation);
361
+ if (operationLinks) {
362
+ op.operationLinks = {};
363
+ for (const [linkType, linkOperation] of operationLinks) {
364
+ if (linkType === "polling" || linkType === "final") {
365
+ // some TypeSpec writes pollingOperation without the operation
366
+ pollingFoundInOperationLinks = true;
367
+ }
368
+ if (linkOperation.linkedOperation) {
369
+ // process linked operation, if not processed
370
+ let linkedOperation = this.operationCache.get(linkOperation.linkedOperation);
371
+ if (!linkedOperation) {
372
+ linkedOperation = this.processOperation(groupName, linkOperation.linkedOperation, clientContext, true);
373
+ }
374
+ const opLink = new OperationLink(linkedOperation);
375
+ // parameters of operation link
376
+ if (linkOperation.parameters) {
377
+ opLink.parameters = this.processSchema(linkOperation.parameters, "parameters");
378
+ }
379
+ op.operationLinks[linkType] = opLink;
380
+ const getResponse = (linkedOp) => {
381
+ if (linkedOp.responses) {
382
+ const response = linkedOp.responses.find((it) => { var _a, _b, _c; return (_c = (_b = (_a = it.protocol) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.statusCodes) === null || _c === void 0 ? void 0 : _c.includes("200"); });
383
+ if (response && response instanceof SchemaResponse) {
384
+ const schema = response.schema;
385
+ if (op.convenienceApi) {
386
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
387
+ }
388
+ return schema;
389
+ }
390
+ }
391
+ return undefined;
392
+ };
393
+ if (linkType === "polling") {
394
+ pollingSchema = getResponse(linkedOperation);
395
+ }
396
+ else if (linkType === "final") {
397
+ finalSchema = getResponse(linkedOperation);
398
+ }
399
+ }
400
+ }
401
+ }
402
+ return new LongRunningMetadata(pollingFoundInOperationLinks, pollingSchema, finalSchema);
403
+ }
404
+ processRouteForLongRunning(op, responses, pollingFoundInOperationLinks) {
405
+ var _a, _b;
406
+ if (pollingFoundInOperationLinks) {
407
+ op.extensions = (_a = op.extensions) !== null && _a !== void 0 ? _a : {};
408
+ op.extensions["x-ms-long-running-operation"] = true;
409
+ return;
410
+ }
411
+ for (const resp of responses) {
412
+ if (resp.responses && resp.responses.length > 0 && resp.responses[0].headers) {
413
+ for (const [_, header] of Object.entries(resp.responses[0].headers)) {
414
+ if (isPollingLocation(this.program, header)) {
415
+ op.extensions = (_b = op.extensions) !== null && _b !== void 0 ? _b : {};
416
+ op.extensions["x-ms-long-running-operation"] = true;
417
+ break;
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ processParameter(op, param, clientContext) {
424
+ var _a;
425
+ if (isApiVersion(this.dpgContext, param)) {
426
+ const parameter = param.type === "query" ? this.apiVersionParameter : this.apiVersionParameterInPath;
427
+ op.addParameter(parameter);
428
+ clientContext.addGlobalParameter(parameter);
429
+ }
430
+ else if (specialHeaderNames.has(param.name.toLowerCase())) {
431
+ // special headers
432
+ op.specialHeaders = (_a = op.specialHeaders) !== null && _a !== void 0 ? _a : [];
433
+ if (!containsIgnoreCase(op.specialHeaders, param.name)) {
434
+ op.specialHeaders.push(param.name);
435
+ }
436
+ }
437
+ else {
438
+ // schema
439
+ let schema;
440
+ if (param.type === "header" && param.param.type.kind === "Scalar" && param.param.type.name === "zonedDateTime") {
441
+ // zonedTateTime in header maps to RFC 5322
442
+ schema = this.processDateTimeSchema(param.param.type, param.param.name, true);
443
+ }
444
+ else {
445
+ schema = this.processSchema(param.param.type, param.param.name);
446
+ }
447
+ // skip-url-encoding
448
+ let extensions = undefined;
449
+ if ((param.type === "query" || param.type === "path") &&
450
+ param.param.type.kind === "Scalar" &&
451
+ schema instanceof UriSchema) {
452
+ extensions = { "x-ms-skip-url-encoding": true };
453
+ }
454
+ // format if array
455
+ let style = undefined;
456
+ let explode = undefined;
457
+ if (param.param.type.kind === "Model" && isArrayModelType(this.program, param.param.type)) {
458
+ if (param.type === "query") {
459
+ const queryParamOptions = getQueryParamOptions(this.program, param.param);
460
+ switch (queryParamOptions === null || queryParamOptions === void 0 ? void 0 : queryParamOptions.format) {
461
+ case "csv":
462
+ style = SerializationStyle.Simple;
463
+ break;
464
+ case "multi":
465
+ style = SerializationStyle.Form;
466
+ explode = true;
467
+ break;
468
+ }
469
+ }
470
+ else if (param.type === "header") {
471
+ const headerFieldOptions = getHeaderFieldOptions(this.program, param.param);
472
+ switch (headerFieldOptions === null || headerFieldOptions === void 0 ? void 0 : headerFieldOptions.format) {
473
+ case "csv":
474
+ style = SerializationStyle.Simple;
475
+ break;
476
+ }
477
+ }
478
+ }
479
+ const nullable = this.isNullableType(param.param.type);
480
+ const parameter = new Parameter(param.param.name, this.getDoc(param.param), schema, {
481
+ summary: this.getSummary(param.param),
482
+ implementation: ImplementationLocation.Method,
483
+ required: !param.param.optional,
484
+ nullable: nullable,
485
+ protocol: {
486
+ http: new HttpParameter(param.type, {
487
+ style: style,
488
+ explode: explode,
489
+ }),
490
+ },
491
+ // clientDefaultValue: this.getDefaultValue(param.param.default),
492
+ language: {
493
+ default: {
494
+ serializedName: param.name,
495
+ },
496
+ },
497
+ extensions: extensions,
498
+ });
499
+ op.addParameter(parameter);
500
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.Input] });
501
+ if (op.convenienceApi) {
502
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
503
+ }
504
+ if (param.name.toLowerCase() === "content-type") {
505
+ let mediaTypes = ["application/json"];
506
+ if (schema instanceof ConstantSchema) {
507
+ mediaTypes = [schema.value.value.toString()];
508
+ }
509
+ else if (schema instanceof SealedChoiceSchema) {
510
+ mediaTypes = schema.choices.map((it) => it.value.toString());
511
+ }
512
+ op.requests[0].protocol.http.mediaTypes = mediaTypes;
513
+ }
514
+ }
515
+ }
516
+ addAcceptHeaderParameter(op, responses) {
517
+ var _a, _b;
518
+ const produces = new Set(["application/json"]);
519
+ for (const resp of responses) {
520
+ if (resp.responses && resp.responses.length > 0) {
521
+ for (const response of resp.responses) {
522
+ (_a = response.body) === null || _a === void 0 ? void 0 : _a.contentTypes.forEach((it) => produces.add(it));
523
+ }
524
+ }
525
+ }
526
+ const acceptTypes = Array.from(produces.values()).join(", ");
527
+ const acceptSchema = ((_b = this.codeModel.schemas.constants) === null || _b === void 0 ? void 0 : _b.find((it) => it.language.default.name === "accept" && it.value.value === acceptTypes)) ||
528
+ this.codeModel.schemas.add(new ConstantSchema("accept", `Accept: ${acceptTypes}`, {
529
+ valueType: this.stringSchema,
530
+ value: new ConstantValue(acceptTypes),
531
+ }));
532
+ op.addParameter(new Parameter("accept", "Accept header", acceptSchema, {
533
+ implementation: ImplementationLocation.Method,
534
+ origin: "modelerfour:synthesized/accept",
535
+ required: true,
536
+ protocol: {
537
+ http: new HttpParameter(ParameterLocation.Header),
538
+ },
539
+ language: {
540
+ default: {
541
+ serializedName: "accept",
542
+ },
543
+ },
544
+ }));
545
+ }
546
+ processParameterBody(op, body, parameters) {
547
+ var _a, _b, _c;
548
+ let schema;
549
+ if (body.kind === "ModelProperty" && body.type.kind === "Scalar" && body.type.name === "bytes") {
550
+ //handle for binary body
551
+ schema = this.processBinarySchema(body.name);
552
+ }
553
+ else {
554
+ schema = this.processSchema(body.kind === "Model" ? body : body.type, body.name);
555
+ }
556
+ const parameter = new Parameter(body.name, this.getDoc(body), schema, {
557
+ summary: this.getSummary(body),
558
+ implementation: ImplementationLocation.Method,
559
+ required: body.kind === "Model" || !body.optional,
560
+ protocol: {
561
+ http: new HttpParameter(ParameterLocation.Body),
562
+ },
563
+ // clientDefaultValue: this.getDefaultValue(body.default),
564
+ });
565
+ op.addParameter(parameter);
566
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.Input] });
567
+ if (op.convenienceApi) {
568
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.ConvenienceApi] });
569
+ }
570
+ if (!schema.language.default.name && schema instanceof ObjectSchema) {
571
+ // anonymous model
572
+ if (!parameter.language.default.name) {
573
+ // name the parameter for documentation
574
+ parameter.language.default.name = "request";
575
+ }
576
+ this.trackSchemaUsage(schema, { usage: [SchemaContext.Anonymous] });
577
+ if (op.convenienceApi && op.parameters) {
578
+ op.convenienceApi.requests = [];
579
+ const request = new Request();
580
+ request.parameters = [];
581
+ op.convenienceApi.requests.push(request);
582
+ for (const [key, _] of parameters.properties) {
583
+ const existParameter = op.parameters.find((it) => it.language.default.serializedName === key);
584
+ if (existParameter) {
585
+ // parameter
586
+ if (existParameter.implementation === ImplementationLocation.Method &&
587
+ ((_b = (_a = existParameter.origin) === null || _a === void 0 ? void 0 : _a.startsWith("modelerfour:synthesized/")) !== null && _b !== void 0 ? _b : true)) {
588
+ request.parameters.push(new Parameter(existParameter.language.default.name, existParameter.language.default.description, existParameter.schema, {
589
+ language: {
590
+ default: {
591
+ serializedName: existParameter.language.default.serializedName,
592
+ },
593
+ },
594
+ protocol: existParameter.protocol,
595
+ summary: existParameter.summary,
596
+ implementation: ImplementationLocation.Method,
597
+ required: existParameter.required,
598
+ nullable: existParameter.nullable,
599
+ extensions: existParameter.extensions,
600
+ }));
601
+ }
602
+ }
603
+ else {
604
+ // property from anonymous model
605
+ const existBodyProperty = (_c = schema.properties) === null || _c === void 0 ? void 0 : _c.find((it) => it.serializedName === key);
606
+ if (existBodyProperty) {
607
+ request.parameters.push(new VirtualParameter(existBodyProperty.language.default.name, existBodyProperty.language.default.description, existBodyProperty.schema, {
608
+ originalParameter: parameter,
609
+ targetProperty: existBodyProperty,
610
+ language: {
611
+ default: {
612
+ serializedName: existBodyProperty.serializedName,
613
+ },
614
+ },
615
+ summary: existBodyProperty.summary,
616
+ implementation: ImplementationLocation.Method,
617
+ required: existBodyProperty.required,
618
+ nullable: existBodyProperty.nullable,
619
+ }));
620
+ }
621
+ }
622
+ }
623
+ request.signatureParameters = request.parameters;
624
+ if (request.signatureParameters.length > 6) {
625
+ // create an option bag
626
+ const name = op.language.default.name + "Options";
627
+ const namespace = body.kind === "Model" ? getNamespace(body) : this.namespace;
628
+ // option bag schema
629
+ const optionBagSchema = this.codeModel.schemas.add(new GroupSchema(name, `Options for ${op.language.default.name} API`, {
630
+ language: {
631
+ default: {
632
+ namespace: namespace,
633
+ },
634
+ java: {
635
+ namespace: getJavaNamespace(namespace),
636
+ },
637
+ },
638
+ }));
639
+ request.parameters.forEach((it) => {
640
+ optionBagSchema.add(new GroupProperty(it.language.default.name, it.language.default.description, it.schema, {
641
+ originalParameter: [it],
642
+ summary: it.summary,
643
+ required: it.required,
644
+ nullable: it.nullable,
645
+ readOnly: false,
646
+ serializedName: it.language.default.serializedName,
647
+ }));
648
+ });
649
+ this.trackSchemaUsage(optionBagSchema, { usage: [SchemaContext.Input, SchemaContext.ConvenienceApi] });
650
+ // option bag parameter
651
+ const optionBagParameter = new Parameter("options", optionBagSchema.language.default.description, optionBagSchema, {
652
+ implementation: ImplementationLocation.Method,
653
+ required: true,
654
+ nullable: false,
655
+ });
656
+ request.signatureParameters = [optionBagParameter];
657
+ request.parameters.forEach((it) => (it.groupedBy = optionBagParameter));
658
+ request.parameters.push(optionBagParameter);
659
+ }
660
+ }
661
+ }
662
+ }
663
+ findResponseBody(bodyType) {
664
+ // find a type that possibly without http metadata like @statusCode
665
+ return this.getEffectiveSchemaType(bodyType);
666
+ }
667
+ processResponse(op, resp, candidateResponseSchema = undefined) {
668
+ var _a, _b, _c, _d, _e, _f;
669
+ // TODO: what to do if more than 1 response?
670
+ let response;
671
+ let headers = undefined;
672
+ if (resp.responses && resp.responses.length > 0 && resp.responses[0].headers) {
673
+ // headers
674
+ headers = [];
675
+ for (const [key, header] of Object.entries(resp.responses[0].headers)) {
676
+ const schema = this.processSchema(header.type, key);
677
+ headers.push(new HttpHeader(key, schema, {
678
+ language: {
679
+ default: {
680
+ name: key,
681
+ description: this.getDoc(header),
682
+ },
683
+ },
684
+ }));
685
+ }
686
+ }
687
+ let trackConvenienceApi = (_a = op.convenienceApi) !== null && _a !== void 0 ? _a : false;
688
+ if (resp.responses && resp.responses.length > 0 && resp.responses[0].body) {
689
+ const responseBody = resp.responses[0].body;
690
+ const bodyType = this.findResponseBody(responseBody.type);
691
+ if (bodyType.kind === "Scalar" && bodyType.name === "bytes") {
692
+ // binary
693
+ response = new BinaryResponse({
694
+ protocol: {
695
+ http: {
696
+ statusCodes: [this.getStatusCode(resp.statusCode)],
697
+ headers: headers,
698
+ mediaTypes: responseBody.contentTypes,
699
+ knownMediaType: "binary",
700
+ },
701
+ },
702
+ language: {
703
+ default: {
704
+ name: op.language.default.name + "Response",
705
+ description: this.getResponseDescription(resp),
706
+ },
707
+ },
708
+ });
709
+ }
710
+ else {
711
+ // schema (usually JSON)
712
+ let schema = undefined;
713
+ const verb = (_d = (_c = (_b = op.requests) === null || _b === void 0 ? void 0 : _b[0].protocol) === null || _c === void 0 ? void 0 : _c.http) === null || _d === void 0 ? void 0 : _d.method;
714
+ if (
715
+ // LRO, candidateResponseSchema is Model/ObjectSchema
716
+ candidateResponseSchema &&
717
+ candidateResponseSchema instanceof ObjectSchema &&
718
+ // bodyType is templated Model
719
+ bodyType.kind === "Model" &&
720
+ bodyType.templateMapper &&
721
+ bodyType.templateMapper.args &&
722
+ bodyType.templateMapper.args.length > 0) {
723
+ if (verb === "post") {
724
+ // for LRO ResourceAction, the standard does not require a final type, hence it can be the same as intermediate type
725
+ // https://github.com/microsoft/api-guidelines/blob/vNext/azure/ConsiderationsForServiceDesign.md#long-running-action-operations
726
+ // check if we can use candidateResponseSchema as response schema (instead of the templated Model), for LRO ResourceAction
727
+ if (((_e = candidateResponseSchema.properties) === null || _e === void 0 ? void 0 : _e.length) === bodyType.properties.size) {
728
+ let match = true;
729
+ for (const prop of Array.from(bodyType.properties.values())) {
730
+ const name = this.getName(prop);
731
+ if (!((_f = candidateResponseSchema.properties) === null || _f === void 0 ? void 0 : _f.find((it) => it.language.default.name === name))) {
732
+ match = false;
733
+ break;
734
+ }
735
+ }
736
+ if (match) {
737
+ schema = candidateResponseSchema;
738
+ this.program.trace("typespec-java", `Replace TypeSpec model ${this.getName(bodyType)} with ${candidateResponseSchema.language.default.name}`);
739
+ }
740
+ }
741
+ }
742
+ else if (verb === "delete") {
743
+ // for LRO ResourceDelete, final type will be replaced to "Void" in convenience API, hence do not generate the class
744
+ trackConvenienceApi = false;
745
+ }
746
+ }
747
+ if (!schema) {
748
+ schema = this.processSchema(bodyType, "response");
749
+ }
750
+ response = new SchemaResponse(schema, {
751
+ protocol: {
752
+ http: {
753
+ statusCodes: [this.getStatusCode(resp.statusCode)],
754
+ headers: headers,
755
+ mediaTypes: responseBody.contentTypes,
756
+ },
757
+ },
758
+ language: {
759
+ default: {
760
+ name: op.language.default.name + "Response",
761
+ description: this.getResponseDescription(resp),
762
+ },
763
+ },
764
+ });
765
+ }
766
+ }
767
+ else {
768
+ // not binary nor schema, usually NoContent
769
+ response = new Response({
770
+ protocol: {
771
+ http: {
772
+ statusCodes: [this.getStatusCode(resp.statusCode)],
773
+ headers: headers,
774
+ },
775
+ },
776
+ language: {
777
+ default: {
778
+ name: op.language.default.name + "Response",
779
+ description: this.getResponseDescription(resp),
780
+ },
781
+ },
782
+ });
783
+ }
784
+ if (resp.statusCode === "*" || Number(resp.statusCode) / 100 > 3) {
785
+ // TODO: x-ms-error-response
786
+ op.addException(response);
787
+ if (response instanceof SchemaResponse) {
788
+ this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Exception] });
789
+ }
790
+ }
791
+ else {
792
+ op.addResponse(response);
793
+ if (response instanceof SchemaResponse) {
794
+ this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Output] });
795
+ if (trackConvenienceApi) {
796
+ this.trackSchemaUsage(response.schema, { usage: [SchemaContext.ConvenienceApi] });
797
+ }
798
+ }
799
+ }
800
+ }
801
+ getStatusCode(statusCode) {
802
+ return statusCode === "*" ? "default" : statusCode;
803
+ }
804
+ getResponseDescription(resp) {
805
+ return (resp.description ||
806
+ (resp.statusCode === "*" ? "An unexpected error response" : getStatusCodeDescription(resp.statusCode)) ||
807
+ "");
808
+ }
809
+ processSchema(type, nameHint) {
810
+ return this.schemaCache.process(type, nameHint) || fail("Unable to process schema.");
811
+ }
812
+ processSchemaImpl(type, nameHint) {
813
+ switch (type.kind) {
814
+ case "Intrinsic":
815
+ if (isUnknownType(type)) {
816
+ return this.processAnySchema(type, nameHint);
817
+ }
818
+ else {
819
+ throw new Error(`Unrecognized intrinsic type: '${type.name}'.`);
820
+ }
821
+ case "String":
822
+ return this.processChoiceSchemaForLiteral(type, nameHint);
823
+ case "Number":
824
+ // TODO: float
825
+ return this.processChoiceSchemaForLiteral(type, nameHint);
826
+ case "Boolean":
827
+ return this.processChoiceSchemaForLiteral(type, nameHint);
828
+ case "Enum":
829
+ return this.processChoiceSchema(type, this.getName(type), isFixed(this.program, type));
830
+ case "Union":
831
+ return this.processUnionSchema(type, nameHint);
832
+ case "ModelProperty": {
833
+ let schema = undefined;
834
+ const knownValues = getKnownValues(this.program, type);
835
+ if (knownValues) {
836
+ // use it for extensible enum
837
+ schema = this.processChoiceSchema(knownValues, this.getName(knownValues), false);
838
+ }
839
+ else {
840
+ schema = this.processSchema(type.type, nameHint);
841
+ }
842
+ return this.applyModelPropertyDecorators(type, nameHint, schema);
843
+ }
844
+ case "Scalar":
845
+ return this.processScalar(type, undefined, nameHint);
846
+ case "Model":
847
+ if (isArrayModelType(this.program, type)) {
848
+ return this.processArraySchema(type, nameHint);
849
+ }
850
+ else if (isRecordModelType(this.program, type)) {
851
+ return this.processDictionarySchema(type, nameHint);
852
+ }
853
+ else {
854
+ return this.processObjectSchema(type, this.getName(type));
855
+ }
856
+ }
857
+ throw new Error(`Unrecognized type: '${type.kind}'.`);
858
+ }
859
+ processScalar(type, formatFromDerived, nameHint) {
860
+ const scalarName = type.name;
861
+ if (this.program.checker.isStdType(type)) {
862
+ switch (scalarName) {
863
+ case "string": {
864
+ const format = formatFromDerived !== null && formatFromDerived !== void 0 ? formatFromDerived : getFormat(this.program, type);
865
+ if (format) {
866
+ return this.processFormatString(type, format, nameHint);
867
+ }
868
+ return this.processStringSchema(type, nameHint);
869
+ }
870
+ case "bytes":
871
+ return this.processByteArraySchema(type, nameHint, false);
872
+ case "boolean":
873
+ return this.processBooleanSchema(type, nameHint);
874
+ case "plainTime":
875
+ return this.processTimeSchema(type, nameHint);
876
+ case "plainDate":
877
+ return this.processDateSchema(type, nameHint);
878
+ case "zonedDateTime":
879
+ return this.processDateTimeSchema(type, nameHint, false);
880
+ case "duration":
881
+ return this.processDurationSchema(type, nameHint);
882
+ case "url":
883
+ return this.processUrlSchema(type, nameHint);
884
+ }
885
+ if (scalarName.startsWith("int") || scalarName.startsWith("uint") || scalarName === "safeint") {
886
+ // integer
887
+ const integerSize = scalarName === "safeint" || scalarName.includes("int64") ? 64 : 32;
888
+ return this.processIntegerSchema(type, nameHint, integerSize);
889
+ }
890
+ else if (scalarName.startsWith("float")) {
891
+ // float point
892
+ return this.processNumberSchema(type, nameHint);
893
+ }
894
+ else {
895
+ throw new Error(`Unrecognized scalar type: '${scalarName}'.`);
896
+ }
897
+ }
898
+ else {
899
+ const knownValues = getKnownValues(this.program, type);
900
+ if (knownValues) {
901
+ // use it for extensible enum
902
+ return this.processChoiceSchema(knownValues, this.getName(type), false);
903
+ }
904
+ else {
905
+ if (type.baseScalar) {
906
+ // fallback to baseScalar
907
+ const schema = this.processScalar(type.baseScalar, getFormat(this.program, type), nameHint);
908
+ const doc = getDoc(this.program, type);
909
+ const summary = getSummary(this.program, type);
910
+ if (doc) {
911
+ schema.language.default.description = doc;
912
+ }
913
+ if (summary) {
914
+ schema.summary = summary;
915
+ }
916
+ return schema;
917
+ }
918
+ else {
919
+ throw new Error(`Unrecognized scalar type: '${scalarName}'.`);
920
+ }
921
+ }
922
+ }
923
+ }
924
+ processAnySchema(type, name) {
925
+ return this.codeModel.schemas.add(new AnySchema(this.getDoc(type), {
926
+ summary: this.getSummary(type),
927
+ }));
928
+ }
929
+ processStringSchema(type, name) {
930
+ return this.codeModel.schemas.add(new StringSchema(name, this.getDoc(type), {
931
+ summary: this.getSummary(type),
932
+ }));
933
+ }
934
+ processByteArraySchema(type, name, base64Encoded) {
935
+ return this.codeModel.schemas.add(new ByteArraySchema(name, this.getDoc(type), {
936
+ summary: this.getSummary(type),
937
+ format: base64Encoded ? "base64url" : "byte",
938
+ }));
939
+ }
940
+ processIntegerSchema(type, name, precision) {
941
+ return this.codeModel.schemas.add(new NumberSchema(name, this.getDoc(type), SchemaType.Integer, precision, {
942
+ summary: this.getSummary(type),
943
+ }));
944
+ }
945
+ processNumberSchema(type, name) {
946
+ return this.codeModel.schemas.add(new NumberSchema(name, this.getDoc(type), SchemaType.Number, 64, {
947
+ summary: this.getSummary(type),
948
+ }));
949
+ }
950
+ processBooleanSchema(type, name) {
951
+ return this.codeModel.schemas.add(new BooleanSchema(name, this.getDoc(type), {
952
+ summary: this.getSummary(type),
953
+ }));
954
+ }
955
+ processArraySchema(type, name) {
956
+ const elementSchema = this.processSchema(type.indexer.value, name);
957
+ return this.codeModel.schemas.add(new ArraySchema(name, this.getDoc(type), elementSchema, {
958
+ summary: this.getSummary(type),
959
+ }));
960
+ }
961
+ processDictionarySchema(type, name) {
962
+ const dictSchema = new DictionarySchema(name, this.getDoc(type), null, {
963
+ summary: this.getSummary(type),
964
+ });
965
+ // cache this now before we accidentally recurse on this type.
966
+ this.schemaCache.set(type, dictSchema);
967
+ const elementSchema = this.processSchema(type.indexer.value, name);
968
+ dictSchema.elementType = elementSchema;
969
+ return this.codeModel.schemas.add(dictSchema);
970
+ }
971
+ processChoiceSchema(type, name, sealed) {
972
+ const namespace = getNamespace(type);
973
+ const valueType = typeof type.members.values().next().value.value === "number" ? this.integerSchema : this.stringSchema;
974
+ const choices = [];
975
+ type.members.forEach((it) => { var _a; return choices.push(new ChoiceValue(it.name, this.getDoc(it), (_a = it.value) !== null && _a !== void 0 ? _a : it.name)); });
976
+ if (sealed) {
977
+ return this.codeModel.schemas.add(new SealedChoiceSchema(name, this.getDoc(type), {
978
+ summary: this.getSummary(type),
979
+ choiceType: valueType,
980
+ choices: choices,
981
+ language: {
982
+ default: {
983
+ namespace: namespace,
984
+ },
985
+ java: {
986
+ namespace: getJavaNamespace(namespace),
987
+ },
988
+ },
989
+ }));
990
+ }
991
+ else {
992
+ return this.codeModel.schemas.add(new ChoiceSchema(name, this.getDoc(type), {
993
+ summary: this.getSummary(type),
994
+ choiceType: valueType,
995
+ choices: choices,
996
+ language: {
997
+ default: {
998
+ namespace: namespace,
999
+ },
1000
+ java: {
1001
+ namespace: getJavaNamespace(namespace),
1002
+ },
1003
+ },
1004
+ }));
1005
+ }
1006
+ }
1007
+ processChoiceSchemaForLiteral(type, name) {
1008
+ const valueType = type.kind === "String" ? this.stringSchema : type.kind === "Boolean" ? this.booleanSchema : this.integerSchema;
1009
+ return this.codeModel.schemas.add(new ConstantSchema(name, this.getDoc(type), {
1010
+ summary: this.getSummary(type),
1011
+ valueType: valueType,
1012
+ value: new ConstantValue(type.value),
1013
+ }));
1014
+ // return this.codeModel.schemas.add(
1015
+ // new ChoiceSchema(name, this.getDoc(type), {
1016
+ // summary: this.getSummary(type),
1017
+ // choiceType: valueType as any,
1018
+ // choices: [new ChoiceValue(type.value.toString(), this.getDoc(type), type.value)]
1019
+ // })
1020
+ // );
1021
+ }
1022
+ processChoiceSchemaForUnion(type, variants, name) {
1023
+ const kind = variants[0].type.kind;
1024
+ const valueType = kind === "String" ? this.stringSchema : kind === "Boolean" ? this.booleanSchema : this.integerSchema;
1025
+ const choices = [];
1026
+ variants.forEach((it) => choices.push(new ChoiceValue(it.type.value.toString(), this.getDoc(it), it.type.value)));
1027
+ const namespace = getNamespace(type);
1028
+ return this.codeModel.schemas.add(new SealedChoiceSchema(name, this.getDoc(type), {
1029
+ summary: this.getSummary(type),
1030
+ choiceType: valueType,
1031
+ choices: choices,
1032
+ language: {
1033
+ default: {
1034
+ namespace: namespace,
1035
+ },
1036
+ java: {
1037
+ namespace: getJavaNamespace(namespace),
1038
+ },
1039
+ },
1040
+ }));
1041
+ }
1042
+ processDateTimeSchema(type, name, rfc1123) {
1043
+ return this.codeModel.schemas.add(new DateTimeSchema(name, this.getDoc(type), {
1044
+ summary: this.getSummary(type),
1045
+ format: rfc1123 ? "date-time-rfc1123" : "date-time",
1046
+ }));
1047
+ }
1048
+ processDateSchema(type, name) {
1049
+ return this.codeModel.schemas.add(new DateSchema(name, this.getDoc(type), {
1050
+ summary: this.getSummary(type),
1051
+ }));
1052
+ }
1053
+ processTimeSchema(type, name) {
1054
+ return this.codeModel.schemas.add(new TimeSchema(name, this.getDoc(type), {
1055
+ summary: this.getSummary(type),
1056
+ }));
1057
+ }
1058
+ processDurationSchema(type, name) {
1059
+ return this.codeModel.schemas.add(new DurationSchema(name, this.getDoc(type), {
1060
+ summary: this.getSummary(type),
1061
+ }));
1062
+ }
1063
+ processUrlSchema(type, name) {
1064
+ return this.codeModel.schemas.add(new UriSchema(name, this.getDoc(type), {
1065
+ summary: this.getSummary(type),
1066
+ }));
1067
+ }
1068
+ processObjectSchema(type, name) {
1069
+ var _a;
1070
+ const namespace = getNamespace(type);
1071
+ const objectSchema = this.codeModel.schemas.add(new ObjectSchema(name, this.getDoc(type), {
1072
+ summary: this.getSummary(type),
1073
+ language: {
1074
+ default: {
1075
+ namespace: namespace,
1076
+ },
1077
+ java: {
1078
+ namespace: getJavaNamespace(namespace),
1079
+ },
1080
+ },
1081
+ }));
1082
+ // cache this now before we accidentally recurse on this type.
1083
+ this.schemaCache.set(type, objectSchema);
1084
+ // discriminator
1085
+ let discriminatorPropertyName = undefined;
1086
+ const discriminator = getDiscriminator(this.program, type);
1087
+ if (discriminator) {
1088
+ discriminatorPropertyName = discriminator.propertyName;
1089
+ objectSchema.discriminator = new Discriminator(new Property(discriminatorPropertyName, discriminatorPropertyName, this.stringSchema, {
1090
+ required: true,
1091
+ serializedName: discriminatorPropertyName,
1092
+ }));
1093
+ }
1094
+ // parent
1095
+ if (type.baseModel) {
1096
+ const parentSchema = this.processSchema(type.baseModel, this.getName(type.baseModel));
1097
+ objectSchema.parents = new Relations();
1098
+ objectSchema.parents.immediate.push(parentSchema);
1099
+ if (parentSchema instanceof ObjectSchema) {
1100
+ pushDistinct(objectSchema.parents.all, parentSchema);
1101
+ parentSchema.children = parentSchema.children || new Relations();
1102
+ pushDistinct(parentSchema.children.immediate, objectSchema);
1103
+ pushDistinct(parentSchema.children.all, objectSchema);
1104
+ if (parentSchema.parents) {
1105
+ pushDistinct(objectSchema.parents.all, ...parentSchema.parents.all);
1106
+ parentSchema.parents.all.forEach((it) => {
1107
+ if (it instanceof ObjectSchema && it.children) {
1108
+ pushDistinct(it.children.all, objectSchema);
1109
+ }
1110
+ });
1111
+ }
1112
+ }
1113
+ }
1114
+ // value of the discriminator property
1115
+ if (objectSchema.parents) {
1116
+ const parentWithDiscriminator = objectSchema.parents.all.find((it) => it instanceof ObjectSchema && it.discriminator);
1117
+ if (parentWithDiscriminator) {
1118
+ discriminatorPropertyName = parentWithDiscriminator.discriminator.property.serializedName;
1119
+ const discriminatorProperty = Array.from(type.properties.values()).find((it) => it.name === discriminatorPropertyName && it.type.kind === "String");
1120
+ if (discriminatorProperty) {
1121
+ // value of the StringLiteral of the discriminator property
1122
+ objectSchema.discriminatorValue = discriminatorProperty.type.value;
1123
+ }
1124
+ else {
1125
+ // fallback to name of the Model
1126
+ objectSchema.discriminatorValue = name;
1127
+ }
1128
+ }
1129
+ }
1130
+ // properties
1131
+ for (const prop of type.properties.values()) {
1132
+ if (prop.name === discriminatorPropertyName || // skip the discriminator property
1133
+ isNeverType(prop.type) || // skip property of type "never"
1134
+ !isPayloadProperty(this.program, prop)) {
1135
+ continue;
1136
+ }
1137
+ objectSchema.addProperty(this.processModelProperty(prop));
1138
+ }
1139
+ // process all children
1140
+ (_a = type.derivedModels) === null || _a === void 0 ? void 0 : _a.filter(modelContainsDerivedModel).forEach((it) => this.processSchema(it, this.getName(it)));
1141
+ return objectSchema;
1142
+ }
1143
+ getEffectiveSchemaType(type) {
1144
+ const program = this.program;
1145
+ function isSchemaProperty(property) {
1146
+ return isPayloadProperty(program, property);
1147
+ }
1148
+ if (type.kind === "Model") {
1149
+ const effective = getEffectiveModelType(program, type, isSchemaProperty);
1150
+ if (effective.name) {
1151
+ return effective;
1152
+ }
1153
+ }
1154
+ return type;
1155
+ }
1156
+ applyModelPropertyDecorators(prop, nameHint, schema) {
1157
+ // if (schema instanceof StringSchema) {
1158
+ // const decorators = {
1159
+ // minLength: getMinLength(this.program, prop),
1160
+ // maxLength: getMaxLength(this.program, prop),
1161
+ // pattern: getPattern(this.program, prop),
1162
+ // };
1163
+ // if (Object.values(decorators).some((it) => it !== undefined)) {
1164
+ // schema = new StringSchema(schema.language.default.name, schema.language.default.description, {
1165
+ // language: schema.language,
1166
+ // summary: schema.summary,
1167
+ // extensions: schema.extensions,
1168
+ // ...decorators,
1169
+ // });
1170
+ // }
1171
+ // } else if (schema instanceof NumberSchema) {
1172
+ // const decorators = {
1173
+ // minimum: getMinValue(this.program, prop),
1174
+ // maximum: getMaxValue(this.program, prop),
1175
+ // };
1176
+ // if (Object.values(decorators).some((it) => it !== undefined)) {
1177
+ // schema = new NumberSchema(
1178
+ // schema.language.default.name,
1179
+ // schema.language.default.description,
1180
+ // schema.type,
1181
+ // schema.precision,
1182
+ // {
1183
+ // language: schema.language,
1184
+ // summary: schema.summary,
1185
+ // extensions: schema.extensions,
1186
+ // ...decorators,
1187
+ // },
1188
+ // );
1189
+ // }
1190
+ // }
1191
+ const format = getFormat(this.program, prop);
1192
+ if (format) {
1193
+ if (prop.type.kind === "Scalar" && schema instanceof StringSchema) {
1194
+ schema = this.processFormatString(prop.type, format, nameHint);
1195
+ }
1196
+ }
1197
+ return schema;
1198
+ }
1199
+ processModelProperty(prop) {
1200
+ const schema = this.processSchema(prop, prop.name);
1201
+ const nullable = this.isNullableType(prop.type);
1202
+ return new Property(this.getName(prop), this.getDoc(prop), schema, {
1203
+ summary: this.getSummary(prop),
1204
+ required: !prop.optional,
1205
+ nullable: nullable,
1206
+ readOnly: this.isReadOnly(prop),
1207
+ // clientDefaultValue: this.getDefaultValue(prop.default),
1208
+ serializedName: this.getSerializedName(prop),
1209
+ });
1210
+ }
1211
+ processFormatString(type, format, nameHint) {
1212
+ switch (format) {
1213
+ case "byte":
1214
+ return this.processByteArraySchema(type, nameHint, true);
1215
+ case "binary":
1216
+ return this.processByteArraySchema(type, nameHint, false);
1217
+ case "date-time":
1218
+ return this.processDateTimeSchema(type, nameHint, false);
1219
+ case "date-time-rfc1123":
1220
+ return this.processDateTimeSchema(type, nameHint, true);
1221
+ case "password":
1222
+ case "url":
1223
+ case "uuid":
1224
+ return this.processStringSchema(type, nameHint);
1225
+ }
1226
+ throw new Error(`Unrecognized string format: '${format}'.`);
1227
+ }
1228
+ processUnionSchema(type, name) {
1229
+ const nonNullVariants = Array.from(type.variants.values()).filter((it) => !isNullType(it.type));
1230
+ if (nonNullVariants.length === 1) {
1231
+ // nullable
1232
+ return this.processSchema(nonNullVariants[0].type, name);
1233
+ }
1234
+ if (this.isSameLiteralTypes(nonNullVariants)) {
1235
+ // enum
1236
+ return this.processChoiceSchemaForUnion(type, nonNullVariants, name);
1237
+ }
1238
+ // TODO: name from typespec-client-generator-core
1239
+ const namespace = getNamespace(type);
1240
+ const unionSchema = new OrSchema(pascalCase(name) + "ModelBase", this.getDoc(type), {
1241
+ summary: this.getSummary(type),
1242
+ });
1243
+ unionSchema.anyOf = [];
1244
+ nonNullVariants.forEach((it) => {
1245
+ const variantName = this.getUnionVariantName(it.type, { depth: 0 });
1246
+ const modelName = variantName + pascalCase(name) + "Model";
1247
+ const propertyName = "value";
1248
+ // these ObjectSchema is not added to codeModel.schemas
1249
+ const objectSchema = new ObjectSchema(modelName, this.getDoc(type), {
1250
+ summary: this.getSummary(type),
1251
+ language: {
1252
+ default: {
1253
+ namespace: namespace,
1254
+ },
1255
+ java: {
1256
+ namespace: getJavaNamespace(namespace),
1257
+ },
1258
+ },
1259
+ });
1260
+ const variantSchema = this.processSchema(it.type, variantName);
1261
+ objectSchema.addProperty(new Property(propertyName, this.getDoc(type), variantSchema, {
1262
+ summary: this.getSummary(type),
1263
+ required: true,
1264
+ nullable: true,
1265
+ readOnly: false,
1266
+ }));
1267
+ unionSchema.anyOf.push(objectSchema);
1268
+ });
1269
+ return this.codeModel.schemas.add(unionSchema);
1270
+ }
1271
+ processBinarySchema(name) {
1272
+ return this.codeModel.schemas.add(new BinarySchema(name));
1273
+ }
1274
+ getUnionVariantName(type, option) {
1275
+ switch (type.kind) {
1276
+ case "Scalar": {
1277
+ const scalarName = type.name;
1278
+ let name = type.name;
1279
+ if (scalarName.startsWith("int") || scalarName.startsWith("uint") || scalarName === "safeint") {
1280
+ name = scalarName === "safeint" || scalarName.includes("int64") ? "Long" : "Integer";
1281
+ }
1282
+ else if (scalarName.startsWith("float")) {
1283
+ name = "Double";
1284
+ }
1285
+ else if (scalarName === "bytes") {
1286
+ name = "ByteArray";
1287
+ }
1288
+ else if (scalarName === "zonedDateTime") {
1289
+ name = "Time";
1290
+ }
1291
+ return pascalCase(name);
1292
+ }
1293
+ case "Enum":
1294
+ return pascalCase(type.name);
1295
+ case "Model":
1296
+ if (isArrayModelType(this.program, type)) {
1297
+ ++option.depth;
1298
+ if (option.depth == 1) {
1299
+ return this.getUnionVariantName(type.indexer.value, option) + "List";
1300
+ }
1301
+ else {
1302
+ return "ListOf" + this.getUnionVariantName(type.indexer.value, option);
1303
+ }
1304
+ }
1305
+ else if (isRecordModelType(this.program, type)) {
1306
+ ++option.depth;
1307
+ if (option.depth == 1) {
1308
+ return this.getUnionVariantName(type.indexer.value, option) + "Map";
1309
+ }
1310
+ else {
1311
+ return "MapOf" + this.getUnionVariantName(type.indexer.value, option);
1312
+ }
1313
+ }
1314
+ else {
1315
+ return pascalCase(type.name);
1316
+ }
1317
+ default:
1318
+ throw new Error(`Unrecognized type for union variable: '${type.kind}'.`);
1319
+ }
1320
+ }
1321
+ isNullableType(type) {
1322
+ if (type.kind === "Union") {
1323
+ const nullVariants = Array.from(type.variants.values()).filter((it) => isNullType(it.type));
1324
+ return nullVariants.length >= 1;
1325
+ }
1326
+ else {
1327
+ return false;
1328
+ }
1329
+ }
1330
+ isSameLiteralTypes(variants) {
1331
+ const kindSet = new Set(variants.map((it) => it.type.kind));
1332
+ if (kindSet.size === 1) {
1333
+ const kind = kindSet.values().next().value;
1334
+ return kind === "String" || kind === "Number" || kind === "Boolean";
1335
+ }
1336
+ else {
1337
+ return false;
1338
+ }
1339
+ }
1340
+ getDefaultValue(type) {
1341
+ if (type) {
1342
+ switch (type.kind) {
1343
+ case "String":
1344
+ return type.value;
1345
+ case "Number":
1346
+ return type.value;
1347
+ case "Boolean":
1348
+ return type.value;
1349
+ // case "Tuple":
1350
+ // return type.values.map(getDefaultValue);
1351
+ }
1352
+ }
1353
+ return undefined;
1354
+ }
1355
+ getDoc(target) {
1356
+ return getDoc(this.program, target) || "";
1357
+ }
1358
+ getSummary(target) {
1359
+ return getSummary(this.program, target);
1360
+ }
1361
+ getName(target) {
1362
+ // TODO: once getLibraryName API in typespec-client-generator-core can get projected name from language and client, as well as can handle template case, use getLibraryName API
1363
+ const languageProjectedName = getProjectedName(this.program, target, "java");
1364
+ if (languageProjectedName) {
1365
+ return languageProjectedName;
1366
+ }
1367
+ const clientProjectedName = getProjectedName(this.program, target, "client");
1368
+ if (clientProjectedName) {
1369
+ return clientProjectedName;
1370
+ }
1371
+ const friendlyName = getFriendlyName(this.program, target);
1372
+ if (friendlyName) {
1373
+ return friendlyName;
1374
+ }
1375
+ // if no projectedName and friendlyName found, return the name of the target (including special handling for template)
1376
+ if (target.kind === "Model" &&
1377
+ target.templateMapper &&
1378
+ target.templateMapper.args &&
1379
+ target.templateMapper.args.length > 0) {
1380
+ const tspName = getTypeName(target, this.typeNameOptions);
1381
+ const newName = getNameForTemplate(target);
1382
+ this.logWarning(`Rename TypeSpec model '${tspName}' to '${newName}'`);
1383
+ return newName;
1384
+ }
1385
+ return target.name;
1386
+ }
1387
+ getSerializedName(target) {
1388
+ // First get projected name, if not found, return target.name
1389
+ const jsonProjectedName = getProjectedName(this.program, target, "json");
1390
+ if (jsonProjectedName) {
1391
+ return jsonProjectedName;
1392
+ }
1393
+ return target.name;
1394
+ }
1395
+ isReadOnly(target) {
1396
+ // const key = isKey(this.program, target);
1397
+ const segment = getSegment(this.program, target) !== undefined;
1398
+ if (segment) {
1399
+ return true;
1400
+ }
1401
+ else {
1402
+ const visibility = getVisibility(this.program, target);
1403
+ if (visibility) {
1404
+ return (!visibility.includes("write") &&
1405
+ !visibility.includes("create") &&
1406
+ !visibility.includes("update") &&
1407
+ !visibility.includes("delete") &&
1408
+ !visibility.includes("query"));
1409
+ }
1410
+ else {
1411
+ return false;
1412
+ }
1413
+ }
1414
+ }
1415
+ getConvenienceApiName(op) {
1416
+ // check @convenienceMethod
1417
+ if (shouldGenerateConvenient(this.dpgContext, op)) {
1418
+ return this.getName(op);
1419
+ }
1420
+ else {
1421
+ return undefined;
1422
+ }
1423
+ }
1424
+ logWarning(msg) {
1425
+ this.program.trace("typespec-java", msg);
1426
+ this.program.reportDiagnostic({
1427
+ code: "typespec-java",
1428
+ severity: "warning",
1429
+ message: msg,
1430
+ target: NoTarget,
1431
+ });
1432
+ }
1433
+ get stringSchema() {
1434
+ return (this._stringSchema ||
1435
+ (this._stringSchema = this.codeModel.schemas.add(new StringSchema("string", "simple string"))));
1436
+ }
1437
+ get integerSchema() {
1438
+ return (this._integerSchema ||
1439
+ (this._integerSchema = this.codeModel.schemas.add(new NumberSchema("integer", "simple integer", SchemaType.Integer, 64))));
1440
+ }
1441
+ get booleanSchema() {
1442
+ return (this._booleanSchema ||
1443
+ (this._booleanSchema = this.codeModel.schemas.add(new BooleanSchema("boolean", "simple boolean"))));
1444
+ }
1445
+ get binarySchema() {
1446
+ return this._binarySchema || (this._binarySchema = this.codeModel.schemas.add(new BinarySchema("binary")));
1447
+ }
1448
+ get anySchema() {
1449
+ var _a;
1450
+ return (_a = this._anySchema) !== null && _a !== void 0 ? _a : (this._anySchema = this.codeModel.schemas.add(new AnySchema("Anything")));
1451
+ }
1452
+ createApiVersionParameter(serializedName, parameterLocation) {
1453
+ return new Parameter(serializedName, "Version parameter", this.codeModel.schemas.add(new ConstantSchema(serializedName, "API Version", {
1454
+ valueType: this.stringSchema,
1455
+ value: new ConstantValue(""),
1456
+ })), {
1457
+ implementation: ImplementationLocation.Client,
1458
+ origin: originApiVersion,
1459
+ required: true,
1460
+ protocol: {
1461
+ http: new HttpParameter(parameterLocation),
1462
+ },
1463
+ language: {
1464
+ default: {
1465
+ serializedName: serializedName,
1466
+ },
1467
+ },
1468
+ });
1469
+ }
1470
+ get apiVersionParameter() {
1471
+ return (this._apiVersionParameter ||
1472
+ (this._apiVersionParameter = this.createApiVersionParameter("api-version", ParameterLocation.Query)));
1473
+ }
1474
+ get apiVersionParameterInPath() {
1475
+ return (this._apiVersionParameterInPath ||
1476
+ // TODO: hardcode as "apiVersion", as it is what we get from compiler
1477
+ (this._apiVersionParameterInPath = this.createApiVersionParameter("apiVersion", ParameterLocation.Path)));
1478
+ }
1479
+ propagateSchemaUsage(schema) {
1480
+ var _a;
1481
+ const processedSchemas = new Set();
1482
+ const innerApplySchemaUsage = (schema, schemaUsage) => {
1483
+ this.trackSchemaUsage(schema, schemaUsage);
1484
+ innerPropagateSchemaUsage(schema, schemaUsage);
1485
+ };
1486
+ const innerPropagateSchemaUsage = (schema, schemaUsage) => {
1487
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1488
+ if (processedSchemas.has(schema)) {
1489
+ return;
1490
+ }
1491
+ processedSchemas.add(schema);
1492
+ if (schema instanceof ObjectSchema) {
1493
+ if (schemaUsage.usage || schemaUsage.serializationFormats) {
1494
+ (_a = schema.properties) === null || _a === void 0 ? void 0 : _a.forEach((p) => innerApplySchemaUsage(p.schema, schemaUsage));
1495
+ (_c = (_b = schema.parents) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.forEach((p) => innerApplySchemaUsage(p, schemaUsage));
1496
+ (_e = (_d = schema.parents) === null || _d === void 0 ? void 0 : _d.immediate) === null || _e === void 0 ? void 0 : _e.forEach((p) => innerApplySchemaUsage(p, schemaUsage));
1497
+ (_g = (_f = schema.children) === null || _f === void 0 ? void 0 : _f.all) === null || _g === void 0 ? void 0 : _g.forEach((c) => innerApplySchemaUsage(c, schemaUsage));
1498
+ (_j = (_h = schema.children) === null || _h === void 0 ? void 0 : _h.immediate) === null || _j === void 0 ? void 0 : _j.forEach((c) => innerApplySchemaUsage(c, schemaUsage));
1499
+ // Object.values(schema.discriminator?.all ?? {}).forEach((d) => {
1500
+ // innerApplySchemaUsage(d, schemaUsage);
1501
+ // });
1502
+ // Object.values(schema.discriminator?.immediate ?? {}).forEach((d) => {
1503
+ // innerApplySchemaUsage(d, schemaUsage);
1504
+ // });
1505
+ }
1506
+ }
1507
+ else if (schema instanceof DictionarySchema) {
1508
+ innerApplySchemaUsage(schema.elementType, schemaUsage);
1509
+ }
1510
+ else if (schema instanceof ArraySchema) {
1511
+ innerApplySchemaUsage(schema.elementType, schemaUsage);
1512
+ }
1513
+ else if (schema instanceof OrSchema) {
1514
+ (_k = schema.anyOf) === null || _k === void 0 ? void 0 : _k.forEach((it) => innerApplySchemaUsage(it, schemaUsage));
1515
+ }
1516
+ };
1517
+ // Exclude context that not to be propagated
1518
+ const schemaUsage = {
1519
+ usage: (_a = schema.usage) === null || _a === void 0 ? void 0 : _a.filter((it) => it !== SchemaContext.Paged && it !== SchemaContext.Anonymous),
1520
+ serializationFormats: schema.serializationFormats,
1521
+ };
1522
+ // Propagate the usage of the initial schema itself
1523
+ innerPropagateSchemaUsage(schema, schemaUsage);
1524
+ }
1525
+ trackSchemaUsage(schema, schemaUsage) {
1526
+ if (schema instanceof ObjectSchema ||
1527
+ schema instanceof GroupSchema ||
1528
+ schema instanceof ChoiceSchema ||
1529
+ schema instanceof SealedChoiceSchema ||
1530
+ schema instanceof OrSchema) {
1531
+ if (schemaUsage.usage) {
1532
+ pushDistinct((schema.usage = schema.usage || []), ...schemaUsage.usage);
1533
+ }
1534
+ }
1535
+ else if (schema instanceof DictionarySchema) {
1536
+ this.trackSchemaUsage(schema.elementType, schemaUsage);
1537
+ }
1538
+ else if (schema instanceof ArraySchema) {
1539
+ this.trackSchemaUsage(schema.elementType, schemaUsage);
1540
+ }
1541
+ }
1542
+ }
1543
+ /** Acts as a cache for processing inputs.
1544
+ *
1545
+ * If the input is undefined, the output is always undefined.
1546
+ * for a given input, the process is only ever called once.
1547
+ *
1548
+ *
1549
+ */
1550
+ class ProcessingCache {
1551
+ constructor(transform) {
1552
+ this.transform = transform;
1553
+ this.results = new Map();
1554
+ }
1555
+ has(original) {
1556
+ return !!original && !!this.results.get(original);
1557
+ }
1558
+ set(original, result) {
1559
+ this.results.set(original, result);
1560
+ return result;
1561
+ }
1562
+ process(original, ...args) {
1563
+ if (original) {
1564
+ const result = this.results.get(original) || this.transform(original, ...args);
1565
+ this.results.set(original, result);
1566
+ return result;
1567
+ }
1568
+ return undefined;
1569
+ }
1570
+ }
1571
+ /** adds only if the item is not in the collection already
1572
+ *
1573
+ * @note While this isn't very efficient, it doesn't disturb the original
1574
+ * collection, so you won't get inadvertent side effects from using Set, etc.
1575
+ */
1576
+ function pushDistinct(targetArray, ...items) {
1577
+ for (const i of items) {
1578
+ if (!targetArray.includes(i)) {
1579
+ targetArray.push(i);
1580
+ }
1581
+ }
1582
+ return targetArray;
1583
+ }
1584
+ function getNamespace(type) {
1585
+ let namespaceRef = type.namespace;
1586
+ let namespaceStr = undefined;
1587
+ while (namespaceRef && namespaceRef.name.length !== 0) {
1588
+ namespaceStr = namespaceRef.name + (namespaceStr ? "." + namespaceStr : "");
1589
+ namespaceRef = namespaceRef.namespace;
1590
+ }
1591
+ return namespaceStr;
1592
+ }
1593
+ function getJavaNamespace(namespace) {
1594
+ return namespace ? "com." + namespace.toLowerCase() : undefined;
1595
+ }
1596
+ function modelContainsDerivedModel(model) {
1597
+ return !isTemplateDeclaration(model) && !(isTemplateInstance(model) && model.derivedModels.length === 0);
1598
+ }
1599
+ function isModelReferredInTemplate(template, target) {
1600
+ var _a, _b, _c;
1601
+ return (template === target ||
1602
+ ((_c = (_b = (_a = template === null || template === void 0 ? void 0 : template.templateMapper) === null || _a === void 0 ? void 0 : _a.args) === null || _b === void 0 ? void 0 : _b.some((it) => it.kind === "Model" || it.kind === "Union" ? isModelReferredInTemplate(it, target) : false)) !== null && _c !== void 0 ? _c : false));
1603
+ }
1604
+ function getNameForTemplate(target) {
1605
+ switch (target.kind) {
1606
+ case "Model": {
1607
+ let name = target.name;
1608
+ if (target.templateMapper && target.templateMapper.args) {
1609
+ name = name + target.templateMapper.args.map((it) => getNameForTemplate(it)).join("");
1610
+ }
1611
+ return name;
1612
+ }
1613
+ case "String":
1614
+ return target.value;
1615
+ default:
1616
+ return "";
1617
+ }
1618
+ }
1619
+ function containsIgnoreCase(stringList, str) {
1620
+ return stringList && str ? stringList.findIndex((s) => s.toLowerCase() === str.toLowerCase()) != -1 : false;
1621
+ }
1622
+ function operationContainsJsonMergePatch(op) {
1623
+ for (const param of op.parameters.parameters) {
1624
+ if (param.type === "header" && param.name.toLowerCase() === "content-type") {
1625
+ if (param.param.type.kind === "String" && param.param.type.value === "application/merge-patch+json") {
1626
+ return true;
1627
+ }
1628
+ }
1629
+ }
1630
+ return false;
1631
+ }
1632
+ function pascalCase(name) {
1633
+ if (name.length > 0) {
1634
+ return name[0].toUpperCase() + name.slice(1);
1635
+ }
1636
+ else {
1637
+ return name;
1638
+ }
1639
+ }
1640
+ function isPayloadProperty(program, property) {
1641
+ const headerInfo = getHeaderFieldName(program, property);
1642
+ const queryInfo = getQueryParamName(program, property);
1643
+ const pathInfo = getPathParamName(program, property);
1644
+ const statusCodeInfo = isStatusCode(program, property);
1645
+ return !(headerInfo || queryInfo || pathInfo || statusCodeInfo);
1646
+ }
1647
+ function getClientApiVersions(client) {
1648
+ var _a;
1649
+ if ((_a = client.globalParameters) === null || _a === void 0 ? void 0 : _a.find((it) => it.origin === originApiVersion)) {
1650
+ return client.apiVersions;
1651
+ }
1652
+ else {
1653
+ return undefined;
1654
+ }
1655
+ }
1656
+ function getServiceVersion(client) {
1657
+ let name = client.language.default.name;
1658
+ let description = name;
1659
+ if (name.endsWith("Client")) {
1660
+ name = name.substring(0, name.length - "Client".length);
1661
+ }
1662
+ else {
1663
+ description = description + "Client";
1664
+ }
1665
+ if (name.endsWith("Service")) {
1666
+ name = name + "Version";
1667
+ }
1668
+ else {
1669
+ name = name + "ServiceVersion";
1670
+ }
1671
+ return new ServiceVersion(name, description);
1672
+ }
1673
+ const specialHeaderNames = new Set(["repeatability-request-id", "repeatability-first-sent"]);
1674
+ const originApiVersion = "modelerfour:synthesized/api-version";
1675
+ //# sourceMappingURL=code-model-builder.js.map