@azure-tools/typespec-java 0.25.0 → 0.26.1

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.
@@ -1,8 +1,8 @@
1
1
  import { AnySchema, ApiVersion, ArraySchema, BinaryResponse, BinarySchema, BooleanSchema, ByteArraySchema, ChoiceValue, DateSchema, DateTimeSchema, DictionarySchema, Discriminator, GroupProperty, GroupSchema, HttpHeader, HttpParameter, ImplementationLocation, KeySecurityScheme, Language, Metadata, NumberSchema, OAuth2SecurityScheme, ObjectSchema, OperationGroup, Parameter, ParameterLocation, Property, Relations, Response, SchemaResponse, SchemaType, Security, SerializationStyle, StringSchema, TimeSchema, UnixTimeSchema, UriSchema, VirtualParameter, } from "@autorest/codemodel";
2
2
  import { KnownMediaType } from "@azure-tools/codegen";
3
3
  import { createSdkContext, getAllModels, getWireName, isApiVersion, isSdkBuiltInKind, isSdkIntKind, } from "@azure-tools/typespec-client-generator-core";
4
- import { getDoc, getEffectiveModelType, getNamespaceFullName, getOverloadedOperation, getSummary, getVisibility, isArrayModelType, isRecordModelType, listServices, } from "@typespec/compiler";
5
- import { Visibility, getAuthentication, getHeaderFieldName, getPathParamName, getQueryParamName, isHeader, isPathParam, isQueryParam, } from "@typespec/http";
4
+ import { getDoc, getEffectiveModelType, getNamespaceFullName, getOverloadedOperation, getSummary, isArrayModelType, isRecordModelType, listServices, } from "@typespec/compiler";
5
+ import { Visibility, getAuthentication, getHeaderFieldName, getPathParamName, getQueryParamName, isCookieParam, isHeader, isPathParam, isQueryParam, } from "@typespec/http";
6
6
  import { getSegment } from "@typespec/rest";
7
7
  import { getAddedOnVersions } from "@typespec/versioning";
8
8
  import { fail } from "assert";
@@ -20,7 +20,7 @@ import { createPollOperationDetailsSchema, getFileDetailsSchema } from "./extern
20
20
  import { ClientContext } from "./models.js";
21
21
  import { CONTENT_TYPE_KEY, ORIGIN_API_VERSION, SPECIAL_HEADER_NAMES, cloneOperationParameter, getServiceVersion, isKnownContentType, isLroNewPollingStrategy, isPayloadProperty, operationIsJsonMergePatch, operationIsMultipart, operationIsMultipleContentTypes, } from "./operation-utils.js";
22
22
  import { ProcessingCache, getAccess, getDurationFormat, getNonNullSdkType, getUnionDescription, getUsage, isStable, modelIs, pushDistinct, } from "./type-utils.js";
23
- import { getNamespace, logWarning, pascalCase, removeClientSuffix, stringArrayContainsIgnoreCase, trace, } from "./utils.js";
23
+ import { getNamespace, logError, logWarning, pascalCase, removeClientSuffix, stringArrayContainsIgnoreCase, trace, } from "./utils.js";
24
24
  const { isEqual } = pkg;
25
25
  export class CodeModelBuilder {
26
26
  constructor(program1, context) {
@@ -39,12 +39,10 @@ export class CodeModelBuilder {
39
39
  }
40
40
  const service = listServices(this.program)[0];
41
41
  if (!service) {
42
- throw Error("TypeSpec for HTTP must define a service.");
42
+ this.logError("TypeSpec for HTTP must define a service.");
43
43
  }
44
44
  this.serviceNamespace = service.type;
45
45
  this.namespace = getNamespaceFullName(this.serviceNamespace) || "Azure.Client";
46
- // java namespace
47
- const javaNamespace = this.getJavaNamespace(this.namespace);
48
46
  const namespace1 = this.namespace;
49
47
  this.typeNameOptions = {
50
48
  // shorten type names by removing TypeSpec and service namespace
@@ -67,9 +65,7 @@ export class CodeModelBuilder {
67
65
  summary: this.getSummary(this.serviceNamespace),
68
66
  namespace: this.namespace,
69
67
  },
70
- java: {
71
- namespace: javaNamespace,
72
- },
68
+ java: {},
73
69
  },
74
70
  });
75
71
  }
