1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"). 5 * You may not use this file except in compliance with the License. 6 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.codegen.poet.rules2; 17 18 import com.squareup.javapoet.ClassName; 19 import com.squareup.javapoet.TypeName; 20 import java.util.Arrays; 21 import java.util.Collections; 22 import java.util.HashMap; 23 import java.util.List; 24 import java.util.Map; 25 import software.amazon.awssdk.utils.Validate; 26 27 public final class RuleRuntimeTypeMirror { 28 // Static types 29 // Used for undefined/don't care types. 30 public static final RuleType VOID = RuleType 31 .builder("Void") 32 .baseType(TypeName.VOID) 33 .build(); 34 public static final RuleType BOOLEAN = RuleType 35 .builder("Boolean") 36 .baseType(TypeName.BOOLEAN) 37 .build(); 38 public static final RuleType INTEGER = RuleType 39 .builder("Integer") 40 .baseType(TypeName.INT) 41 .build(); 42 public static final RuleType STRING = RuleType 43 .builder("String") 44 .baseType(ClassName.get(String.class)) 45 .build(); 46 public static final RuleType LIST_OF_STRING = RuleType 47 .builder("List<String>") 48 .baseType(ClassName.get(List.class)) 49 .addTypeParam(ClassName.get(String.class)) 50 .ruleTypeParam(STRING) 51 .build(); 52 private static final String URL_TYPE_NAME = "Url"; 53 private static final String PARTITION_TYPE_NAME = "Partition"; 54 private static final String ARN_TYPE_NAME = "Arn"; 55 private static final String RESULT_TYPE_NAME = "RuleResult"; 56 private static final String RULES_FUNCTIONS_TYPE_NAME = "RulesFunctions"; 57 private final Map<String, RuleType> internalTypes; 58 private final Map<String, RuleFunctionMirror> builtinFunctions; 59 RuleRuntimeTypeMirror(String packageName)60 public RuleRuntimeTypeMirror(String packageName) { 61 Map<String, RuleType> types = new HashMap<>(); 62 for (RuleType.Builder builder : ruleTypes()) { 63 RuleType type = builder.packageName(packageName) 64 .build(); 65 types.put(type.name(), type); 66 } 67 this.internalTypes = Collections.unmodifiableMap(types); 68 this.builtinFunctions = Collections.unmodifiableMap(buildNameToFunctionMap(types)); 69 } 70 ruleTypes()71 static List<RuleType.Builder> ruleTypes() { 72 return Arrays.asList( 73 RuleType 74 .builder(URL_TYPE_NAME) 75 .putProperty("scheme", STRING) 76 .putProperty("authority", STRING) 77 .putProperty("path", STRING) 78 .putProperty("normalizedPath", STRING) 79 .putProperty("isIp", BOOLEAN) 80 .className("RuleUrl"), 81 RuleType 82 .builder(PARTITION_TYPE_NAME) 83 .putProperty("name", STRING) 84 .putProperty("dnsSuffix", STRING) 85 .putProperty("dualStackDnsSuffix", STRING) 86 .putProperty("supportsFIPS", BOOLEAN) 87 .putProperty("supportsDualStack", BOOLEAN) 88 .putProperty("supportsDualStack", BOOLEAN) 89 .putProperty("implicitGlobalRegion", STRING) 90 .className("RulePartition"), 91 RuleType 92 .builder(ARN_TYPE_NAME) 93 .putProperty("partition", STRING) 94 .putProperty("service", STRING) 95 .putProperty("region", STRING) 96 .putProperty("accountId", STRING) 97 .putProperty("resourceId", LIST_OF_STRING) 98 .className("RuleArn"), 99 // Rules result and adjacent types 100 RuleType 101 .builder(RESULT_TYPE_NAME) 102 .className(RESULT_TYPE_NAME), 103 // Pseudo-type used to contain the builtin functions. 104 RuleType 105 .builder(RULES_FUNCTIONS_TYPE_NAME) 106 .className(RULES_FUNCTIONS_TYPE_NAME) 107 ); 108 } 109 buildNameToFunctionMap(Map<String, RuleType> types)110 static Map<String, RuleFunctionMirror> buildNameToFunctionMap(Map<String, RuleType> types) { 111 Map<String, RuleFunctionMirror> result = new HashMap<>(); 112 for (RuleFunctionMirror func : builtInFunctions(types)) { 113 result.put(func.name(), func); 114 } 115 return result; 116 } 117 builtInFunctions(Map<String, RuleType> types)118 static List<RuleFunctionMirror> builtInFunctions(Map<String, RuleType> types) { 119 RuleType containingType = types.get(RULES_FUNCTIONS_TYPE_NAME); 120 return Arrays.asList( 121 RuleFunctionMirror 122 .builder("not") 123 .returns(BOOLEAN) 124 .addArgument("value", BOOLEAN) 125 .containingType(containingType) 126 .build(), 127 RuleFunctionMirror 128 .builder("substring") 129 .returns(STRING) 130 .addArgument("index", STRING) 131 .addArgument("startIdx", INTEGER) 132 .addArgument("endIdx", INTEGER) 133 .addArgument("reverse", BOOLEAN) 134 .containingType(containingType) 135 .build(), 136 RuleFunctionMirror 137 .builder("stringEquals") 138 .returns(BOOLEAN) 139 .addArgument("left", STRING) 140 .addArgument("right", STRING) 141 .containingType(containingType) 142 .build(), 143 RuleFunctionMirror 144 .builder("booleanEquals") 145 .returns(BOOLEAN) 146 .addArgument("left", BOOLEAN) 147 .addArgument("right", BOOLEAN) 148 .containingType(containingType) 149 .build(), 150 RuleFunctionMirror 151 .builder("uriEncode") 152 .returns(STRING) 153 .addArgument("value", STRING) 154 .containingType(containingType) 155 .build(), 156 RuleFunctionMirror 157 .builder("parseURL") 158 .returns(types.get(URL_TYPE_NAME)) 159 .addArgument("value", STRING) 160 .containingType(containingType) 161 .build(), 162 RuleFunctionMirror 163 .builder("isValidHostLabel") 164 .returns(BOOLEAN) 165 .addArgument("value", STRING) 166 .addArgument("allowSubDomains", BOOLEAN) 167 .containingType(containingType) 168 .build(), 169 RuleFunctionMirror 170 .builder("aws.partition") 171 .javaName("awsPartition") 172 .returns(types.get(PARTITION_TYPE_NAME)) 173 .addArgument("value", STRING) 174 .containingType(containingType) 175 .build(), 176 RuleFunctionMirror 177 .builder("aws.parseArn") 178 .javaName("awsParseArn") 179 .returns(types.get(ARN_TYPE_NAME)) 180 .addArgument("value", STRING) 181 .containingType(containingType) 182 .build(), 183 RuleFunctionMirror 184 .builder("aws.isVirtualHostableS3Bucket") 185 .javaName("awsIsVirtualHostableS3Bucket") 186 .returns(BOOLEAN) 187 .addArgument("value", STRING) 188 .addArgument("allowSubDomains", BOOLEAN) 189 .containingType(containingType) 190 .build(), 191 // Not well-defined, should take List<T> and return T 192 // still does the trick for codegen. 193 RuleFunctionMirror 194 .builder("listAccess") 195 .returns(BOOLEAN) 196 .addArgument("value", LIST_OF_STRING) 197 .addArgument("index", INTEGER) 198 .containingType(containingType) 199 .build() 200 ); 201 } 202 rulesFunctions()203 public RuleType rulesFunctions() { 204 return requireType(RULES_FUNCTIONS_TYPE_NAME); 205 } 206 rulesResult()207 public RuleType rulesResult() { 208 return requireType(RESULT_TYPE_NAME); 209 } 210 endpointUrl()211 public RuleType endpointUrl() { 212 return requireType(URL_TYPE_NAME); 213 } 214 resolveFunction(String name)215 public RuleFunctionMirror resolveFunction(String name) { 216 return builtinFunctions.get(name); 217 } 218 resolveType(String name)219 public RuleType resolveType(String name) { 220 return internalTypes.get(name); 221 } 222 requireType(String name)223 public RuleType requireType(String name) { 224 return Validate.notNull(internalTypes.get(name), name); 225 } 226 } 227