private Map<String, String> inferChildResourceIdentifiers(
            Model model,
            ShapeId service,
            String arnRoot,
            ResourceShape resource,
            ResourceShape parent
    ) {
        Map<String, String> result = new HashMap<>();

        // We want child resources to reuse parent resource context keys, so
        // extract out identifiers that were introduced by the child resource.
        Set<String> parentIds = parent == null ? SetUtils.of() : parent.getIdentifiers().keySet();
        Set<String> childIds = new HashSet<>(resource.getIdentifiers().keySet());
        childIds.removeAll(parentIds);

        for (String childId : childIds) {
            model.getShape(resource.getIdentifiers().get(childId)).ifPresent(shape -> {
                // Only infer identifiers introduced by a child. Children should
                // use their parent identifiers and not duplicate them.
                ConditionKeyDefinition.Builder builder = ConditionKeyDefinition.builder();
                if (shape.hasTrait(ArnReferenceTrait.ID)) {
                    // Use an ARN type if the targeted shape has the arnReference trait.
                    builder.type(ARN_TYPE);
                } else {
                    // Fall back to a string type otherwise.
                    builder.type(STRING_TYPE);
                }

                // Inline provided documentation or compute a simple string.
                builder.documentation(shape.getTrait(DocumentationTrait.class)
                        .map(DocumentationTrait::getValue)
                        .orElse(computeIdentifierDocs(resource, childId)));
                // The identifier name consists of "[arn service]:[Resource name][uppercase identifier name]".
                String computeIdentifierName = computeIdentifierName(arnRoot, resource, childId);
                // Add the computed identifier binding and resolved context key to the result map.
                result.put(childId, computeIdentifierName);
                // Register the newly inferred context key definition with the service.
                serviceConditionKeys.get(service).put(computeIdentifierName, builder.build());
            });
        }

        return result;
    }
Get all the defined condition keys used in an operation or resource, including
any inferred keys and keys inherited by parent resource bindings.

<p>The result does not include global condition keys like "aws:accountId".
Use {@link #getConditionKeyNames} to find all the condition keys used
but not necessarily defined for a resource or operation.

@param service Service shape/shapeId use to scope the result.
@param resourceOrOperation Resource or operation shape/shapeId
@return Returns the conditions keys of the service or an empty map when not found.
smithy-aws-iam-traits/src/main/java/software/amazon/smithy/aws/iam/traits/ConditionKeysIndex.java