You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2020/10/20 12:52:39 UTC

[tinkerpop] 01/01: TINKERPOP-2443 Refactored TypeTranslator

This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch TINKERPOP-2443
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit bbcda032cd1b3cbf3d8be0e6c5ad1c75ecf45cc5
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Tue Oct 20 08:51:31 2020 -0400

    TINKERPOP-2443 Refactored TypeTranslator
    
    Tried to make better re-use of the logic of the TypeTranslator. There was a lot of duplication between python and groovy and it seemed like that could be abstracted a bit so that the language specific implementations could focus more solely on the actual types that needed to be translated.
---
 .../gremlin/process/traversal/Translator.java      | 259 +++++++++++++++
 .../traversal/translator/GroovyTranslator.java     | 368 ++++++++++-----------
 .../traversal/translator/PythonTranslator.java     | 331 +++++++++---------
 3 files changed, 612 insertions(+), 346 deletions(-)

diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
index 796f63f..d7dc61b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Translator.java
@@ -19,6 +19,19 @@
 
 package org.apache.tinkerpop.gremlin.process.traversal;
 
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.util.function.Lambda;
+
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
 import java.util.function.BiFunction;
 
 /**
@@ -68,6 +81,252 @@ public interface Translator<S, T> {
          * representations in their target language.
          */
         public interface TypeTranslator extends BiFunction<String, Object, Script> { }