@@ -77,6 +73,20 @@ export class CodeModelBuilder {
77
73
  this.sdkContext = await createSdkContext(this.emitterContext, "@azure-tools/typespec-java", {
78
74
  versioning: { previewStringRegex: /$/ },
79
75
  }); // include all versions and do the filter by ourselves
76
+ // java namespace
77
+ if (this.options.namespace) {
78
+ // legacy mode, clientNamespace from TCGC will be ignored
79
+ this.legacyJavaNamespace = true;
80
+ this.baseJavaNamespace = this.options.namespace;
81
+ }
82
+ else {
83
+ this.legacyJavaNamespace = false;
84
+ // baseJavaNamespace is used for model from Azure.Core/Azure.ResourceManager but cannot be mapped to azure-core,
85
+ // or some model (e.g. Options, FileDetails) that is created in this emitter.
86
+ // otherwise, the clientNamespace from SdkType will be used.
87
+ this.baseJavaNamespace = this.getBaseJavaNamespace();
88
+ }
89
+ this.codeModel.language.java.namespace = this.baseJavaNamespace;
80
90
  // TODO: reportDiagnostics from TCGC temporary disabled
81
91
  // issue https://github.com/Azure/typespec-azure/issues/1675
82
92
  // this.program.reportDiagnostics(this.sdkContext.diagnostics);
@@ -108,7 +118,7 @@ export class CodeModelBuilder {
108
118
  else {
109
119
  const schema = this.processSchema(arg.type, arg.name);
110
120
  this.trackSchemaUsage(schema, {
111
- usage: [SchemaContext.Input, SchemaContext.Output /*SchemaContext.Public*/],
121
+ usage: [SchemaContext.Input, SchemaContext.Output, SchemaContext.Public],
112
122
  });
113
123
  parameter = new Parameter(arg.name, (_a = arg.doc) !== null && _a !== void 0 ? _a : "", schema, {
114
124
  implementation: ImplementationLocation.Client,
@@ -149,10 +159,15 @@ export class CodeModelBuilder {
149
159
  break;
150
160
  case "apiKey":
151
161
  {
152
- const keyScheme = new KeySecurityScheme({
153
- name: scheme.name,
154
- });
155
- securitySchemes.push(keyScheme);
162
+ if (scheme.in === "header") {
163
+ const keyScheme = new KeySecurityScheme({
164
+ name: scheme.name,
165
+ });
166
+ securitySchemes.push(keyScheme);
167
+ }
168
+ else {
169
+ this.logWarning(`ApiKey auth is currently only supported for ApiKeyLocation.header.`);
170
+ }
156
171
  }
157
172
  break;
158
173
  case "http":
@@ -163,7 +178,7 @@ export class CodeModelBuilder {
163
178
  schemeOrApiKeyPrefix = pascalCase(schemeOrApiKeyPrefix);
164
179
  if (this.isBranded()) {
165
180
  // Azure would not allow BasicAuth or BearerAuth
166
- this.logWarning(`${scheme.scheme} auth method is currently not supported.`);
181
+ this.logWarning(`HTTP auth with ${scheme.scheme} scheme is not supported for Azure.`);
167
182
  continue;
168
183
  }
169
184
  }
@@ -184,7 +199,8 @@ export class CodeModelBuilder {
184
199
  }
185
200
  }
186
201
  isBranded() {
187
- return !this.options["flavor"] || this.options["flavor"].toLocaleLowerCase() === "azure";
202
+ var _a;
203
+ return ((_a = this.options["flavor"]) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === "azure";
188
204
  }
189
205
  processModels() {
190
206
  const processedSdkModels = new Set();
@@ -291,96 +307,110 @@ export class CodeModelBuilder {
291
307
  }
292
308
  }
293
309
  processClients() {
294
- var _a, _b, _c;
310
+ var _a;
295
311
  // preprocess group-etag-headers
296
312
  this.options["group-etag-headers"] = (_a = this.options["group-etag-headers"]) !== null && _a !== void 0 ? _a : true;
297
313
  const sdkPackage = this.sdkContext.sdkPackage;
298
314
  for (const client of sdkPackage.clients) {
299
- let clientName = client.name;
300
- let javaNamespace = this.getJavaNamespace(this.namespace);
301
- const clientFullName = client.name;
302
- const clientNameSegments = clientFullName.split(".");
303
- if (clientNameSegments.length > 1) {
304
- clientName = clientNameSegments.at(-1);
305
- const clientSubNamespace = clientNameSegments.slice(0, -1).join(".");
306
- javaNamespace = this.getJavaNamespace(this.namespace + "." + clientSubNamespace);
307
- }
308
- const codeModelClient = new CodeModelClient(clientName, (_b = client.doc) !== null && _b !== void 0 ? _b : "", {
309
- summary: client.summary,
310
- language: {
311
- default: {
312
- namespace: this.namespace,
313
- },
314
- java: {
315
- namespace: javaNamespace,
316
- },
315
+ this.processClient(client);
316
+ }
317
+ }
318
+ processClient(client) {
319
+ var _a, _b;
320
+ let clientName = client.name;
321
+ let javaNamespace = this.getJavaNamespace(client);
322
+ const clientFullName = client.name;
323
+ const clientNameSegments = clientFullName.split(".");
324
+ if (clientNameSegments.length > 1) {
325
+ clientName = clientNameSegments.at(-1);
326
+ const clientSubNamespace = clientNameSegments.slice(0, -1).join(".").toLowerCase();
327
+ javaNamespace = javaNamespace + "." + clientSubNamespace;
328
+ }
329
+ const codeModelClient = new CodeModelClient(clientName, (_a = client.doc) !== null && _a !== void 0 ? _a : "", {
330
+ summary: client.summary,
331
+ language: {
332
+ default: {
333
+ namespace: this.namespace,
317
334
  },
318
- // at present, use global security definition
319
- security: this.codeModel.security,
320
- });
321
- codeModelClient.crossLanguageDefinitionId = client.crossLanguageDefinitionId;
322
- // versioning
323
- const versions = client.apiVersions;
324
- if (versions && versions.length > 0) {
325
- if (!this.sdkContext.apiVersion || ["all", "latest"].includes(this.sdkContext.apiVersion)) {
326
- this.apiVersion = versions[versions.length - 1];
327
- }
328
- else {
329
- this.apiVersion = versions.find((it) => it === this.sdkContext.apiVersion);
330
- if (!this.apiVersion) {
331
- throw new Error("Unrecognized api-version: " + this.sdkContext.apiVersion);
332
- }
333
- }
334
- codeModelClient.apiVersions = [];
335
- for (const version of this.getFilteredApiVersions(this.apiVersion, versions, this.options["service-version-exclude-preview"])) {
336
- const apiVersion = new ApiVersion();
337
- apiVersion.version = version;
338
- codeModelClient.apiVersions.push(apiVersion);
335
+ java: {
336
+ namespace: javaNamespace,
337
+ },
338
+ },
339
+ // at present, use global security definition
340
+ security: this.codeModel.security,
341
+ });
342
+ codeModelClient.crossLanguageDefinitionId = client.crossLanguageDefinitionId;
343
+ // versioning
344
+ const versions = client.apiVersions;
345
+ if (versions && versions.length > 0) {
346
+ if (!this.sdkContext.apiVersion || ["all", "latest"].includes(this.sdkContext.apiVersion)) {
347
+ this.apiVersion = versions[versions.length - 1];
348
+ }
349
+ else {
350
+ this.apiVersion = versions.find((it) => it === this.sdkContext.apiVersion);
351
+ if (!this.apiVersion) {
352
+ this.logError("Unrecognized api-version: " + this.sdkContext.apiVersion);
339
353
  }
340
354
  }
341
- // client initialization
342
- let baseUri = "{endpoint}";
343
- let hostParameters = [];
344
- client.initialization.properties.forEach((initializationProperty) => {
345
- if (initializationProperty.kind === "endpoint") {
346
- let sdkPathParameters = [];
347
- if (initializationProperty.type.kind === "union") {
348
- if (initializationProperty.type.variantTypes.length === 2) {
349
- // only get the sdkPathParameters from the endpoint whose serverUrl is not {"endpoint"}
350
- for (const endpointType of initializationProperty.type.variantTypes) {
351
- if (endpointType.kind === "endpoint" && endpointType.serverUrl !== "{endpoint}") {
352
- sdkPathParameters = endpointType.templateArguments;
353
- baseUri = endpointType.serverUrl;
354
- }
355
+ codeModelClient.apiVersions = [];
356
+ for (const version of this.getFilteredApiVersions(this.apiVersion, versions, this.options["service-version-exclude-preview"])) {
357
+ const apiVersion = new ApiVersion();
358
+ apiVersion.version = version;
359
+ codeModelClient.apiVersions.push(apiVersion);
360
+ }
361
+ }
362
+ // client initialization
363
+ let baseUri = "{endpoint}";
364
+ let hostParameters = [];
365
+ client.initialization.properties.forEach((initializationProperty) => {
366
+ if (initializationProperty.kind === "endpoint") {
367
+ let sdkPathParameters = [];
368
+ if (initializationProperty.type.kind === "union") {
369
+ if (initializationProperty.type.variantTypes.length === 2) {
370
+ // only get the sdkPathParameters from the endpoint whose serverUrl is not {"endpoint"}
371
+ for (const endpointType of initializationProperty.type.variantTypes) {
372
+ if (endpointType.kind === "endpoint" && endpointType.serverUrl !== "{endpoint}") {
373
+ sdkPathParameters = endpointType.templateArguments;
374
+ baseUri = endpointType.serverUrl;
355
375
  }
356
376
  }
357
- else if (initializationProperty.type.variantTypes.length > 2) {
358
- throw new Error("Multiple server url defined for one client is not supported yet.");
359
- }
360
377
  }
361
- else if (initializationProperty.type.kind === "endpoint") {
362
- sdkPathParameters = initializationProperty.type.templateArguments;
363
- baseUri = initializationProperty.type.serverUrl;
378
+ else if (initializationProperty.type.variantTypes.length > 2) {
379
+ this.logError("Multiple server url defined for one client is not supported yet.");
364
380
  }
365
- hostParameters = this.processHostParameters(sdkPathParameters);
366
- codeModelClient.addGlobalParameters(hostParameters);
367
381
  }
368
- });
369
- const clientContext = new ClientContext(baseUri, hostParameters, codeModelClient.globalParameters, codeModelClient.apiVersions);
370
- // preprocess operation groups and operations
371
- // operations without operation group
372
- const serviceMethodsWithoutSubClient = this.listServiceMethodsUnderClient(client);
373
- let codeModelGroup = new OperationGroup("");
374
- for (const serviceMethod of serviceMethodsWithoutSubClient) {
375
- if (!this.needToSkipProcessingOperation(serviceMethod.__raw, clientContext)) {
376
- codeModelGroup.addOperation(this.processOperation(serviceMethod, clientContext, ""));
382
+ else if (initializationProperty.type.kind === "endpoint") {
383
+ sdkPathParameters = initializationProperty.type.templateArguments;
384
+ baseUri = initializationProperty.type.serverUrl;
377
385
  }
386
+ hostParameters = this.processHostParameters(sdkPathParameters);
387
+ codeModelClient.addGlobalParameters(hostParameters);
378
388
  }
379
- if (((_c = codeModelGroup.operations) === null || _c === void 0 ? void 0 : _c.length) > 0) {
380
- codeModelClient.operationGroups.push(codeModelGroup);
389
+ });
390
+ const clientContext = new ClientContext(baseUri, hostParameters, codeModelClient.globalParameters, codeModelClient.apiVersions);
391
+ const enableSubclient = Boolean(this.options["enable-subclient"]);
392
+ // preprocess operation groups and operations
393
+ // operations without operation group
394
+ const serviceMethodsWithoutSubClient = this.listServiceMethodsUnderClient(client);
395
+ let codeModelGroup = new OperationGroup("");
396
+ for (const serviceMethod of serviceMethodsWithoutSubClient) {
397
+ if (!this.needToSkipProcessingOperation(serviceMethod.__raw, clientContext)) {
398
+ codeModelGroup.addOperation(this.processOperation(serviceMethod, clientContext, ""));
399
+ }
400
+ }
401
+ if (((_b = codeModelGroup.operations) === null || _b === void 0 ? void 0 : _b.length) > 0 || enableSubclient) {
402
+ codeModelClient.operationGroups.push(codeModelGroup);
403
+ }
404
+ const subClients = this.listSubClientsUnderClient(client, !enableSubclient);
405
+ if (enableSubclient) {
406
+ // subclient, no operation group
407
+ for (const subClient of subClients) {
408
+ const codeModelSubclient = this.processClient(subClient);
409
+ codeModelClient.addSubClient(codeModelSubclient);
381
410
  }
411
+ }
412
+ else {
382
413
  // operations under operation groups
383
- const subClients = this.listSubClientsUnderClient(client, true, true);
384
414
  for (const subClient of subClients) {
385
415
  const serviceMethods = this.listServiceMethodsUnderClient(subClient);
386
416
  // operation group with no operation is skipped
@@ -394,45 +424,47 @@ export class CodeModelBuilder {
394
424
  codeModelClient.operationGroups.push(codeModelGroup);
395
425
  }
396
426
  }
397
- this.codeModel.clients.push(codeModelClient);
398
- // postprocess for ServiceVersion
399
- let apiVersionSameForAllClients = true;
400
- let sharedApiVersions = undefined;
401
- for (const client of this.codeModel.clients) {
402
- const apiVersions = client.apiVersions;
403
- if (!apiVersions) {
404
- // client does not have apiVersions
405
- apiVersionSameForAllClients = false;
406
- }
407
- else if (!sharedApiVersions) {
408
- // first client, set it to sharedApiVersions
409
- sharedApiVersions = apiVersions;
410
- }
411
- else {
412
- apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
413
- }
414
- if (!apiVersionSameForAllClients) {
415
- break;
416
- }
427
+ }
428
+ this.codeModel.clients.push(codeModelClient);
429
+ // postprocess for ServiceVersion
430
+ let apiVersionSameForAllClients = true;
431
+ let sharedApiVersions = undefined;
432
+ for (const client of this.codeModel.clients) {
433
+ const apiVersions = client.apiVersions;
434
+ if (!apiVersions) {
435
+ // client does not have apiVersions
436
+ apiVersionSameForAllClients = false;
417
437
  }
418
- if (apiVersionSameForAllClients) {
419
- const serviceVersion = getServiceVersion(this.codeModel);
420
- for (const client of this.codeModel.clients) {
421
- client.serviceVersion = serviceVersion;
422
- }
438
+ else if (!sharedApiVersions) {
439
+ // first client, set it to sharedApiVersions
440
+ sharedApiVersions = apiVersions;
423
441
  }
424
442
  else {
425
- for (const client of this.codeModel.clients) {
426
- const apiVersions = client.apiVersions;
427
- if (apiVersions) {
428
- client.serviceVersion = getServiceVersion(client);
429
- }
443
+ apiVersionSameForAllClients = isEqual(sharedApiVersions, apiVersions);
444
+ }
445
+ if (!apiVersionSameForAllClients) {
446
+ break;
447
+ }
448
+ }
449
+ if (apiVersionSameForAllClients) {
450
+ const serviceVersion = getServiceVersion(this.codeModel);
451
+ for (const client of this.codeModel.clients) {
452
+ client.serviceVersion = serviceVersion;
453
+ }
454
+ }
455
+ else {
456
+ for (const client of this.codeModel.clients) {
457
+ const apiVersions = client.apiVersions;
458
+ if (apiVersions) {
459
+ client.serviceVersion = getServiceVersion(client);
430
460
  }
431
461
  }
432
462
  }
463
+ return codeModelClient;
433
464
  }
434
- listSubClientsUnderClient(client, includeNestedOperationGroups, isRootClient) {
435
- const operationGroups = [];
465
+ listSubClientsUnderClient(client, includeNestedSubClients) {
466
+ const isRootClient = !client.parent;
467
+ const subClients = [];
436
468
  for (const method of client.methods) {
437
469
  if (method.kind === "clientaccessor") {
438
470
  const subClient = method.response;
@@ -441,15 +473,15 @@ export class CodeModelBuilder {
441
473
  subClient.name =
442
474
  removeClientSuffix(client.name) + removeClientSuffix(pascalCase(subClient.name));
443
475
  }
444
- operationGroups.push(subClient);
445
- if (includeNestedOperationGroups) {
446
- for (const operationGroup of this.listSubClientsUnderClient(subClient, includeNestedOperationGroups, false)) {
447
- operationGroups.push(operationGroup);
476
+ subClients.push(subClient);
477
+ if (includeNestedSubClients) {
478
+ for (const operationGroup of this.listSubClientsUnderClient(subClient, includeNestedSubClients)) {
479
+ subClients.push(operationGroup);
448
480
  }
449
481
  }
450
482
  }
451
483
  }
452
- return operationGroups;
484
+ return subClients;
453
485
  }
454
486
  listServiceMethodsUnderClient(client) {
455
487
  const methods = [];
@@ -578,6 +610,11 @@ export class CodeModelBuilder {
578
610
  clientContext.hostParameters.forEach((it) => codeModelOperation.addParameter(it));
579
611
  // path/query/header parameters
580
612
  for (const param of httpOperation.parameters) {
613
+ // TODO, switch to TCGC param.kind=="cookie"
614
+ if (param.__raw && isCookieParam(this.program, param.__raw)) {
615
+ // ignore cookie parameter
616
+ continue;
617
+ }
581
618
  // if it's paged operation with request body, skip content-type header added by TCGC, as next link call should not have content type header
582
619
  if ((sdkMethod.kind === "paging" || sdkMethod.kind === "lropaging") &&
583
620
  httpOperation.bodyParam &&
@@ -625,6 +662,10 @@ export class CodeModelBuilder {
625
662
  }
626
663
  processRouteForPaged(op, responses, sdkMethod) {
627
664
  var _a, _b;
665
+ if (!this.isBranded()) {
666
+ // TODO: currently unbranded does not support paged operation
667
+ return;
668
+ }
628
669
  if (sdkMethod.kind === "paging" || sdkMethod.kind === "lropaging") {
629
670
  for (const response of responses) {
630
671
  const bodyType = response.type;
@@ -664,7 +705,7 @@ export class CodeModelBuilder {
664
705
  language: {
665
706
  java: {
666
707
  name: "OperationLocationPollingStrategy",
667
- namespace: this.getJavaNamespace(this.namespace) + ".implementation",
708
+ namespace: this.baseJavaNamespace + ".implementation",
668
709
  },
669
710
  },
670
711
  });
@@ -1076,7 +1117,7 @@ export class CodeModelBuilder {
1076
1117
  namespace: namespace,
1077
1118
  },
1078
1119
  java: {
1079
- namespace: this.getJavaNamespace(namespace),
1120
+ namespace: this.getJavaNamespace(),
1080
1121
  },
1081
1122
  },
1082
1123
  }));
@@ -1251,6 +1292,11 @@ export class CodeModelBuilder {
1251
1292
  op.addException(response);
1252
1293
  if (response instanceof SchemaResponse) {
1253
1294
  this.trackSchemaUsage(response.schema, { usage: [SchemaContext.Exception] });
1295
+ if (trackConvenienceApi && !this.isBranded()) {
1296
+ this.trackSchemaUsage(response.schema, {
1297
+ usage: [op.internalApi ? SchemaContext.Internal : SchemaContext.Public],
1298
+ });
1299
+ }
1254
1300
  }
1255
1301
  }
1256
1302
  else {
@@ -1316,7 +1362,9 @@ export class CodeModelBuilder {
1316
1362
  }
1317
1363
  }
1318
1364
  }
1319
- throw new Error(`Unrecognized type: '${type.kind}'.`);
1365
+ const errorMsg = `Unrecognized type: '${type.kind}'.`;
1366
+ this.logError(errorMsg);
1367
+ throw new Error(errorMsg);
1320
1368
  }
1321
1369
  processBuiltInType(type, nameHint) {
1322
1370
  nameHint = nameHint || type.kind;
@@ -1447,7 +1495,7 @@ export class CodeModelBuilder {
1447
1495
  namespace: namespace,
1448
1496
  },
1449
1497
  java: {
1450
- namespace: this.getJavaNamespace(namespace),
1498
+ namespace: this.getJavaNamespace(type),
1451
1499
  },
1452
1500
  },
1453
1501
  });
@@ -1521,7 +1569,7 @@ export class CodeModelBuilder {
1521
1569
  namespace: namespace,
1522
1570
  },
1523
1571
  java: {
1524
- namespace: this.getJavaNamespace(namespace),
1572
+ namespace: this.getJavaNamespace(type),
1525
1573
  },
1526
1574
  },
1527
1575
  });
@@ -1599,7 +1647,7 @@ export class CodeModelBuilder {
1599
1647
  if (type.kind === "Model") {
1600
1648
  const effective = getEffectiveModelType(program, type, isSchemaProperty);
1601
1649
  if (this.isArm() && ((_a = getNamespace(effective)) === null || _a === void 0 ? void 0 : _a.startsWith("Azure.ResourceManager"))) {
1602
- // Catalog is TrackedResource<CatalogProperties>
1650
+ // e.g. typespec: Catalog is TrackedResource<CatalogProperties>
1603
1651
  return type;
1604
1652
  }
1605
1653
  else if (effective.name) {
@@ -1662,7 +1710,7 @@ export class CodeModelBuilder {
1662
1710
  processUnionSchema(type, name) {
1663
1711
  var _a, _b;
1664
1712
  if (!(type.__raw && type.__raw.kind === "Union")) {
1665
- throw new Error(`Invalid type for union: '${type.kind}'.`);
1713
+ this.logError(`Invalid type for union: '${type.kind}'.`);
1666
1714
  }
1667
1715
  const rawUnionType = type.__raw;
1668
1716
  const namespace = getNamespace(rawUnionType);
@@ -1685,7 +1733,7 @@ export class CodeModelBuilder {
1685
1733
  namespace: namespace,
1686
1734
  },
1687
1735
  java: {
1688
- namespace: this.getJavaNamespace(namespace),
1736
+ namespace: this.getJavaNamespace(),
1689
1737
  },
1690
1738
  },
1691
1739
  });
@@ -1708,7 +1756,8 @@ export class CodeModelBuilder {
1708
1756
  getUnionVariantName(type, option) {
1709
1757
  var _a, _b;
1710
1758
  if (type === undefined) {
1711
- throw new Error("type is undefined.");
1759
+ this.logError("type is undefined.");
1760
+ return "UnionVariant";
1712
1761
  }
1713
1762
  switch (type.kind) {
1714
1763
  case "Scalar": {
@@ -1765,29 +1814,34 @@ export class CodeModelBuilder {
1765
1814
  case "UnionVariant":
1766
1815
  return (_b = (typeof type.name === "string" ? type.name : undefined)) !== null && _b !== void 0 ? _b : "UnionVariant";
1767
1816
  default:
1768
- throw new Error(`Unrecognized type for union variable: '${type.kind}'.`);
1817
+ this.logError(`Unrecognized type for union variable: '${type.kind}'.`);
1818
+ return "UnionVariant";
1769
1819
  }
1770
1820
  }
1771
1821
  processMultipartFormDataFilePropertySchema(property) {
1772
- var _a, _b, _c, _d;
1822
+ var _a;
1773
1823
  const processSchemaFunc = (type) => this.processSchema(type, "");
1824
+ const processNamespaceFunc = (type) => {
1825
+ var _a;
1826
+ const namespace = type.kind === "model" ? ((_a = getNamespace(type.__raw)) !== null && _a !== void 0 ? _a : this.namespace) : this.namespace;
1827
+ const javaNamespace = type.kind === "model" ? this.getJavaNamespace(type) : this.getJavaNamespace();
1828
+ return { namespace, javaNamespace };
1829
+ };
1774
1830
  if (property.type.kind === "bytes" || property.type.kind === "model") {
1775
- const namespace = property.type.kind === "model"
1776
- ? ((_a = getNamespace(property.type.__raw)) !== null && _a !== void 0 ? _a : this.namespace)
1777
- : this.namespace;
1778
- return getFileDetailsSchema(property, (_b = getNamespace(property.type.__raw)) !== null && _b !== void 0 ? _b : this.namespace, namespace, this.codeModel.schemas, this.binarySchema, this.stringSchema, processSchemaFunc);
1831
+ const namespaceTuple = processNamespaceFunc(property.type);
1832
+ return getFileDetailsSchema(property, namespaceTuple.namespace, namespaceTuple.javaNamespace, this.codeModel.schemas, this.binarySchema, this.stringSchema, processSchemaFunc);
1779
1833
  }
1780
1834
  else if (property.type.kind === "array" &&
1781
1835
  (property.type.valueType.kind === "bytes" || property.type.valueType.kind === "model")) {
1782
- const namespace = property.type.valueType.kind === "model"
1783
- ? ((_c = getNamespace(property.type.valueType.__raw)) !== null && _c !== void 0 ? _c : this.namespace)
1784
- : this.namespace;
1785
- return new ArraySchema(property.name, (_d = property.doc) !== null && _d !== void 0 ? _d : "", getFileDetailsSchema(property, namespace, this.getJavaNamespace(namespace), this.codeModel.schemas, this.binarySchema, this.stringSchema, processSchemaFunc), {
1836
+ const namespaceTuple = processNamespaceFunc(property.type.valueType);
1837
+ return new ArraySchema(property.name, (_a = property.doc) !== null && _a !== void 0 ? _a : "", getFileDetailsSchema(property, namespaceTuple.namespace, namespaceTuple.javaNamespace, this.codeModel.schemas, this.binarySchema, this.stringSchema, processSchemaFunc), {
1786
1838
  summary: property.summary,
1787
1839
  });
1788
1840
  }
1789
1841
  else {
1790
- throw new Error(`Invalid type for multipart form data: '${property.type.kind}'.`);
1842
+ const errorMsg = `Invalid type for multipart form data: '${property.type.kind}'.`;
1843
+ this.logError(errorMsg);
1844
+ throw new Error(errorMsg);
1791
1845
  }
1792
1846
  }
1793
1847
  getDoc(target) {
@@ -1817,13 +1871,13 @@ export class CodeModelBuilder {
1817
1871
  return true;
1818
1872
  }
1819
1873
  else {
1820
- const visibility = target.__raw ? getVisibility(this.program, target.__raw) : undefined;
1874
+ const visibility = target.kind === "property" ? target.visibility : undefined;
1821
1875
  if (visibility) {
1822
- return (!visibility.includes("write") &&
1823
- !visibility.includes("create") &&
1824
- !visibility.includes("update") &&
1825
- !visibility.includes("delete") &&
1826
- !visibility.includes("query"));
1876
+ return (!visibility.includes(Visibility.All) &&
1877
+ !visibility.includes(Visibility.Create) &&
1878
+ !visibility.includes(Visibility.Update) &&
1879
+ !visibility.includes(Visibility.Delete) &&
1880
+ !visibility.includes(Visibility.Query));
1827
1881
  }
1828
1882
  else {
1829
1883
  return false;
@@ -1871,20 +1925,58 @@ export class CodeModelBuilder {
1871
1925
  return undefined;
1872
1926
  }
1873
1927
  }
1874
- getJavaNamespace(namespace) {
1875
- const tspNamespace = this.namespace;
1876
- const baseJavaNamespace = this.emitterContext.options.namespace;
1877
- if (!namespace) {
1878
- return undefined;
1928
+ getBaseJavaNamespace() {
1929
+ // hack, just find the shortest clientNamespace among all clients
1930
+ // hopefully it is the root namespace of the SDK
1931
+ let baseJavaNamespace = undefined;
1932
+ this.sdkContext.sdkPackage.clients
1933
+ .map((it) => it.clientNamespace)
1934
+ .forEach((it) => {
1935
+ if (baseJavaNamespace === undefined || baseJavaNamespace.length > it.length) {
1936
+ baseJavaNamespace = it;
1937
+ }
1938
+ });
1939
+ // fallback if there is no client
1940
+ if (!baseJavaNamespace) {
1941
+ baseJavaNamespace = this.namespace;
1942
+ }
1943
+ return baseJavaNamespace.toLowerCase();
1944
+ }
1945
+ getJavaNamespace(type = undefined) {
1946
+ // clientNamespace from TCGC
1947
+ const clientNamespace = type === null || type === void 0 ? void 0 : type.clientNamespace;
1948
+ if (this.isBranded() && type) {
1949
+ // special handling for namespace of model that cannot be mapped to azure-core
1950
+ if (type.crossLanguageDefinitionId === "TypeSpec.Http.File") {
1951
+ // TypeSpec.Http.File
1952
+ return this.baseJavaNamespace;
1953
+ }
1954
+ else if (type.crossLanguageDefinitionId === "Azure.Core.Foundations.OperationState") {
1955
+ // Azure.Core.OperationState
1956
+ return this.baseJavaNamespace;
1957
+ }
1958
+ else if (type.crossLanguageDefinitionId === "Azure.Core.ResourceOperationStatus" ||
1959
+ type.crossLanguageDefinitionId === "Azure.Core.Foundations.OperationStatus") {
1960
+ // Azure.Core.ResourceOperationStatus<>
1961
+ // Azure.Core.Foundations.OperationStatus<>
1962
+ // usually this model will not be generated, but javadoc of protocol method requires it be in SDK namespace
1963
+ return this.baseJavaNamespace;
1964
+ }
1965
+ else if (type.crossLanguageDefinitionId.startsWith("Azure.ResourceManager.")) {
1966
+ // models in Azure.ResourceManager
1967
+ return this.baseJavaNamespace;
1968
+ }
1879
1969
  }
1880
- else if (baseJavaNamespace &&
1881
- (namespace === tspNamespace || namespace.startsWith(tspNamespace + "."))) {
1882
- return baseJavaNamespace + namespace.slice(tspNamespace.length).toLowerCase();
1970
+ if (this.legacyJavaNamespace || !clientNamespace) {
1971
+ return this.baseJavaNamespace;
1883
1972
  }
1884
1973
  else {
1885
- return namespace.toLowerCase();
1974
+ return clientNamespace.toLowerCase();
1886
1975
  }
1887
1976
  }
1977
+ logError(msg) {
1978
+ logError(this.program, msg);
1979
+ }
1888
1980
  logWarning(msg) {
1889
1981
  if (this.loggingEnabled) {
1890
1982
  logWarning(this.program, msg);