@Override
        public Void visitProjection(ProjectionExpression expression) {
            if (!(expression.getLeft() instanceof CurrentExpression)) {
                expression.getLeft().accept(this);
            }

            // Without this check, [::1].a would be reserialized into [::-1][*]."a",
            // which is equivalent, but convoluted.
            if (!(expression.getLeft() instanceof SliceExpression)) {
                // Flatten expressions, when parsed, inherently create a projection. Unroll
                // that here.
                if (!(expression.getLeft() instanceof FlattenExpression)) {
                    builder.append("[*]");
                }
            }

            // Avoid unnecessary addition of extracting the current node.
            // We add the current node in projections if there's no RHS.
            if (!(expression.getRight() instanceof CurrentExpression)) {
                // Add a "." if the right hand side needs it.
                if (rhsNeedsDot(expression.getRight())) {
                    builder.append('.');
                }
                expression.getRight().accept(this);
            }

            return null;
        }
Serialize the given JMESPath expression to a string.

@param expression JMESPath expression to serialize.
@return Returns the serialized expression.
smithy-jmespath/src/main/java/software/amazon/smithy/jmespath/ExpressionSerializer.java