+
+        public abstract class AbstractTypeTranslator implements ScriptTranslator.TypeTranslator {
+            protected static final String ANONYMOUS_TRAVERSAL_PREFIX = "__";
+            protected final boolean withParameters;
+            protected final Script script;
+
+            protected AbstractTypeTranslator(final boolean withParameters) {
+                this.withParameters = withParameters;
+                this.script = new Script();
+            }
+
+            @Override
+            public Script apply(final String traversalSource, final Object o) {
+                this.script.init();
+                if (o instanceof Bytecode) {
+                    return produceScript(traversalSource, (Bytecode) o);
+                } else {
+                    return convertToScript(o);
+                }
+            }
+
+            /**
+             * Gets the syntax for the spawn of an anonymous traversal which is traditionally the double underscore.
+             */
+            protected String getAnonymousTraversalPrefix() {
+                return ANONYMOUS_TRAVERSAL_PREFIX;
+            }
+
+            /**
+             * Gets the syntax for a {@code null} value as a string representation.
+             */
+            protected abstract String getNullSyntax();
+
+            /**
+             * Take the string argument and convert it to a string representation in the target language (i.e. escape,
+             * enclose in appropriate quotes, etc.)
+             */
+            protected abstract String getSyntax(final String o);
+
+            /**
+             * Take the boolean argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final Boolean o);
+
+            /**
+             * Take the {@code Date} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final Date o);
+
+            /**
+             * Take the {@code Timestamp} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final Timestamp o);
+
+            /**
+             * Take the {@code UUID} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final UUID o);
+
+            /**
+             * Take the {@link Lambda} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final Lambda o);
+
+            /**
+             * Take the {@link SackFunctions.Barrier} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final SackFunctions.Barrier o);
+
+            /**
+             * Take the {@link VertexProperty.Cardinality} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final VertexProperty.Cardinality o);
+
+            /**
+             * Take the {@link TraversalOptionParent.Pick} argument and convert it to a string representation in the target language.
+             */
+            protected abstract String getSyntax(final TraversalOptionParent.Pick o);
+
+            /**
+             * Take the numeric argument and convert it to a string representation in the target language. Languages
+             * that can discern differences in types of numbers will wish to further check the type of the
+             * {@code Number} instance itself (i.e. {@code Double}, {@code Integer}, etc.)
+             */
+            protected abstract String getSyntax(final Number o);
+
+            /**
+             * Take the {@code Set} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Set<?> o);
+
+            /**
+             * Take the {@code List} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final List<?> o);
+
+            /**
+             * Take the {@code Map} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Map<?,?> o);
+
+            /**
+             * Take the {@code Class} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Class<?> o);
+
+            /**
+             * Take the {@code Enum} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Enum<?> o);
+
+            /**
+             * Take the {@link Vertex} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Vertex o);
+
+            /**
+             * Take the {@link Edge} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final Edge o);
+
+            /**
+             * Take the {@link VertexProperty} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final VertexProperty<?> o);
+
+            /**
+             * Take the {@link TraversalStrategyProxy} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final TraversalStrategyProxy<?> o);
+
+            /**
+             * Take the {@link Bytecode} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final String traversalSource, final Bytecode o);
+
+            /**
+             * Take the {@link P} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final P<?> p);
+
+            /**
+             * Take the {@link TextP} and writes the syntax directly to the member {@link #script} variable.
+             */
+            protected abstract Script produceScript(final TextP p);
+
+            /**
+             *  For each operator argument, if withParameters set true, try parametrization as follows:
+             *
+             *  -----------------------------------------------
+             *  if unpack, why ?      ObjectType
+             *  -----------------------------------------------
+             *  (Yes)                 Bytecode.Binding
+             *  (Recursion, No)       Bytecode
+             *  (Recursion, No)       Traversal
+             *  (Yes)                 String
+             *  (Recursion, No)       Set
+             *  (Recursion, No)       List
+             *  (Recursion, No)       Map
+             *  (Yes)                 Long
+             *  (Yes)                 Double
+             *  (Yes)                 Float
+             *  (Yes)                 Integer
+             *  (Yes)                 Timestamp
+             *  (Yes)                 Date
+             *  (Yes)                 Uuid
+             *  (Recursion, No)       P
+             *  (Enumeration, No)     SackFunctions.Barrier
+             *  (Enumeration, No)     VertexProperty.Cardinality
+             *  (Enumeration, No)     TraversalOptionParent.Pick
+             *  (Enumeration, No)     Enum
+             *  (Recursion, No)       Vertex
+             *  (Recursion, No)       Edge
+             *  (Recursion, No)       VertexProperty
+             *  (Yes)                 Lambda
+             *  (Recursion, No)       TraversalStrategyProxy
+             *  (Enumeration, No)     TraversalStrategy
+             *  (Yes)                 Other
+             *  -------------------------------------------------
+             *
+             * @param object
+             * @return String Repres
+             */
+            protected Script convertToScript(final Object object) {
+                if (object instanceof Bytecode.Binding) {
+                    return script.getBoundKeyOrAssign(withParameters, ((Bytecode.Binding) object).variable());
+                } else if (object instanceof Bytecode) {
+                    return produceScript(getAnonymousTraversalPrefix(), (Bytecode) object);
+                } else if (object instanceof Traversal) {
+                    return convertToScript(((Traversal) object).asAdmin().getBytecode());
+                } else if (object instanceof String) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((String) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof Boolean) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((Boolean) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof Set) {
+                    return produceScript((Set<?>) object);
+                } else if (object instanceof List) {
+                    return produceScript((List<?>) object);
+                } else if (object instanceof Map) {
+                    return produceScript((Map<?, ?>) object);
+                } else if (object instanceof Number) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((Number) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof Class) {
+                    return produceScript((Class<?>) object);
+                } else if (object instanceof Timestamp) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((Timestamp) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof Date) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((Date) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof UUID) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((UUID) object);
+                    return script.getBoundKeyOrAssign(withParameters, objectOrWrapper);
+                } else if (object instanceof TextP) {
+                    return produceScript((TextP) object);
+                } else if (object instanceof P) {
+                    return produceScript((P<?>) object);
+                } else if (object instanceof SackFunctions.Barrier) {
+                    return script.append(getSyntax((SackFunctions.Barrier) object));
+                } else if (object instanceof VertexProperty.Cardinality) {
+                    return script.append(getSyntax((VertexProperty.Cardinality) object));
+                } else if (object instanceof TraversalOptionParent.Pick) {
+                    return script.append(getSyntax((TraversalOptionParent.Pick) object));
+                } else if (object instanceof Enum) {
+                    return produceScript((Enum<?>) object);
+                } else if (object instanceof Vertex) {
+                    return produceScript((Vertex) object);
+                } else if (object instanceof Edge) {
+                    return produceScript((Edge) object);
+                } else if (object instanceof VertexProperty) {
+                    return produceScript((VertexProperty<?>) object);
+                } else if (object instanceof Lambda) {
+                    final Object objectOrWrapper = withParameters ? object : getSyntax((Lambda) object);
+                    return script.getBoundKeyOrAssign(withParameters,objectOrWrapper);
+                } else if (object instanceof TraversalStrategyProxy) {
+                    return produceScript((TraversalStrategyProxy<?>) object);
+                } else if (object instanceof TraversalStrategy) {
+                    return convertToScript(new TraversalStrategyProxy(((TraversalStrategy) object)));
+                } else {
+                    return null == object ? script.append(getNullSyntax()) : script.getBoundKeyOrAssign(withParameters, object);
+                }
+            }
+        }
     }
 
     /**
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
index 3a8f8a5..c4c7d35 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
@@ -27,28 +27,27 @@ import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
 import org.apache.tinkerpop.gremlin.process.traversal.Script;
 import org.apache.tinkerpop.gremlin.process.traversal.TextP;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
 import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.sql.Timestamp;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import java.util.stream.Collectors;
 import java.util.function.BinaryOperator;
 import java.util.function.Supplier;
 import java.util.function.UnaryOperator;
@@ -87,12 +86,13 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
         return of(traversalSource, new DefaultTypeTranslator(withParameters));
     }
 
+    /**
+     * Creates the translator with a custom {@link TypeTranslator} instance.
+     */
     public static GroovyTranslator of(final String traversalSource, final TypeTranslator typeTranslator) {
         return new GroovyTranslator(traversalSource, typeTranslator);
     }
 
