2525import java .util .ServiceLoader ;
2626import java .util .Set ;
2727import java .util .TreeSet ;
28+ import java .util .UUID ;
2829import java .util .logging .Logger ;
30+ import software .amazon .smithy .aws .traits .ServiceTrait ;
2931import software .amazon .smithy .build .FileManifest ;
3032import software .amazon .smithy .build .PluginContext ;
3133import software .amazon .smithy .codegen .core .Symbol ;
3234import software .amazon .smithy .codegen .core .SymbolDependency ;
3335import software .amazon .smithy .codegen .core .SymbolProvider ;
3436import software .amazon .smithy .codegen .core .TopologicalIndex ;
37+ import software .amazon .smithy .codegen .core .trace .ArtifactDefinitions ;
38+ import software .amazon .smithy .codegen .core .trace .TraceMetadata ;
39+ import software .amazon .smithy .codegen .core .trace .TracingSymbolProvider ;
3540import software .amazon .smithy .model .Model ;
3641import software .amazon .smithy .model .knowledge .TopDownIndex ;
3742import software .amazon .smithy .model .neighbor .Walker ;
43+ import software .amazon .smithy .model .node .Node ;
3844import software .amazon .smithy .model .shapes .OperationShape ;
3945import software .amazon .smithy .model .shapes .ServiceShape ;
4046import software .amazon .smithy .model .shapes .Shape ;
@@ -93,6 +99,7 @@ class CodegenVisitor extends ShapeVisitor.Default<Void> {
9399 runtimePlugins .add (runtimePlugin );
94100 });
95101 });
102+
96103 // Sort the integrations in specified order.
97104 integrations .sort (Comparator .comparingInt (TypeScriptIntegration ::getOrder ));
98105
@@ -113,19 +120,55 @@ class CodegenVisitor extends ShapeVisitor.Default<Void> {
113120 fileManifest = context .getFileManifest ();
114121 LOGGER .info (() -> String .format ("Generating TypeScript %s for service %s" ,
115122 settings .generateClient () ? "client" : "server" , service .getId ()));
123+ // Resolve the nullable protocol generator and application protocol.
124+ protocolGenerator = resolveProtocolGenerator (integrations , service , settings );
125+ applicationProtocol = protocolGenerator == null
126+ ? ApplicationProtocol .createDefaultHttpApplicationProtocol ()
127+ : protocolGenerator .getApplicationProtocol ();
116128
117129 // Decorate the symbol provider using integrations.
118130 SymbolProvider resolvedProvider = artifactType .createSymbolProvider (model , settings );
119131 for (TypeScriptIntegration integration : integrations ) {
120132 resolvedProvider = integration .decorateSymbolProvider (settings , model , resolvedProvider );
121133 }
122- symbolProvider = SymbolProvider .cache (resolvedProvider );
123134
124- // Resolve the nullable protocol generator and application protocol.
125- protocolGenerator = resolveProtocolGenerator (integrations , service , settings );
126- applicationProtocol = protocolGenerator == null
127- ? ApplicationProtocol .createDefaultHttpApplicationProtocol ()
128- : protocolGenerator .getApplicationProtocol ();
135+ // Make the symbol provider a cachingSymbolProvider.
136+ SymbolProvider cachedProvider = SymbolProvider .cache (resolvedProvider );
137+ // Defining Definitions for TraceFile Generation.
138+ ArtifactDefinitions artifactDefinitions = ArtifactDefinitions .builder ()
139+ .addType (TypeScriptShapeLinkProvider .FIELD_TYPE ,
140+ "Field declaration (includes enum constants)" )
141+ .addType (TypeScriptShapeLinkProvider .METHOD_TYPE , "Method declaration" )
142+ .addType (TypeScriptShapeLinkProvider .TYPE_TYPE ,
143+ "Class, interface (including annotation type), or enum declaration" )
144+ .addTag (TypeScriptShapeLinkProvider .SERVICE_TAG , "Service client" )
145+ .addTag (TypeScriptShapeLinkProvider .REQUEST_TAG , "AWS SDK request type" )
146+ .addTag (TypeScriptShapeLinkProvider .RESPONSE_TAG , "AWS SDK response type" )
147+ .addTag (TypeScriptShapeLinkProvider .SERIALIZER_TAG , "Command serializer" )
148+ .addTag (TypeScriptShapeLinkProvider .DESERIALIZER_TAG , "Command deserializer" )
149+ .build ();
150+
151+ String serviceId ;
152+ if (service .hasTrait (ServiceTrait .class )) {
153+ serviceId = service .getTrait (ServiceTrait .class ).get ().getSdkId ();
154+ } else {
155+ serviceId = service .getId ().getName ();
156+ }
157+ TraceMetadata artifactMetadata = TraceMetadata .builder ()
158+ .setTimestampAsNow ()
159+ .id (serviceId )
160+ .version (UUID .randomUUID ().toString ())
161+ .type ("TypeScript" )
162+ .build ();
163+
164+
165+ // Decorate the symbol provider using the trace file generator.
166+ symbolProvider = TracingSymbolProvider .builder ()
167+ .symbolProvider (cachedProvider )
168+ .metadata (artifactMetadata )
169+ .artifactDefinitions (artifactDefinitions )
170+ .shapeLinkCreator (new TypeScriptShapeLinkProvider ())
171+ .build ();
129172
130173 writers = new TypeScriptDelegator (settings , model , fileManifest , symbolProvider , integrations );
131174 }
@@ -212,6 +255,13 @@ void execute() {
212255 settings , model , protocol , symbolProvider , writers , protocolGenerator ).run ();
213256 }
214257
258+ // Write the TraceFile.
259+ TracingSymbolProvider traceProvider = (TracingSymbolProvider ) symbolProvider ;
260+ String traceName = symbolProvider .toSymbol (service ).getName ().replace ("Client" , "" )
261+ .toLowerCase () + ".trace.json" ;
262+ fileManifest .writeFile (traceName ,
263+ Node .prettyPrintJson (traceProvider .buildTraceFile ().toNode ()));
264+
215265 // Write each pending writer.
216266 LOGGER .fine ("Flushing TypeScript writers" );
217267 List <SymbolDependency > dependencies = writers .getDependencies ();
@@ -372,6 +422,10 @@ private void generateClient(ServiceShape shape) {
372422 boolean hasPaginatedOperation = false ;
373423
374424 for (OperationShape operation : containedOperations ) {
425+ OperationShape finalOperation = operation ;
426+ writers .useShapeWriter (operation , commandWriter -> new CommandGenerator (
427+ settings , model , finalOperation , symbolProvider , commandWriter ,
428+ runtimePlugins , protocolGenerator , applicationProtocol ).run ());
375429 if (operation .hasTrait (PaginatedTrait .ID )) {
376430 hasPaginatedOperation = true ;
377431 String outputFilename = PaginationGenerator .getOutputFilelocation (operation );
@@ -428,7 +482,7 @@ private void generateCommands(ServiceShape shape) {
428482 TopDownIndex topDownIndex = TopDownIndex .of (model );
429483 Set <OperationShape > containedOperations = new TreeSet <>(topDownIndex .getContainedOperations (shape ));
430484 for (OperationShape operation : containedOperations ) {
431- // Right now this only generates stubs
485+ // Right now this only generates stubs.
432486 if (settings .generateClient ()) {
433487 writers .useShapeWriter (operation , commandWriter -> new CommandGenerator (
434488 settings , model , operation , symbolProvider , commandWriter ,
0 commit comments