private static Node createSyntacticShapeId(
            IdlModelLoader loader,
            String identifier,
            SourceLocation location
    ) {
        // Unquoted node values syntactically are assumed to be references to shapes. A lazy string node is
        // used because the shape ID may not be able to be resolved until after the entire model is loaded.
        Pair<StringNode, Consumer<String>> pair = StringNode.createLazyString(identifier, location);
        Consumer<String> consumer = pair.right;
        loader.addForwardReference(identifier, (id, type) -> {
            consumer.accept(id.toString());
            if (type != null) {
                return null;
            } else {
                return ValidationEvent.builder()
                        .id(SYNTACTIC_SHAPE_ID_TARGET)
                        .severity(Severity.DANGER)
                        .message(String.format("Syntactic shape ID `%s` does not resolve to a valid shape ID: "
                                + "`%s`. Did you mean to quote this string? Are you missing a "
                                + "model file?", identifier, id))
                        .sourceLocation(location)
                        .build();
            }
        });
        return pair.left;
    }
Parse a Node identifier String, taking into account keywords and forward references.

@param loader     IDL parser.
@param identifier Identifier to parse.
@param location   Source location to assign to the identifier.
@return Returns the parsed identifier.
smithy-model/src/main/java/software/amazon/smithy/model/loader/IdlNodeParser.java