public void write()

in codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/auth/http/integration/AwsSdkCustomizeEndpointRuleSetHttpAuthSchemeProvider.java [348:504]


                public void write(
                    TypeScriptWriter w,
                    String previousText,
                    DefaultHttpAuthSchemeProviderFunctionCodeSection s
                ) {
                    String serviceName = CodegenUtils.getServiceName(
                        s.getSettings(),
                        s.getModel(),
                        s.getSymbolProvider());
                    ServiceIndex serviceIndex = ServiceIndex.of(s.getModel());
                    TopDownIndex topDownIndex = TopDownIndex.of(s.getModel());
                    SupportedHttpAuthSchemesIndex authIndex = new SupportedHttpAuthSchemesIndex(
                        codegenContext.integrations(),
                        s.getModel(),
                        s.getSettings());
                    Map<ShapeId, HttpAuthScheme> effectiveHttpAuthSchemes =
                        AuthUtils.getAllEffectiveNoAuthAwareAuthSchemes(
                            s.getService(),
                            serviceIndex,
                            authIndex,
                            topDownIndex);
                    w.writeDocs("@internal");
                    w.write("""
                        interface EndpointRuleSetHttpAuthSchemeProvider<
                          EndpointParametersT extends EndpointParameters,
                          HttpAuthSchemeParametersT extends HttpAuthSchemeParameters
                        > extends HttpAuthSchemeProvider<EndpointParametersT & HttpAuthSchemeParametersT> { }""");
                    w.addDependency(TypeScriptDependency.SMITHY_TYPES);
                    w.addImport("signatureV4CrtContainer", null, AwsDependency.SIGNATURE_V4_MULTIREGION);
                    w.addImport("Logger", null, TypeScriptDependency.SMITHY_TYPES);
                    w.addImport("EndpointV2", null, TypeScriptDependency.SMITHY_TYPES);
                    w.writeDocs("@internal");
                    w.write("""
                        interface DefaultEndpointResolver<EndpointParametersT extends EndpointParameters> {
                          (params: EndpointParametersT, context?: { logger?: Logger; }): EndpointV2;
                        }""");
                    w.addImport("HttpAuthSchemeId", null, TypeScriptDependency.SMITHY_TYPES);
                    w.writeDocs("@internal");
                    w.write("""
                        const createEndpointRuleSetHttpAuthSchemeProvider = <
                          EndpointParametersT extends EndpointParameters,
                          HttpAuthSchemeParametersT extends HttpAuthSchemeParameters
                        >(
                          defaultEndpointResolver: DefaultEndpointResolver<EndpointParametersT>,
                          defaultHttpAuthSchemeResolver: HttpAuthSchemeProvider<HttpAuthSchemeParametersT>,
                          createHttpAuthOptionFunctions: Record<
                            HttpAuthSchemeId,
                            (authParameters: EndpointParametersT & HttpAuthSchemeParametersT) => HttpAuthOption
                          >
                        ): EndpointRuleSetHttpAuthSchemeProvider<EndpointParametersT, HttpAuthSchemeParametersT> => {
                          const endpointRuleSetHttpAuthSchemeProvider: EndpointRuleSetHttpAuthSchemeProvider<
                            EndpointParametersT,
                            HttpAuthSchemeParametersT
                          > = (authParameters) => {
                            const endpoint: EndpointV2 = defaultEndpointResolver(authParameters);
                            const authSchemes = endpoint.properties?.authSchemes;
                            if (!authSchemes) {
                              return defaultHttpAuthSchemeResolver(authParameters);
                            }
                            const options: HttpAuthOption[] = [];
                            for (const scheme of authSchemes) {
                              const { name: resolvedName, properties = {}, ...rest } = scheme;
                              const name = resolvedName.toLowerCase();
                              if (resolvedName !== name) {
                                console.warn(`HttpAuthScheme has been normalized with lowercasing: \
                        \\`$${resolvedName}\\` to \\`$${name}\\``);
                              }
                              let schemeId;
                              if (name === "sigv4a") {
                                schemeId = "aws.auth#sigv4a";
                                const sigv4Present = authSchemes.find(s => {
                                  const name = s.name.toLowerCase();
                                  return name !== "sigv4a" && name.startsWith("sigv4");
                                });
                                if (!signatureV4CrtContainer.CrtSignerV4 && sigv4Present) {
                                  // sigv4a -> sigv4 fallback.
                                  continue;
                                }
                              } else if (name.startsWith("sigv4")) {
                                schemeId = "aws.auth#sigv4";
                              } else {
                                throw new Error(`Unknown HttpAuthScheme found in \
                        \\`@smithy.rules#endpointRuleSet\\`: \\`$${name}\\``);
                              }
                              const createOption = createHttpAuthOptionFunctions[schemeId];
                              if (!createOption) {
                                throw new Error(`Could not find HttpAuthOption create function for \
                        \\`$${schemeId}\\``);
                              }
                              const option = createOption(authParameters);
                              option.schemeId = schemeId;
                              option.signingProperties = { ...(option.signingProperties || {}), \
                        ...rest, ...properties };
                              options.push(option);
                            }
                            return options;
                          };

                          return endpointRuleSetHttpAuthSchemeProvider;
                        }""");
                    w.writeDocs("@internal");
                    w.openBlock("""
                        const _default$LHttpAuthSchemeProvider: _$LHttpAuthSchemeProvider = \
                        (authParameters) => {""", "};",
                        serviceName, serviceName, () -> {
                        w.write("const options: HttpAuthOption[] = [];");
                        w.openBlock("switch (authParameters.operation) {", "};", () -> {
                            var serviceAuthSchemes = serviceIndex.getEffectiveAuthSchemes(
                                s.getService(), AuthSchemeMode.NO_AUTH_AWARE);
                            serviceAuthSchemes.put(
                                SIGV4A_ID, new DynamicTrait(SIGV4A_ID, ObjectNode.objectNode()));
                            for (OperationShape operationShape : topDownIndex.getContainedOperations(s.getService())) {
                                ShapeId operationShapeId = operationShape.getId();
                                var operationAuthSchemes = serviceIndex.getEffectiveAuthSchemes(
                                    s.getService(), operationShapeId, AuthSchemeMode.NO_AUTH_AWARE);
                                operationAuthSchemes.put(
                                    SIGV4A_ID, new DynamicTrait(SIGV4A_ID, ObjectNode.objectNode()));
                                // Skip operation generation if operation auth schemes are equivalent to the default
                                // service auth schemes.
                                if (AuthUtils.areHttpAuthSchemesEqual(serviceAuthSchemes, operationAuthSchemes)) {
                                    continue;
                                }
                                w.openBlock("case $S: {", "};", operationShapeId.getName(), () -> {
                                    operationAuthSchemes.keySet().forEach(shapeId -> {
                                        w.write("options.push(create$LHttpAuthOption(authParameters));",
                                            HttpAuthSchemeProviderGenerator.normalizeAuthSchemeName(shapeId));
                                    });
                                    w.write("break;");
                                });
                            }
                            w.openBlock("default: {", "};", () -> {
                                serviceAuthSchemes.keySet().forEach(shapeId -> {
                                    w.write("options.push(create$LHttpAuthOption(authParameters));",
                                        HttpAuthSchemeProviderGenerator.normalizeAuthSchemeName(shapeId));
                                });
                            });
                        });
                        w.write("return options;");
                    });
                    w.addImport("defaultEndpointResolver", null, EndpointsV2Generator.ENDPOINT_RESOLVER_DEPENDENCY);
                    w.writeInline("""
                        /**
                         * @internal
                         */
                        export const default$LHttpAuthSchemeProvider: $LHttpAuthSchemeProvider = \
                        createEndpointRuleSetHttpAuthSchemeProvider(\
                        defaultEndpointResolver, \
                        _default$LHttpAuthSchemeProvider, """,
                        serviceName, serviceName, serviceName);
                    w.openBlock("{", "});", () -> {
                        for (HttpAuthScheme scheme : effectiveHttpAuthSchemes.values()) {
                            w.write("$S: create$LHttpAuthOption,",
                                scheme.getSchemeId(),
                                HttpAuthSchemeProviderGenerator.normalizeAuthSchemeName(scheme.getSchemeId()));
                        }
                    });
                }