@@ -5,18 +5,19 @@ import {
55 createCadlLibrary ,
66 getDeprecated ,
77 getDoc ,
8- getServiceNamespace ,
9- getServiceNamespaceString ,
10- getServiceTitle ,
11- getServiceVersion ,
8+ getNamespaceFullName ,
129 getSummary ,
1310 ignoreDiagnostics ,
1411 isErrorModel ,
12+ JSONSchemaType ,
13+ listServices ,
1514 Model ,
1615 ModelProperty ,
16+ Namespace ,
1717 Operation ,
1818 Program ,
19- resolvePath
19+ resolvePath ,
20+ Service
2021} from "@cadl-lang/compiler" ;
2122import {
2223 getAllHttpServices ,
@@ -76,7 +77,7 @@ import { execSync } from "child_process";
7677import {
7778 Client ,
7879 createDpgContext ,
79- getConvenienceAPIName ,
80+ DpgEmitterOptions ,
8081 isApiVersion ,
8182 listClients ,
8283 listOperationGroups ,
@@ -110,9 +111,8 @@ export async function $onEmit(context: EmitContext<NetEmitterOptions>) {
110111 const outputFolder = resolveOutputFolder ( context ) ;
111112 if ( ! program . compilerOptions . noEmit && ! program . hasError ( ) ) {
112113 // Write out the dotnet model to the output path
113- const namespace = getServiceNamespaceString ( program ) || "" ;
114-
115114 const root = createModel ( context ) ;
115+ const namespace = root . Name ;
116116 // await program.host.writeFile(outPath, prettierOutput(JSON.stringify(root, null, 2)));
117117 if ( root ) {
118118 const generatedFolder = resolvePath ( outputFolder , "Generated" ) ;
@@ -223,22 +223,34 @@ function getClient(
223223}
224224
225225export function createModel ( context : EmitContext < NetEmitterOptions > ) : any {
226- const program = context . program ;
227- const serviceNamespaceType = getServiceNamespace ( program ) ;
228- if ( ! serviceNamespaceType ) {
229- return ;
226+ const services = listServices ( context . program ) ;
227+ if ( services . length === 0 ) {
228+ services . push ( { type : context . program . getGlobalNamespaceType ( ) } ) ;
229+ }
230+
231+ // TODO: support multiple service. Current only chose the first service.
232+ const service = services [ 0 ] ;
233+ const serviceNamespaceType = service . type ;
234+ if ( serviceNamespaceType === undefined ) {
235+ throw Error ( "Can not emit yaml for a namespace that doesn't exist." ) ;
230236 }
231- const title = getServiceTitle ( program ) ;
237+
238+ return createModelForService ( context , service ) ;
239+ }
240+
241+ export function createModelForService (
242+ context : EmitContext < NetEmitterOptions > ,
243+ service : Service
244+ ) : any {
245+ const program = context . program ;
246+ const title = service . title ;
247+ const serviceNamespaceType = service . type ;
232248 const apiVersions : Set < string > = new Set < string > ( ) ;
233- let version = getServiceVersion ( program ) ;
234- if ( version !== "0000-00-00" ) {
249+ let version = service . version ;
250+ if ( version && version !== "0000-00-00" ) {
235251 apiVersions . add ( version ) ;
236252 }
237-
238- const versions = getVersions (
239- program ,
240- serviceNamespaceType
241- ) [ 1 ] ?. getVersions ( ) ;
253+ const versions = getVersions ( program , service . type ) [ 1 ] ?. getVersions ( ) ;
242254 if ( versions ) {
243255 for ( const ver of versions ) {
244256 apiVersions . add ( ver . value ) ;
@@ -280,7 +292,7 @@ export function createModel(context: EmitContext<NetEmitterOptions>): any {
280292 Value : version
281293 } as InputConstant
282294 } ;
283- const namespace = getServiceNamespaceString ( program ) || "client" ;
295+ const namespace = getNamespaceFullName ( serviceNamespaceType ) || "client" ;
284296 const authentication = getAuthentication ( program , serviceNamespaceType ) ;
285297 let auth = undefined ;
286298 if ( authentication ) {
@@ -293,6 +305,7 @@ export function createModel(context: EmitContext<NetEmitterOptions>): any {
293305 let url : string = "" ;
294306 const convenienceOperations : HttpOperation [ ] = [ ] ;
295307 let lroMonitorOperations : Set < Operation > ;
308+ const dpgContext = createDpgContext ( context as EmitContext < any > ) ;
296309 try {
297310 //create endpoint parameter from servers
298311 if ( servers !== undefined ) {
@@ -317,10 +330,10 @@ export function createModel(context: EmitContext<NetEmitterOptions>): any {
317330
318331 lroMonitorOperations = getAllLroMonitorOperations ( routes , program ) ;
319332 const clients : InputClient [ ] = [ ] ;
320- const dpgClients = listClients ( program ) ;
333+ const dpgClients = listClients ( dpgContext ) ;
321334 for ( const client of dpgClients ) {
322335 clients . push ( emitClient ( client ) ) ;
323- const dpgOperationGroups = listOperationGroups ( program , client ) ;
336+ const dpgOperationGroups = listOperationGroups ( dpgContext , client ) ;
324337 for ( const dpgGroup of dpgOperationGroups ) {
325338 clients . push ( emitClient ( dpgGroup , client ) ) ;
326339 }
@@ -388,7 +401,7 @@ export function createModel(context: EmitContext<NetEmitterOptions>): any {
388401 client : Client | OperationGroup ,
389402 parent ?: Client
390403 ) : InputClient {
391- const operations = listOperationsInOperationGroup ( program , client ) ;
404+ const operations = listOperationsInOperationGroup ( dpgContext , client ) ;
392405 let clientDesc = "" ;
393406 if ( operations . length > 0 ) {
394407 const container = ignoreDiagnostics (
@@ -418,6 +431,7 @@ export function createModel(context: EmitContext<NetEmitterOptions>): any {
418431 httpOperation ,
419432 url ,
420433 urlParameters ,
434+ serviceNamespaceType ,
421435 modelMap ,
422436 enumMap
423437 ) ;
@@ -575,7 +589,11 @@ function processServiceAuthentication(
575589 return auth ;
576590}
577591
578- function getOperationGroupName ( program : Program , operation : Operation ) : string {
592+ function getOperationGroupName (
593+ program : Program ,
594+ operation : Operation ,
595+ serviceNamespaceType : Namespace
596+ ) : string {
579597 const explicitOperationId = getOperationId ( program , operation ) ;
580598 if ( explicitOperationId ) {
581599 const ids : string [ ] = explicitOperationId . split ( "_" ) ;
@@ -590,8 +608,7 @@ function getOperationGroupName(program: Program, operation: Operation): string {
590608 let namespace = operation . namespace ;
591609 if ( ! namespace ) {
592610 namespace =
593- program . checker . getGlobalNamespaceType ( ) ??
594- getServiceNamespace ( program ) ;
611+ program . checker . getGlobalNamespaceType ( ) ?? serviceNamespaceType ;
595612 }
596613
597614 if ( namespace ) return namespace . name ;
@@ -603,10 +620,12 @@ function loadOperation(
603620 operation : HttpOperation ,
604621 uri : string ,
605622 urlParameters : InputParameter [ ] | undefined = undefined ,
623+ serviceNamespaceType : Namespace ,
606624 models : Map < string , InputModelType > ,
607625 enums : Map < string , InputEnumType >
608626) : InputOperation {
609627 const program = context . program ;
628+ const dpgContext = createDpgContext ( context ) ;
610629 const {
611630 path : fullPath ,
612631 operation : op ,
@@ -681,14 +700,10 @@ function loadOperation(
681700 mediaTypes . push ( contentTypeParameter . DefaultValue ?. Value ) ;
682701 }
683702 const requestMethod = parseHttpRequestMethod ( verb ) ;
684- const generateProtocol : boolean = shouldGenerateProtocol (
685- createDpgContext ( context ) ,
686- op
687- ) ;
703+ const generateProtocol : boolean = shouldGenerateProtocol ( dpgContext , op ) ;
688704 const generateConvenience : boolean =
689705 requestMethod !== RequestMethod . PATCH &&
690- ( shouldGenerateConvenient ( createDpgContext ( context ) , op ) ||
691- getConvenienceAPIName ( program , op ) !== undefined ) ;
706+ shouldGenerateConvenient ( dpgContext , op ) ;
692707
693708 /* handle lro */
694709 /* handle paging. */
@@ -719,7 +734,7 @@ function loadOperation(
719734 Name : op . name ,
720735 ResourceName :
721736 resourceOperation ?. resourceType . name ??
722- getOperationGroupName ( program , op ) ,
737+ getOperationGroupName ( program , op , serviceNamespaceType ) ,
723738 Summary : summary ,
724739 Deprecated : getDeprecated ( program , op ) ,
725740 Description : desc ,
@@ -763,7 +778,7 @@ function loadOperation(
763778 } as InputConstant ;
764779 }
765780 const requestLocation = requestLocationMap [ location ] ;
766- const isApiVer : boolean = isApiVersion ( program , parameter ) ;
781+ const isApiVer : boolean = isApiVersion ( dpgContext , parameter ) ;
767782 const isContentType : boolean =
768783 requestLocation === RequestLocation . Header &&
769784 name . toLowerCase ( ) === "content-type" ;
0 commit comments