1 package software.amazon.smithy.aws.go.codegen;
2 
3 import java.util.List;
4 import java.util.logging.Logger;
5 import software.amazon.smithy.aws.traits.ServiceTrait;
6 import software.amazon.smithy.codegen.core.Symbol;
7 import software.amazon.smithy.codegen.core.SymbolProvider;
8 import software.amazon.smithy.go.codegen.GoDelegator;
9 import software.amazon.smithy.go.codegen.GoSettings;
10 import software.amazon.smithy.go.codegen.SmithyGoDependency;
11 import software.amazon.smithy.go.codegen.SymbolUtils;
12 import software.amazon.smithy.go.codegen.integration.GoIntegration;
13 import software.amazon.smithy.model.Model;
14 import software.amazon.smithy.model.shapes.ServiceShape;
15 import software.amazon.smithy.utils.ListUtils;
16 
17 /**
18  * Registers additional client specific configuration fields
19  */
20 public class ResolveClientConfig implements GoIntegration {
21     private static final Logger LOGGER = Logger.getLogger(AddAwsConfigFields.class.getName());
22 
23     private static final String USE_ARN_REGION_OPTION = "UseARNRegion";
24     private static final String CLIENT_CONFIG_RESOLVER_FUNC = "resolveClientConfig";
25     private static final String CONFIG_SOURCE_CONFIG_NAME = "ConfigSources";
26     private static final String RESOLVE_USE_ARN_REGION= "ResolveUseARNRegion";
27 
28     public static final List<AddAwsConfigFields.AwsConfigField> AWS_CONFIG_FIELDS = ListUtils.of(
29             AddAwsConfigFields.AwsConfigField.builder()
30                     .name(USE_ARN_REGION_OPTION)
31                     .type(getUniversalSymbol("boolean"))
32                     .generatedOnClient(false)
33                     .servicePredicate((model, serviceShape) -> {
34                         return isS3SharedService(model, serviceShape);
35                     })
36                     .awsResolveFunction(SymbolUtils.createValueSymbolBuilder(CLIENT_CONFIG_RESOLVER_FUNC)
37                             .build())
38                     .build()
39     );
40 
41     @Override
writeAdditionalFiles( GoSettings settings, Model model, SymbolProvider symbolProvider, GoDelegator goDelegator )42     public void writeAdditionalFiles(
43             GoSettings settings,
44             Model model,
45             SymbolProvider symbolProvider,
46             GoDelegator goDelegator
47     ) {
48         LOGGER.info("generating client config resolver");
49         ServiceShape serviceShape = settings.getService(model);
50         goDelegator.useShapeWriter(serviceShape, writer -> {
51             if (!isS3SharedService(model, serviceShape)) {
52                 return;
53             }
54 
55             writer.writeDocs("resolves client config");
56             writer.addUseImports(AwsGoDependency.AWS_CORE);
57             writer.openBlock("func $L(cfg aws.Config, o *Options) error {", "}",
58                     CLIENT_CONFIG_RESOLVER_FUNC, () -> {
59                 writer.openBlock("if len(cfg.$L) == 0 {", "}",
60                         CONFIG_SOURCE_CONFIG_NAME,
61                         () -> writer.write("return nil")
62                 );
63 
64                 writer.addUseImports(SmithyGoDependency.CONTEXT);
65                 Symbol resolverFunc = SymbolUtils.createValueSymbolBuilder(RESOLVE_USE_ARN_REGION,
66                         AwsGoDependency.S3_SHARED_CONFIG).build();
67                 writer.write("value, found, err := $T(context.Background(), cfg.$L)", resolverFunc,
68                         CONFIG_SOURCE_CONFIG_NAME);
69                 writer.write("if err != nil { return err }");
70                 writer.write("if found { o.$L = value }", USE_ARN_REGION_OPTION);
71 
72                 writer.write("return nil");
73             });
74 
75         });
76     }
77 
78 
getUniversalSymbol(String symbolName)79     private static Symbol getUniversalSymbol(String symbolName) {
80         return SymbolUtils.createValueSymbolBuilder(symbolName)
81                 .putProperty(SymbolUtils.GO_UNIVERSE_TYPE, true).build();
82     }
83 
isS3SharedService(Model model, ServiceShape service)84     private static boolean isS3SharedService(Model model, ServiceShape service) {
85         return isS3Service(model, service) || isS3ControlService(model, service);
86     }
87 
isS3Service(Model model, ServiceShape service)88     private static boolean isS3Service(Model model, ServiceShape service) {
89         return service.expectTrait(ServiceTrait.class).getSdkId().equalsIgnoreCase("S3");
90     }
91 
isS3ControlService(Model model, ServiceShape service)92     private static boolean isS3ControlService(Model model, ServiceShape service) {
93         return service.expectTrait(ServiceTrait.class).getSdkId().equalsIgnoreCase("S3 Control");
94     }
95 
96 }
97