-    ///////
-
     @Override
     public Script translate(final Bytecode bytecode) {
         return typeTranslator.apply(traversalSource, bytecode);
@@ -116,194 +116,189 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
     /**
      * Performs standard type translation for the TinkerPop types to Groovy.
      */
-    public static class DefaultTypeTranslator implements TypeTranslator {
-        protected final boolean withParameters;
-        protected final Script script;
+    public static class DefaultTypeTranslator extends AbstractTypeTranslator {
 
         public DefaultTypeTranslator(final boolean withParameters) {
-            this.withParameters = withParameters;
-            this.script = new Script();
+            super(withParameters);
         }
 
         @Override
-        public Script apply(final String traversalSource, final Object o) {
-            this.script.init();
-            if (o instanceof Bytecode) {
-                return internalTranslate(traversalSource, (Bytecode) o);
-            } else {
-                return convertToScript(o);
-            }
+        protected String getNullSyntax() {
+            return "null";
         }
 
-        /**
-         *  For each operator argument, if withParameters set true, try parametrization as follows:
-         *
-         *  -----------------------------------------------
-         *  if unpack, why ?      ObjectType
-         *  -----------------------------------------------
-         *  (Yes)                 Bytecode.Binding
-         *  (Recursion, No)       Bytecode
-         *  (Recursion, No)       Traversal
-         *  (Yes)                 String
-         *  (Recursion, No)       Set
-         *  (Recursion, No)       List
-         *  (Recursion, No)       Map
-         *  (Yes)                 Long
-         *  (Yes)                 Double
-         *  (Yes)                 Float
-         *  (Yes)                 Integer
-         *  (Yes)                 Timestamp
-         *  (Yes)                 Date
-         *  (Yes)                 Uuid
-         *  (Recursion, No)       P
-         *  (Enumeration, No)     SackFunctions.Barrier
-         *  (Enumeration, No)     VertexProperty.Cardinality
-         *  (Enumeration, No)     TraversalOptionParent.Pick
-         *  (Enumeration, No)     Enum
-         *  (Recursion, No)       Vertex
-         *  (Recursion, No)       Edge
-         *  (Recursion, No)       VertexProperty
-         *  (Yes)                 Lambda
-         *  (Recursion, No)       TraversalStrategyProxy
-         *  (Enumeration, No)     TraversalStrategy
-         *  (Yes)                 Other
-         *  -------------------------------------------------
-         *
-         * @param object
-         * @return String Repres
-         */
-        protected Script convertToScript(final Object object) {
-            if (object instanceof Bytecode.Binding) {
-                return script.getBoundKeyOrAssign(withParameters, ((Bytecode.Binding) object).variable());
-            } else if (object instanceof Bytecode) {
-                return internalTranslate("__", (Bytecode) object);
-            } else if (object instanceof Traversal) {
-                return convertToScript(((Traversal) object).asAdmin().getBytecode());
-            } else if (object instanceof String) {
-                final String wrapper = (((String) object).contains("\"") ? "\"\"\"" + StringEscapeUtils.escapeJava((String) object) + "\"\"\"" : "\"" + StringEscapeUtils.escapeJava((String) object) + "\"")
-                        .replace("$", "\\$");
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : wrapper);
-            } else if (object instanceof Set) {
-                convertToScript(((Set)object).stream().collect(Collectors.toList()));
-                return script.append(" as Set");
-            } else if (object instanceof List) {
-                final Iterator<?> iterator = ((List)object).iterator();
-                if (!iterator.hasNext()) {
-                    return script.append("[]");
-                } else {
-                    script.append("[");
-                    for (;;)  {
-                        Object e =  iterator.next();
-                        convertToScript(e);
-                        if (!iterator.hasNext()) {
-                            return script.append("]");
-                        } else {
-                            script.append(",").append(" ");
-                        }
-                    }
-                }
-            } else if (object instanceof Map) {
-                script.append("[");
-                for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
-                    script.append("(");
-                    convertToScript(entry.getKey());
-                    script.append("):(");
-                    convertToScript(entry.getValue());
-                    script.append("),");
-                }
+        @Override
+        protected String getSyntax(final String o) {
+            return (o.contains("\"") ? "\"\"\"" + StringEscapeUtils.escapeJava(o) + "\"\"\"" : "\"" + StringEscapeUtils.escapeJava(o) + "\"")
+                    .replace("$", "\\$");
+        }
 
-                // only need to remove this last bit if entries were added
-                if (!((Map<?, ?>) object).isEmpty()) {
-                    return script.setCharAtEnd(']');
-                } else {
-                    return script.append("]");
-                }
-            } else if (object instanceof Long) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : object + "L");
-            } else if (object instanceof Double) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : object + "d");
-            } else if (object instanceof Float) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : object + "f");
-            } else if (object instanceof Integer) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : "(int) " + object);
-            } else if (object instanceof Class) {
-                return script.append(((Class) object).getCanonicalName());
-            } else if (object instanceof Timestamp) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : "new java.sql.Timestamp(" + ((Timestamp) object).getTime() + ")");
-            } else if (object instanceof Date) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : "new java.util.Date(" + ((Date) object).getTime() + ")");
-            } else if (object instanceof UUID) {
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : "java.util.UUID.fromString('" + object.toString() + "')");
-            } else if (object instanceof P) {
-                return convertPToScript((P) object);
-            } else if (object instanceof SackFunctions.Barrier) {
-                return script.append("SackFunctions.Barrier." + object.toString());
-            } else if (object instanceof VertexProperty.Cardinality) {
-                return script.append("VertexProperty.Cardinality." + object.toString());
-            } else if (object instanceof TraversalOptionParent.Pick) {
-                return script.append("TraversalOptionParent.Pick." + object.toString());
-            } else if (object instanceof Enum) {
-                return script.append(((Enum) object).getDeclaringClass().getSimpleName() + "." + object.toString());
-            } else if (object instanceof Element) {
-                if (object instanceof Vertex) {
-                    final Vertex vertex = (Vertex) object;
-                    script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex(");
-                    convertToScript(vertex.id());
-                    script.append(",");
-                    convertToScript(vertex.label());
-                    return script.append(", Collections.emptyMap())");
-                } else if (object instanceof Edge) {
-                    final Edge edge = (Edge) object;
-                    script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge(");
-                    convertToScript(edge.id());
-                    script.append(",");
-                    convertToScript(edge.label());
-                    script.append(",");
-                    script.append("Collections.emptyMap(),");
-                    convertToScript(edge.outVertex().id());
-                    script.append(",");
-                    convertToScript(edge.outVertex().label());
-                    script.append(",");
-                    convertToScript(edge.inVertex().id());
-                    script.append(",");
-                    convertToScript(edge.inVertex().label());
-                    return script.append(")");
-                } else {// VertexProperty
-                    final VertexProperty vertexProperty = (VertexProperty) object;
-                    script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty(");
-                    convertToScript(vertexProperty.id());
-                    script.append(",");
-                    convertToScript(vertexProperty.label());
-                    script.append(",");
-                    convertToScript(vertexProperty.value());
+        @Override
+        protected String getSyntax(final Boolean o) {
+            return o.toString();
+        }
+
+        @Override
+        protected String getSyntax(final Date o) {
+            return "new java.util.Date(" + o.getTime() + ")";
+        }
+
+        @Override
+        protected String getSyntax(final Timestamp o) {
+            return "new java.sql.Timestamp(" + o.getTime() + ")";
+        }
+
+        @Override
+        protected String getSyntax(final UUID o) {
+            return "java.util.UUID.fromString('" + o.toString() + "')";
+        }
+
+        @Override
+        protected String getSyntax(final Lambda o) {
+            final String lambdaString = o.getLambdaScript().trim();
+            return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
+        }
+
+        @Override
+        protected String getSyntax(final SackFunctions.Barrier o) {
+            return "SackFunctions.Barrier." + o.toString();
+        }
+
+        @Override
+        protected String getSyntax(final VertexProperty.Cardinality o) {
+            return "VertexProperty.Cardinality." + o.toString();
+        }
+
+        @Override
+        protected String getSyntax(final TraversalOptionParent.Pick o) {
+            return "TraversalOptionParent.Pick." + o.toString();
+        }
+
+        @Override
+        protected String getSyntax(final Number o) {
+            if (o instanceof Long)
+                return o + "L";
+            else if (o instanceof Double)
+                return o + "d";
+            else if (o instanceof Float)
+                return o + "f";
+            else if (o instanceof Integer)
+                return "(int) " + o;
+            else if (o instanceof Byte)
+                return "(byte) " + o;
+            if (o instanceof Short)
+                return "(short) " + o;
+            else if (o instanceof BigInteger)
+                return "new java.math.BigInteger(" + o.toString() + ")";
+            else if (o instanceof BigDecimal)
+                return "new java.math.BigDecimal(" + o.toString() + ")";
+            else
+                return o.toString();
+        }
+
+        @Override
+        protected Script produceScript(final Set<?> o) {
+            return produceScript(new ArrayList<>(o)).append(" as Set");
+        }
+
+        @Override
+        protected Script produceScript(final List<?> o) {
+            final Iterator<?> iterator = ((List<?>) o).iterator();
+            script.append("[");
+
+            while (iterator.hasNext()) {
+                final Object nextItem = iterator.next();
+                convertToScript(nextItem);
+                if (iterator.hasNext())
+                    script.append(",").append(" ");
+            }
+
+            return script.append("]");
+        }
+
+        @Override
+        protected Script produceScript(final Map<?, ?> o) {
+            script.append("[");
+            final Iterator<? extends Map.Entry<?, ?>> itty = ((Map<?, ?>) o).entrySet().iterator();
+            while (itty.hasNext()) {
+                final Map.Entry<?,?> entry = itty.next();
+                script.append("(");
+                convertToScript(entry.getKey());
+                script.append("):(");
+                convertToScript(entry.getValue());
+                script.append(")");
+                if (itty.hasNext())
                     script.append(",");
-                    script.append("Collections.emptyMap(),");
-                    convertToScript(vertexProperty.element());
-                    return script.append(")");
-                }
-            } else if (object instanceof Lambda) {
-                final String lambdaString = ((Lambda) object).getLambdaScript().trim();
-                final String wrapper = lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}";
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : wrapper);
-            } else if (object instanceof TraversalStrategyProxy) {
-                final TraversalStrategyProxy proxy = (TraversalStrategyProxy) object;
-                if (proxy.getConfiguration().isEmpty()) {
-                    return script.append(proxy.getStrategyClass().getCanonicalName() + ".instance()");
-                } else {
-                    script.append(proxy.getStrategyClass().getCanonicalName() + ".create(new org.apache.commons.configuration2.MapConfiguration(");
-                    convertToScript(ConfigurationConverter.getMap(proxy.getConfiguration()));
-                    return script.append("))");
-                }
-            } else if (object instanceof TraversalStrategy) {
-                return convertToScript(new TraversalStrategyProxy(((TraversalStrategy) object)));
+            }
+            return script.append("]");
+        }
+
+        @Override
+        protected Script produceScript(final Class<?> o) {
+            return script.append(o.getCanonicalName());
+        }
+
+        @Override
+        protected Script produceScript(final Enum<?> o) {
+            return script.append(o.getDeclaringClass().getSimpleName() + "." + o.toString());
+        }
+
+        @Override
+        protected Script produceScript(final Vertex o) {
+            script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex(");
+            convertToScript(o.id());
+            script.append(",");
+            convertToScript(o.label());
+            return script.append(", Collections.emptyMap())");
+        }
+
+        @Override
+        protected Script produceScript(final Edge o) {
+            script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge(");
+            convertToScript(o.id());
+            script.append(",");
+            convertToScript(o.label());
+            script.append(",");
+            script.append("Collections.emptyMap(),");
+            convertToScript(o.outVertex().id());
+            script.append(",");
+            convertToScript(o.outVertex().label());
+            script.append(",");
+            convertToScript(o.inVertex().id());
+            script.append(",");
+            convertToScript(o.inVertex().label());
+            return script.append(")");
+        }
+
+        @Override
+        protected Script produceScript(final VertexProperty<?> o) {
+            script.append("new org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty(");
+            convertToScript(o.id());
+            script.append(",");
+            convertToScript(o.label());
+            script.append(",");
+            convertToScript(o.value());
+            script.append(",");
+            script.append("Collections.emptyMap(),");
+            convertToScript(o.element());
+            return script.append(")");
+        }
+
+        @Override
+        protected Script produceScript(final TraversalStrategyProxy<?> o) {
+            if (o.getConfiguration().isEmpty()) {
+                return script.append(o.getStrategyClass().getCanonicalName() + ".instance()");
             } else {
-                return null == object ? script.append("null") : script.getBoundKeyOrAssign(withParameters, object);
+                script.append(o.getStrategyClass().getCanonicalName() + ".create(new org.apache.commons.configuration2.MapConfiguration(");
+                convertToScript(ConfigurationConverter.getMap(o.getConfiguration()));
+                return script.append("))");
             }
         }
 
-        protected Script internalTranslate(final String start, final Bytecode bytecode) {
-            script.append(start);
-            for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
+        @Override
+        protected Script produceScript(final String traversalSource, final Bytecode o) {
+            script.append(traversalSource);
+            for (final Bytecode.Instruction instruction : o.getInstructions()) {
                 final String methodName = instruction.getOperator();
                 if (0 == instruction.getArguments().length) {
                     script.append(".").append(methodName).append("()");
@@ -343,14 +338,12 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
             return script;
         }
 
-        protected Script convertPToScript(final P p) {
-            if (p instanceof TextP) {
-                return convertTextPToScript((TextP) p);
-            }
+        @Override
+        protected Script produceScript(final P<?> p) {
             if (p instanceof ConnectiveP) {
                 final List<P<?>> list = ((ConnectiveP) p).getPredicates();
                 for (int i = 0; i < list.size(); i++) {
-                    convertPToScript(list.get(i));
+                    produceScript(list.get(i));
                     if (i < list.size() - 1) {
                         script.append(p instanceof OrP ? ".or(" : ".and(");
                     }
@@ -363,7 +356,8 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
             return script;
         }
 
-        protected Script convertTextPToScript(final TextP p) {
+        @Override
+        protected Script produceScript(final TextP p) {
             script.append("TextP.").append(p.getBiPredicate().toString()).append("(");
             convertToScript(p.getValue());
             script.append(")");
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
index 360c58e..049ca53 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
@@ -28,25 +28,27 @@ import org.apache.tinkerpop.gremlin.process.traversal.TextP;
 import org.apache.tinkerpop.gremlin.process.traversal.Translator;
 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
-import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
 import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
 import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
 import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
 import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.apache.tinkerpop.gremlin.structure.Element;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
 import org.apache.tinkerpop.gremlin.util.function.Lambda;
 
 import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -65,19 +67,31 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
     private final String traversalSource;
     private final TypeTranslator typeTranslator;
 
-    PythonTranslator(final String traversalSource, final TypeTranslator typeTranslator) {
+    private PythonTranslator(final String traversalSource, final TypeTranslator typeTranslator) {
         this.traversalSource = traversalSource;
         this.typeTranslator = typeTranslator;
     }
 
-    public static PythonTranslator of(final String traversalSource, final boolean withParameters) {
-        return of(traversalSource, new DefaultTypeTranslator(withParameters));
-    }
-
+    /**
+     * Creates the translator with a {@code false} argument to {@code withParameters} using
+     * {@link #of(String, boolean)}.
+     */
     public static PythonTranslator of(final String traversalSource) {
         return of(traversalSource, false);
     }
 
+    /**
+     * Creates the translator with the {@link DefaultTypeTranslator} passing the {@code withParameters} option to it
+     * which will handle type translation in a fashion that should typically increase cache hits and reduce
+     * compilation times if enabled at the sacrifice to rewriting of the script that could reduce readability.
+     */
+    public static PythonTranslator of(final String traversalSource, final boolean withParameters) {
+        return of(traversalSource, new DefaultTypeTranslator(withParameters));
+    }
+
+    /**
+     * Creates the translator with a custom {@link TypeTranslator} instance.
+     */
     public static PythonTranslator of(final String traversalSource, final TypeTranslator typeTranslator) {
         return new PythonTranslator(traversalSource, typeTranslator);
     }
@@ -107,153 +121,163 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
     /**
      * Performs standard type translation for the TinkerPop types to Python.
      */
-    public static class DefaultTypeTranslator implements TypeTranslator {
-        protected final boolean withParameters;
-        protected final Script script;
+    public static class DefaultTypeTranslator extends AbstractTypeTranslator {
 
         public DefaultTypeTranslator(final boolean withParameters) {
-            this.withParameters = withParameters;
-            this.script = new Script();
+            super(withParameters);
         }
 
         @Override
-        public Script apply(final String traversalSource, final Object o) {
-            this.script.init();
-            if (o instanceof Bytecode) {
-                return internalTranslate(traversalSource, (Bytecode) o);
-            } else {
-                return convertToScript(o);
+        protected String getNullSyntax() {
+            return "None";
+        }
+
+        @Override
+        protected String getSyntax(final String o) {
+            return o.contains("'") || o.contains(System.lineSeparator()) ?
+                    "\"\"\"" + o + "\"\"\"" : "'" + o + "'";
+        }
+
+        @Override
+        protected String getSyntax(final Boolean o) {
+            return o ? "True" : "False";
+        }
+
+        @Override
+        protected String getSyntax(final Date o) {
+            return "datetime.datetime.utcfromtimestamp(" + o.getTime() + " / 1000.0)";
+        }
+
+        @Override
+        protected String getSyntax(final Timestamp o) {
+            return "timestamp(" + o.getTime() + " / 1000.0)";
+        }
+
+        @Override
+        protected String getSyntax(final UUID o) {
+            return "UUID('" + o.toString() +"')";
+        }
+
+        @Override
+        protected String getSyntax(final Lambda o) {
+            final String lambdaString = o.getLambdaScript().trim();
+            return lambdaString.startsWith("lambda") ? lambdaString : "lambda " + lambdaString;
+        }
+
+        @Override
+        protected String getSyntax(final Number o) {
+            // todo: nan/inf
+            // all int/short/BigInteger/long are just python int/bignum
+            if (o instanceof Double || o instanceof Float || o instanceof BigDecimal)
+                return "float(" + o + ")";
+            else if (o instanceof Byte)
+                return "SingleByte(" + o + ")";
+            else
+                return o.toString();
+        }
+
+        @Override
+        protected String getSyntax(final SackFunctions.Barrier o) {
+            return "Barrier." + resolveSymbol(o.toString());
+        }
+
+        @Override
+        protected String getSyntax(final VertexProperty.Cardinality o) {
+            return "Cardinality." + resolveSymbol(o.toString());
+        }
+
+        @Override
+        protected String getSyntax(final TraversalOptionParent.Pick o) {
+            return "Pick." + resolveSymbol(o.toString());
+        }
+
+        @Override
+        protected Script produceScript(final Set<?> o) {
+            final Iterator<?> iterator = o.iterator();
+            script.append("set(");
+            while(iterator.hasNext()) {
+                convertToScript(iterator.next());
+                if (iterator.hasNext())
+                    script.append(",");
             }
+            return script.append(")");
         }
 
-        /**
-         * For each operator argument, if withParameters set true, try parametrization as follows:
-         * <p>
-         * -----------------------------------------------
-         * if unpack, why?      ObjectType
-         * -----------------------------------------------
-         * (Yes)                Bytecode.Binding
-         * (Recursion, No)      Bytecode
-         * (Recursion, No)      Traversal
-         * (Yes)                String
-         * (Recursion, No)      Set
-         * (Recursion, No)      List
-         * (Recursion, No)      Map
-         * (Yes)                Long
-         * (Yes)                Double
-         * (Yes)                Float
-         * (Yes)                Integer
-         * (Yes)                Timestamp
-         * (Yes)                Date
-         * (Yes)                Uuid
-         * (Recursion, No)      P
-         * (Enumeration, No)    SackFunctions.Barrier
-         * (Enumeration, No)    VertexProperty.Cardinality
-         * (Enumeration, No)    TraversalOptionParent.Pick
-         * (Enumeration, No)    Enum
-         * (Recursion, No)      Vertex
-         * (Recursion, No)      Edge
-         * (Recursion, No)      VertexProperty
-         * (Yes)                Lambda
-         * (Recursion, No)      TraversalStrategyProxy
-         * (Enumeration, No)    TraversalStrategy
-         * (Yes)                Other
-         * -------------------------------------------------
-         *
-         * @param object
-         * @return String Repres
-         */
-        protected Script convertToScript(final Object object) {
-            if (object instanceof Bytecode.Binding)
-                return script.getBoundKeyOrAssign(withParameters, ((Bytecode.Binding) object).variable());
-            else if (object instanceof Bytecode)
-                return this.internalTranslate("__", (Bytecode) object);
-            else if (object instanceof Traversal)
-                return convertToScript(((Traversal) object).asAdmin().getBytecode());
-            else if (object instanceof String) {
-                final String wrapper = ((String) object).contains("'") || ((String) object).contains(System.lineSeparator()) ?
-                        "\"\"\"" + object + "\"\"\"" : "'" + object + "'";
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : wrapper);
-            } else if (object instanceof Set) {
-                final Iterator<?> iterator = ((Set) object).iterator();
-                script.append("set(");
-                while(iterator.hasNext()) {
-                    convertToScript(iterator.next());
-                    if (iterator.hasNext())
-                        script.append(",");
-                }
+        @Override
+        protected Script produceScript(final List<?> o) {
+            final Iterator<?> iterator = o.iterator();
+            script.append("[");
+            while(iterator.hasNext()) {
+                convertToScript(iterator.next());
+                if (iterator.hasNext())
+                    script.append(",");
+            }
+            return script.append("]");
+        }
+
+        @Override
+        protected Script produceScript(final Map<?, ?> o) {
+            script.append("{");
+            final Iterator<? extends Map.Entry<?, ?>> itty = o.entrySet().iterator();
+            while (itty.hasNext()) {
+                final Map.Entry<?,?> entry = itty.next();
+                convertToScript(entry.getKey()).append(":");
+                convertToScript(entry.getValue());
+                if (itty.hasNext())
+                    script.append(",");
+            }
+            return script.append("}");
+        }
+
+        @Override
+        protected Script produceScript(final Class<?> o) {
+            return script.append("GremlinType(" + o.getCanonicalName() + ")");
+        }
+
+        @Override
+        protected Script produceScript(final Enum<?> o) {
+            return script.append(o.getDeclaringClass().getSimpleName() + "." + resolveSymbol(o.toString()));
+        }
+
+        @Override
+        protected Script produceScript(final Vertex o) {
+            script.append("Vertex(");
+            convertToScript(o.id()).append(",");
+            return convertToScript(o.label()).append(")");
+        }
+
+        @Override
+        protected Script produceScript(final Edge o) {
+            script.append("Edge(");
+            convertToScript(o.id()).append(",");
+            convertToScript(o.outVertex()).append(",");
+            convertToScript(o.label()).append(",");
+            return convertToScript(o.inVertex()).append(")");
+        }
+
+        @Override
+        protected Script produceScript(final VertexProperty<?> o) {
+            script.append("VertexProperty(");
+            convertToScript(o.id()).append(",");
+            convertToScript(o.label()).append(",");
+            return convertToScript(o.value()).append(")");
+        }
+
+        @Override
+        protected Script produceScript(final TraversalStrategyProxy<?> o) {
+            if (o.getConfiguration().isEmpty())
+                return script.append("TraversalStrategy('" + o.getStrategyClass().getSimpleName() + "')");
+            else {
+                script.append("TraversalStrategy('").append(o.getStrategyClass().getSimpleName()).append("',");
+                convertToScript(ConfigurationConverter.getMap(o.getConfiguration()));
                 return script.append(")");
-            } else if (object instanceof List) {
-                final Iterator<?> iterator = ((List) object).iterator();
-                script.append("[");
-                while(iterator.hasNext()) {
-                    convertToScript(iterator.next());
-                    if (iterator.hasNext())
-                        script.append(",");
-                }
-                return script.append("]");
-            } else if (object instanceof Map) {
-                script.append("{");
-                final Iterator<? extends Map.Entry<?, ?>> itty = ((Map<?, ?>) object).entrySet().iterator();
-                while (itty.hasNext()) {
-                    final Map.Entry<?,?> entry = itty.next();
-                    convertToScript(entry.getKey()).append(":");
-                    convertToScript(entry.getValue());
-                    if (itty.hasNext())
-                        script.append(",");
-                }
-                return script.append("}");
-            } else if (object instanceof Long)
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : "long(" + object + ")");
-            else if (object instanceof TraversalStrategyProxy) {
-                return resolveTraversalStrategyProxy((TraversalStrategyProxy) object);
-            } else if (object instanceof TraversalStrategy) {
-                return convertToScript(new TraversalStrategyProxy((TraversalStrategy) object));
-            } else if (object instanceof Boolean)
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : object.equals(Boolean.TRUE) ? "True" : "False");
-            else if (object instanceof Class)
-                return script.append(((Class) object).getCanonicalName());
-            else if (object instanceof VertexProperty.Cardinality)
-                return script.append("Cardinality." + resolveSymbol(object.toString()));
-            else if (object instanceof SackFunctions.Barrier)
-                return script.append("Barrier." + resolveSymbol(object.toString()));
-            else if (object instanceof TraversalOptionParent.Pick)
-                return script.append("Pick." + resolveSymbol(object.toString()));
-            else if (object instanceof Enum)
-                return script.append(((Enum) object).getDeclaringClass().getSimpleName() + "." + resolveSymbol(object.toString()));
-            else if (object instanceof P)
-                return convertPToScript((P) object);
-            else if (object instanceof Element) {
-                if (object instanceof Vertex) {
-                    final Vertex vertex = (Vertex) object;
-                    script.append("Vertex(");
-                    convertToScript(vertex.id()).append(",");
-                    return convertToScript(vertex.label()).append(")");
-                } else if (object instanceof Edge) {
-                    final Edge edge = (Edge) object;
-                    script.append("Edge(");
-                    convertToScript(edge.id()).append(",");
-                    convertToScript(edge.outVertex()).append(",");
-                    convertToScript(edge.label()).append(",");
-                    return convertToScript(edge.inVertex()).append(")");
-                } else {
-                    final VertexProperty vertexProperty = (VertexProperty) object;
-                    script.append("VertexProperty(");
-                    convertToScript(vertexProperty.id()).append(",");
-                    convertToScript(vertexProperty.label()).append(",");
-                    return convertToScript(vertexProperty.value()).append(")");
-                }
-            } else if (object instanceof Lambda) {
-                final String lambdaString = ((Lambda) object).getLambdaScript().trim();
-                final String wrapper = lambdaString.startsWith("lambda") ? lambdaString : "lambda " + lambdaString;;
-                return script.getBoundKeyOrAssign(withParameters, withParameters ? object : wrapper);
-            } else
-                return null == object ? script.append("None") : script.getBoundKeyOrAssign(withParameters, object);
+            }
         }
 
-        private Script internalTranslate(final String start, final Bytecode bytecode) {
-            script.append(start);
-            for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
+        @Override
+        protected Script produceScript(final String traversalSource, final Bytecode o) {
+            script.append(traversalSource);
+            for (final Bytecode.Instruction instruction : o.getInstructions()) {
                 final String methodName = instruction.getOperator();
                 final Object[] arguments = instruction.getArguments();
                 if (0 == arguments.length)
@@ -289,14 +313,12 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
             return script;
         }
 
-        protected Script convertPToScript(final P p) {
-            if (p instanceof TextP) {
-                return convertTextPToScript((TextP) p);
-            }
+        @Override
+        protected Script produceScript(final P<?> p) {
             if (p instanceof ConnectiveP) {
                 final List<P<?>> list = ((ConnectiveP) p).getPredicates();
                 for (int i = 0; i < list.size(); i++) {
-                    convertPToScript(list.get(i));
+                    produceScript(list.get(i));
                     if (i < list.size() - 1) {
                         script.append(p instanceof OrP ? ".or_(" : ".and_(");
                     }
@@ -309,7 +331,8 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
             return script;
         }
 
-        protected Script convertTextPToScript(final TextP p) {
+        @Override
+        protected Script produceScript(final TextP p) {
             script.append("TextP.").append(p.getBiPredicate().toString()).append("(");
             convertToScript(p.getValue());
             script.append(")");
@@ -319,16 +342,6 @@ public final class PythonTranslator implements Translator.ScriptTranslator {
         protected String resolveSymbol(final String methodName) {
             return SymbolHelper.toPython(methodName);
         }
-
-        protected Script resolveTraversalStrategyProxy(final TraversalStrategyProxy proxy) {
-            if (proxy.getConfiguration().isEmpty())
-                return script.append("TraversalStrategy('" + proxy.getStrategyClass().getSimpleName() + "')");
-            else {
-                script.append("TraversalStrategy('").append(proxy.getStrategyClass().getSimpleName()).append("',");
-                convertToScript(ConfigurationConverter.getMap(proxy.getConfiguration()));
-                return script.append(")");
-            }
-        }
     }
 
     static final class SymbolHelper {